It's really unusable to have to go to each node's edit page to add a
list of nodes to a group.  Now you can just add the nodes on the group's
create or edit page.

Signed-off-by: Matt Robinson <m...@puppetlabs.com>
---
Local-branch: ticket/master/8878_add_nodes_from_group_page
 app/controllers/application_controller.rb |    8 ++++
 app/controllers/node_groups_controller.rb |    4 ++
 app/controllers/nodes_controller.rb       |    1 +
 app/models/node.rb                        |    8 ++++
 app/models/node_group.rb                  |   16 ++++++++
 app/views/node_groups/_form.html.haml     |    6 +++-
 spec/models/node_group_spec.rb            |   57 +++++++++++++++++++++++++++++
 7 files changed, 99 insertions(+), 1 deletions(-)

diff --git a/app/controllers/application_controller.rb 
b/app/controllers/application_controller.rb
index d44c354..6f29d7b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -53,6 +53,14 @@ class ApplicationController < ActionController::Base
     end
   end
 
+  def set_node_autocomplete_data_sources(source_object)
+    @node_data = {
+      :class       => '#node_ids',
+      :data_source => nodes_path(:format => :json),
+      :objects     => source_object.nodes
+    }
+  end
+
   def set_group_and_class_autocomplete_data_sources(source_object)
     @class_data = {
       :class       => '#node_class_ids',
diff --git a/app/controllers/node_groups_controller.rb 
b/app/controllers/node_groups_controller.rb
index c543bb0..ee015d3 100644
--- a/app/controllers/node_groups_controller.rb
+++ b/app/controllers/node_groups_controller.rb
@@ -7,6 +7,7 @@ class NodeGroupsController < InheritedResources::Base
   def new
     new! do |format|
       format.html {
+        set_node_autocomplete_data_sources(@node_group)
         set_group_and_class_autocomplete_data_sources(@node_group)
       }
     end
@@ -15,6 +16,7 @@ class NodeGroupsController < InheritedResources::Base
   def create
     create! do |success, failure|
       failure.html {
+        set_node_autocomplete_data_sources(@node_group)
         set_group_and_class_autocomplete_data_sources(@node_group)
         render :new
       }
@@ -24,6 +26,7 @@ class NodeGroupsController < InheritedResources::Base
   def edit
     edit! do |format|
       format.html {
+        set_node_autocomplete_data_sources(@node_group)
         set_group_and_class_autocomplete_data_sources(@node_group)
       }
     end
@@ -32,6 +35,7 @@ class NodeGroupsController < InheritedResources::Base
   def update
     update! do |success, failure|
       failure.html {
+        set_node_autocomplete_data_sources(@node_group)
         set_group_and_class_autocomplete_data_sources(@node_group)
         render :edit
       }
diff --git a/app/controllers/nodes_controller.rb 
b/app/controllers/nodes_controller.rb
index edf050a..3545aa2 100644
--- a/app/controllers/nodes_controller.rb
+++ b/app/controllers/nodes_controller.rb
@@ -140,6 +140,7 @@ class NodesController < InheritedResources::Base
       set_collection_ivar(scope.with_last_report.by_report_date)
 
       format.html { render :index }
+      format.json { render :text => collection.to_json, :content_type => 
'application/json' }
       format.yaml { render :text => collection.to_yaml, :content_type => 
'application/x-yaml' }
       format.csv do
         response["Content-Type"] = 'text/comma-separated-values;'
diff --git a/app/models/node.rb b/app/models/node.rb
index ff99ecc..045c40e 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -248,4 +248,12 @@ class Node < ActiveRecord::Base
     options = {:conditions => "metrics.category = 'resources' AND metrics.name 
= '#{resource_status}'", :joins => 'left join metrics on metrics.report_id = 
nodes.last_apply_report_id'}
     ['all', 'index'].include?(scope) ? Node.sum(:value, options).to_i : 
Node.send(scope).sum(:value, options).to_i
   end
+
+  def self.find_from_form_names(*names)
+    names.reject(&:blank?).map{|name| self.find_by_name(name)}.uniq
+  end
+
+  def self.find_from_form_ids(*ids)
+    ids.map{|entry| entry.to_s.split(/[ 
,]/)}.flatten.reject(&:blank?).uniq.map{|id| self.find(id)}
+  end
 end
diff --git a/app/models/node_group.rb b/app/models/node_group.rb
index 9dd2dd1..01f0f62 100644
--- a/app/models/node_group.rb
+++ b/app/models/node_group.rb
@@ -39,6 +39,22 @@ class NodeGroup < ActiveRecord::Base
     super({:methods => :description, :only => [:name, :id]}.merge(options))
   end
 
+  attr_accessor :node_names
+  attr_accessor :node_ids
+  before_validation :assign_nodes
+  def assign_nodes
+    return true unless @node_ids || @node_names
+    raise NodeClassificationDisabledError.new unless 
SETTINGS.use_external_node_classification
+    nodes = []
+    nodes << Node.find_from_form_names(*@node_names) if @node_names
+    nodes << Node.find_from_form_ids(*@node_ids)     if @node_ids
+
+    self.nodes = nodes.flatten.uniq
+  rescue ActiveRecord::RecordInvalid => e
+    self.errors.add_to_base(e.message)
+    return false
+  end
+
   attr_accessor :node_class_names
   attr_accessor :node_class_ids
   before_validation :assign_node_classes
diff --git a/app/views/node_groups/_form.html.haml 
b/app/views/node_groups/_form.html.haml
index b74253a..8b19472 100644
--- a/app/views/node_groups/_form.html.haml
+++ b/app/views/node_groups/_form.html.haml
@@ -34,4 +34,8 @@
     = label_tag 'Groups'
     = text_field_tag 'node_group[node_group_ids][]', '', :id => 
'node_group_ids'
 
-  %script#tokenizer{:type => "text/javascript"}= 
tokenize_input_class(@class_data, @group_data)
+  .element.nodes
+    = label_tag 'Nodes'
+    = text_field_tag 'node_group[node_ids][]', '', :id => 'node_ids'
+
+  %script#tokenizer{:type => "text/javascript"}= 
tokenize_input_class(@class_data, @group_data, @node_data)
diff --git a/spec/models/node_group_spec.rb b/spec/models/node_group_spec.rb
index 6f6194e..3d5207b 100644
--- a/spec/models/node_group_spec.rb
+++ b/spec/models/node_group_spec.rb
@@ -231,4 +231,61 @@ describe NodeGroup do
       end
     end
   end
+
+  describe "assigning before validation" do
+    let(:node_groups)  { Array.new(2) { |i| NodeGroup.generate! :name => 
"group#{i}" } }
+    let(:node_classes) { Array.new(2) { |i| NodeClass.generate! :name => 
"class#{i}" } }
+    let(:nodes)        { Array.new(2) { |i| Node.generate!      :name => 
"node#{i}"  } }
+
+    it "should assign groups, classes and nodes by id" do
+      new_group = NodeGroup.new(
+        :node_group_ids => node_groups.map(&:id),
+        :node_class_ids => node_classes.map(&:id),
+        :node_ids       => nodes.map(&:id)
+      )
+      new_group.assign_node_groups
+      new_group.assign_node_classes
+      new_group.assign_nodes
+
+      new_group.node_groups.should  == node_groups
+      new_group.node_classes.should == node_classes
+      new_group.nodes.should        == nodes
+    end
+
+    it "should assign groups, classes and nodes by name" do
+      new_group = NodeGroup.new(
+        :node_group_names => node_groups.map(&:name),
+        :node_class_names => node_classes.map(&:name),
+        :node_names       => nodes.map(&:name)
+      )
+      new_group.assign_node_groups
+      new_group.assign_node_classes
+      new_group.assign_nodes
+
+      new_group.node_groups.should  == node_groups
+      new_group.node_classes.should == node_classes
+      new_group.nodes.should        == nodes
+    end
+
+    it "should add assignment errors to the object" do
+      new_group = NodeGroup.new(
+        :node_group_ids => ['cow'],
+        :node_class_ids => ['dog'],
+        :node_ids       => ['pig']
+      )
+      new_group.assign_node_groups
+      new_group.assign_node_classes
+      new_group.assign_nodes
+
+      new_group.node_groups.should  be_empty
+      new_group.node_classes.should be_empty
+      new_group.nodes.should        be_empty
+
+      new_group.errors.full_messages.should =~ [
+        "Couldn't find NodeGroup with ID=cow",
+        "Couldn't find NodeClass with ID=dog",
+        "Couldn't find Node with ID=pig"
+      ]
+    end
+  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 puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to