Node.to_csv now uses a custom set of properties for CSV:
  name, status, resources_count, pending_count, succeessful_count, failed_count

Each resource status for the node will be included along with the node
properties, which will cause multiple CSV lines to be generated per node (one
for each associated resource_status).

If a node has no associated resource statuses, there will be only one line for
that node, with blank entries for the resource status fields.

Paired-With: Jacob Helwig <[email protected]>
Signed-off-by: Nick Lewis <[email protected]>
---
Local-branch: ticket/next/7007
 app/models/node.rb       |   40 ++++++++++++++++++++++++++++++++++++++++
 spec/models/node_spec.rb |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/app/models/node.rb b/app/models/node.rb
index 4d58ac5..56990d0 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -151,6 +151,46 @@ class Node < ActiveRecord::Base
     configuration.to_yaml(opts)
   end
 
+  def resource_count
+    last_apply_report.resource_statuses.count rescue nil
+  end
+
+  def pending_count
+    last_apply_report.resource_statuses.pending(true).failed(false).count 
rescue nil
+  end
+
+  def failed_count
+    last_apply_report.resource_statuses.failed(true).count rescue nil
+  end
+
+  def compliant_count
+    last_apply_report.resource_statuses.pending(false).failed(false).count 
rescue nil
+  end
+
+  def self.to_csv_header
+    CSV.generate_line(Node.to_csv_properties + 
ResourceStatus.to_csv_properties)
+  end
+
+  def self.to_csv_properties
+    [:name, :status, :resource_count, :pending_count, :failed_count, 
:compliant_count]
+  end
+
+  def to_csv
+    node_segment = self.to_csv_array
+    rows = []
+    if (last_apply_report.resource_statuses.present? rescue false)
+      last_apply_report.resource_statuses.each do |res|
+        rows << node_segment + res.to_csv_array
+      end
+    else
+      rows << node_segment + ([nil] * ResourceStatus.to_csv_properties.length)
+    end
+
+    rows.map do |row|
+      CSV.generate_line row
+    end.join("\n")
+  end
+
   def timeline_events
     TimelineEvent.for_node(self)
   end
diff --git a/spec/models/node_spec.rb b/spec/models/node_spec.rb
index f47d51e..afb8b41 100644
--- a/spec/models/node_spec.rb
+++ b/spec/models/node_spec.rb
@@ -587,4 +587,37 @@ describe Node do
       @node.facts.should == {:timestamp => timestamp, :values => {"a" => "1", 
"b" => "2"}}
     end
   end
+
+  describe '.to_csv' do
+    before :each do
+      @node = Node.generate!
+      @report = Report.generate!(:host => @node.name)
+      @node.reload
+
+      @custom_node_properties = [:name, :status, :resource_count, 
:pending_count, :failed_count, :compliant_count]
+      @custom_resource_properties = [:resource_type, :title, :evaluation_time, 
:file, :line, :time, :change_count, :out_of_sync_count, :skipped, :failed]
+    end
+
+    let(:node_values) { @custom_node_properties.map {|prop| @node.send(prop)} }
+
+    it 'should export one row per resource status with both node, and resource 
data' do
+      pending_resource = Factory(:pending_resource, :title => 'pending', 
:report => @report)
+      successful_resource = Factory(:successful_resource, :title => 
'successful', :report => @report)
+      failed_resource = Factory(:failed_resource, :title => 'failed', :report 
=> @report)
+
+      csv_lines = Node.find(:all).to_csv.split("\n")
+      csv_lines.first.should == (@custom_node_properties + 
@custom_resource_properties).join(',')
+      csv_lines[1..-1].should =~ [pending_resource, failed_resource, 
successful_resource].map do |res|
+        line = node_values + @custom_resource_properties.map { |field| 
res.send(field) }
+        line.join(',')
+      end
+    end
+
+    it 'should export nulls for the resource status values when there are no 
resource statuses' do
+      Node.find(:all).to_csv.split("\n").should == [
+        (@custom_node_properties + @custom_resource_properties).join(','),
+        (node_values + ([nil] * @custom_resource_properties.count)).join(',')
+      ]
+    end
+  end
 end
-- 
1.7.5.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