From: Nick Lewis <[email protected]>

Added methods to list nodes/groups/classes, along with the groups
via which they were inherited.

Signed-off-by: Jacob Helwig <[email protected]>
Signed-off-by: Nick Lewis <[email protected]>
---
 app/models/node.rb       |    2 +-
 app/models/node_class.rb |   15 ++++++++++++
 app/models/node_group.rb |   34 +++++++++++++++++++++++++++-
 lib/node_group_graph.rb  |   54 ++++++++++++++++++++++++++++++++++++++++++---
 spec/models/node_spec.rb |   17 +++++++++++---
 5 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/app/models/node.rb b/app/models/node.rb
index be6dae9..dc6de11 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -99,7 +99,7 @@ class Node < ActiveRecord::Base
   end
 
   def inherited_classes
-    (node_group_list - [self]).map(&:node_classes).flatten.uniq
+    (node_group_list.keys - [self]).map(&:node_classes).flatten.uniq
   end
 
   def all_classes
diff --git a/app/models/node_class.rb b/app/models/node_class.rb
index ca7ed48..f048599 100644
--- a/app/models/node_class.rb
+++ b/app/models/node_class.rb
@@ -1,6 +1,8 @@
 class NodeClass < ActiveRecord::Base
   def self.per_page; 50 end # Pagination
 
+  include NodeGroupGraph
+
   has_many :node_group_class_memberships, :dependent => :destroy
   has_many :node_class_memberships, :dependent => :destroy
 
@@ -30,4 +32,17 @@ class NodeClass < ActiveRecord::Base
   def self.find_from_form_ids(*ids)
     ids.map{|entry| entry.to_s.split(/[ 
,]/)}.flatten.reject(&:blank?).uniq.map{|id| self.find(id)}
   end
+
+  def node_list
+    return @node_list if @node_list
+    all = {}
+    self.walk_groups do |group,_|
+      group.nodes.each do |node|
+        all[node] ||= Set.new
+        all[node] << group
+      end
+      group
+    end
+    @node_list = all
+  end
 end
diff --git a/app/models/node_group.rb b/app/models/node_group.rb
index 036b033..933ae88 100644
--- a/app/models/node_group.rb
+++ b/app/models/node_group.rb
@@ -12,8 +12,12 @@ class NodeGroup < ActiveRecord::Base
   has_many :node_group_edges_out, :class_name => "NodeGroupEdge", :foreign_key 
=> 'from_id', :dependent => :destroy
   has_many :node_group_edges_in, :class_name => "NodeGroupEdge", :foreign_key 
=> 'to_id', :dependent => :destroy
 
-  # TODO Want to add a list of groups have edges into us, may want to rename 
node_groups
-  has_many :node_groups, :through => :node_group_edges_out, :source => :to
+  has_many :node_group_children, :class_name => "NodeGroup", :through => 
:node_group_edges_in, :source => :from
+  has_many :node_group_parents, :class_name => "NodeGroup", :through => 
:node_group_edges_out, :source => :to
+
+  # Alias for compatibility with Node
+  alias :node_groups :node_group_parents
+  alias :node_groups= :node_group_parents=
 
   has_parameters
 
@@ -70,4 +74,30 @@ class NodeGroup < ActiveRecord::Base
   def self.find_from_form_ids(*ids)
     ids.map{|entry| entry.to_s.split(/[ 
,]/)}.flatten.reject(&:blank?).uniq.map{|id| self.find(id)}
   end
+
+  def node_group_child_list
+    return @node_group_child_list if @node_group_child_list
+    all = {}
+    self.walk_child_groups do |group,children|
+      children.each do |child|
+        all[child] ||= Set.new
+        all[child] << group
+      end
+      group
+    end
+    @node_group_child_list = all
+  end
+
+  def node_list
+    return @node_list if @node_list
+    all = {}
+    self.walk_child_groups do |group,_|
+      group.nodes.each do |node|
+        all[node] ||= Set.new
+        all[node] << group
+      end
+      group
+    end
+    @node_list = all
+  end
 end
diff --git a/lib/node_group_graph.rb b/lib/node_group_graph.rb
index 7f00514..88fbc48 100644
--- a/lib/node_group_graph.rb
+++ b/lib/node_group_graph.rb
@@ -1,10 +1,45 @@
 module NodeGroupGraph
-  def node_group_graph
-    @node_group_graph ||= compile_node_group_graph.last
+  # Returns a hash of all the groups for this group/node, direct or inherited.
+  # Each key is a group, and each value is the Set of groups from which we 
inherit
+  # that group.
+  def node_group_list
+    return @node_group_list if @node_group_list
+    all = {}
+    self.walk_groups do |group,parents|
+      parents.each do |parent|
+        all[parent] ||= Set.new
+        all[parent] << group
+      end
+      group
+    end
+    @node_group_list = all
   end
 
-  def node_group_list
-    @node_group_list ||= compile_node_group_graph.first
+  # Returns a hash of all the classes for this group/node, direct or inherited.
+  # Each key is a class, and each value is the Set of groups from which we 
inherit
+  # that class.
+  def node_class_list
+    return @node_class_list if @node_class_list
+    all = {}
+    self.walk_groups do |group,_|
+      group.node_classes.each do |node_class|
+        all[node_class] ||= Set.new
+        all[node_class] << group
+      end
+    end
+    @node_class_list = all
+  end
+
+  def walk_groups(&block)
+    walk(:node_groups,&block)
+  end
+
+  def walk_child_groups(&block)
+    walk(:node_group_children,&block)
+  end
+
+  def node_group_graph
+    @node_group_graph ||= compile_node_group_graph.last
   end
 
   private
@@ -14,4 +49,15 @@ module NodeGroupGraph
     graph = group.node_groups.map {|grp| {grp => compile_node_group_graph(grp, 
seen + [group], all).last}}.inject({},&:merge)
     [all.uniq, graph]
   end
+
+  def walk(method,&block)
+    def yield_children(seen,method,&block)
+      return nil if seen.include?(self)
+      children_results = self.send(method).map{|group| 
group.yield_children(seen+[self],method,&block)}.compact
+      yield self,children_results
+    end
+    return unless block
+    seen = []
+    yield_children(seen,method,&block)
+  end
 end
diff --git a/spec/models/node_spec.rb b/spec/models/node_spec.rb
index 8ee87db..99283e0 100644
--- a/spec/models/node_spec.rb
+++ b/spec/models/node_spec.rb
@@ -256,7 +256,7 @@ describe Node do
 
   describe "handling the node group graph" do
     before :each do
-      @node = Node.generate!
+      @node = Node.generate! :name => "Sample"
 
       @node_group_a = NodeGroup.generate! :name => "A"
       @node_group_b = NodeGroup.generate! :name => "B"
@@ -273,17 +273,26 @@ describe Node do
 
     describe "when a group is included twice" do
       before :each do
-        @node_group_c = NodeGroup.generate!
+        @node_group_c = NodeGroup.generate! :name => "C"
+        @node_group_d = NodeGroup.generate! :name => "D"
+        @node_group_c.node_groups << @node_group_d
         @node_group_a.node_groups << @node_group_c
         @node_group_b.node_groups << @node_group_c
       end
 
       it "should return the correct graph" do
-        @node.node_group_graph.should == {...@node_group_a => 
{...@node_group_c => {}}, @node_group_b => {...@node_group_c => {}}}
+        @node.node_group_graph.should == {
+          @node_group_a => {
+            @node_group_c => {...@node_group_d => {}}
+          },
+          @node_group_b => {
+            @node_group_c => {...@node_group_d => {}}
+          }
+        }
       end
 
       it "should return the correct list" do
-        @node.node_group_list.should == [...@node, @node_group_a, 
@node_group_c, @node_group_b]
+        @node.node_group_list.should == {...@node_group_a => s...@node], 
@node_group_c => s...@node_group_a,@node_group_b], @node_group_b => s...@node], 
@node_group_d => s...@node_group_c]}
       end
     end
 
-- 
1.7.3.1

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to