diff --git a/lib/puppet/catalog-diff/comparer.rb b/lib/puppet/catalog-diff/comparer.rb index 1ce6318..391d69c 100644 --- a/lib/puppet/catalog-diff/comparer.rb +++ b/lib/puppet/catalog-diff/comparer.rb @@ -46,7 +46,7 @@ def compare_resources(old, new, options) parameters_in_new[resource[:resource_id]] = \ Hash[(new_resource[:parameters].to_a - resource[:parameters].to_a )] - if options[:show_resource_diff] + unless options[:no_resource_diff] Puppet.debug("Resource diff: #{resource[:resource_id]}") diff_array = str_diff( diff --git a/lib/puppet/catalog-diff/differ.rb b/lib/puppet/catalog-diff/differ.rb index c21a50a..d440905 100644 --- a/lib/puppet/catalog-diff/differ.rb +++ b/lib/puppet/catalog-diff/differ.rb @@ -39,23 +39,35 @@ def diff(options = {}) when '.marshal' tmp = Marshal.load(File.read(r)) when '.pson' - tmp = PSON.load(File.read(r)) - unless tmp.respond_to? :version - if Puppet::Resource::Catalog.respond_to? :from_data_hash - tmp = Puppet::Resource::Catalog.from_data_hash tmp - else - # The method was renamed in 3.5.0 - tmp = Puppet::Resource::Catalog.from_pson tmp + if Puppet::Util::Package.versioncmp(Puppet.version, '4.0.0') < 0 + # If we're still in Puppet 3.X, use the 3.X loading method + tmp = PSON.load(File.read(r)) + unless tmp.respond_to? :version + if Puppet::Resource::Catalog.respond_to? :from_data_hash + tmp = Puppet::Resource::Catalog.from_data_hash tmp + else + # The method was renamed in 3.5.0 + tmp = Puppet::Resource::Catalog.from_pson tmp + end end + else + + # Puppet 4 Method of loading the pson is quite different than 3.X + raw_content = File.read(r) + tmp = Puppet::Resource::Catalog.convert_from(:pson, raw_content) end when '.json' + if Puppet::Util::Package.versioncmp(Puppet.version, '4.0.0') <= 0 + raise "Loading JSON files will not work when using puppet-diff on Puppet 4.X" + end + if Puppet::Resource::Catalog.respond_to? :from_data_hash tmp = Puppet::Resource::Catalog.from_data_hash JSON.load(File.read(r)) else # The method was renamed in 3.5.0 tmp = Puppet::Resource::Catalog.from_pson JSON.load(File.read(r)) end - else + else raise "Provide catalog with the appropriate file extension, valid extensions are pson, yaml and marshal" end @@ -88,8 +100,8 @@ def diff(options = {}) resource_diffs_titles = return_resource_diffs(titles[:to], titles[:from]) - output[:only_in_old] = resource_diffs_titles[:titles_only_in_old] - output[:only_in_new] = resource_diffs_titles[:titles_only_in_new] + output[:only_in_old] = resource_diffs_titles[:titles_only_in_old].sort + output[:only_in_new] = resource_diffs_titles[:titles_only_in_new].sort resource_diffs = compare_resources(from,to,options) output[:differences_in_old] = resource_diffs[:old] diff --git a/lib/puppet/catalog-diff/formater.rb b/lib/puppet/catalog-diff/formater.rb index 7cff1a7..bc1a6aa 100644 --- a/lib/puppet/catalog-diff/formater.rb +++ b/lib/puppet/catalog-diff/formater.rb @@ -141,5 +141,26 @@ def render_pull(output) end end.join("\n") + "#{self.node_summary_header("#{output[:failed_nodes_total]} out of #{output[:total_nodes]} nodes failed to compile. failure rate:",output,:total_percentage)}" end + + def param_diff(resource_list, old, new) + results = resource_list.collect do |resource| + output = String.new + old_resource = old[resource] + new_resource = new[resource] + + params = Set.new + params.merge old_resource.keys + params.merge new_resource.keys + + output << "\t\033[1m#{resource}\033[0m:\n" + params.each do |param| + output << "\t\tOld Value: #{old_resource[param] || "UNDEF"}\n" + output << "\t\tNew Value: #{new_resource[param] || "UNDEF"}\n" + output << "\n" + end + + output + end.join + end end end diff --git a/lib/puppet/face/catalog/diff.rb b/lib/puppet/face/catalog/diff.rb index d2f6499..bf0106e 100644 --- a/lib/puppet/face/catalog/diff.rb +++ b/lib/puppet/face/catalog/diff.rb @@ -29,8 +29,8 @@ summary "Whether to show a diff for File resource content" end - option '--show_resource_diff' do - summary 'Display differeces between resources in unified diff format' + option '--no_resource_diff' do + summary 'Do not display differeces between resources in unified diff format' end option '--exclude_classes' do @@ -162,11 +162,11 @@ with_changes = nodes.select { |node,summary| summary.is_a?(Hash) && !summary[:node_percentage].zero? } most_changed = with_changes.sort_by {|node,summary| summary[:node_percentage]}.map do |node,summary| - Hash[node => summary[:node_percentage]] + Hash[node => summary[:node_percentage]] end most_differences = with_changes.sort_by {|node,summary| summary[:node_differences]}.map do |node,summary| - Hash[node => summary[:node_differences]] + Hash[node => summary[:node_differences]] end total_nodes = nodes.size nodes[:total_percentage] = (nodes.collect{|node,summary| summary.is_a?(Hash) && summary[:node_percentage] || nil }.compact.inject{|sum,x| sum.to_f + x } / total_nodes) @@ -182,35 +182,46 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "catalog-diff", "formater.rb")) format = Puppet::CatalogDiff::Formater.new() + report = String.new + nodes.collect do |node,summary| - next if node == :total_percentage or node == :total_nodes or node == :most_changed or node == :with_changes or node == :most_differences or node == :pull_output or node == :date - format.node_summary_header(node,summary,:node_percentage) + summary.collect do |header,value| - next if value.nil? - if value.is_a?(Hash) - value.collect do |resource_id,resource| - next if resource.nil? - if resource.is_a?(Hash) && resource.has_key?(:type) - # If we find an actual resource print it out - format.resource_reference(header,resource_id,resource) - elsif resource.is_a?(Array) - next unless resource.any? - # Format string diffs - format.string_diff(header,resource_id,resource) - else + next if [:total_percentage, :total_nodes, :most_changed, :with_changes, :most_differences, :pull_output, :date].include? node + report << format.node_summary_header(node,summary,:node_percentage) + + report << summary.collect do |header,value| + next if ([:params_in_new, :params_in_old].include? header) or value.nil? + if value.is_a?(Hash) + value.collect do |resource_id,resource| next if resource.nil? - # Format hash diffs - format.params_diff(header,resource_id,resource) + if resource.is_a?(Hash) && resource.has_key?(:type) + # If we find an actual resource print it out + format.resource_reference(header,resource_id,resource) + elsif resource.is_a?(Array) + next unless resource.any? + # Format string diffs + format.string_diff(header,resource_id,resource) + else + next if resource.nil? + # Format hash diffs + format.params_diff(header,resource_id,resource) + end end + elsif value.is_a?(Array) + next if value.empty? + # Format arrays + format.list(header,value) + else + format.key_pair(header,value) end - elsif value.is_a?(Array) - next if value.empty? - # Format arrays - format.list(header,value) - else - format.key_pair(header,value) - end end.delete_if {|x| x.nil? or x == [] }.join("\n") - end.join("\n") + "#{format.node_summary_header("#{nodes[:with_changes]} out of #{nodes[:total_nodes]} nodes changed.",nodes,:total_percentage)}\n#{format.list_hash("Nodes with the most changes by percent changed",nodes[:most_changed])}\n\n#{format.list_hash("Nodes with the most changes by differeces",nodes[:most_differences],'')}#{(nodes.has_key?(:pull_output) && format.render_pull(nodes[:pull_output]))}" + + report << "\033Parameter differences across catalogs:\033[0m:\n" + report << format.param_diff(summary[:params_in_new].keys, summary[:params_in_old], summary[:params_in_new]) + end.join("\n") + + report << "#{format.node_summary_header("#{nodes[:with_changes]} out of #{nodes[:total_nodes]} nodes changed.",nodes,:total_percentage)}\n" + report << "#{format.list_hash("Nodes with the most changes by percent changed",nodes[:most_changed])}\n\n" + report << "#{format.list_hash("Nodes with the most changes by differeces",nodes[:most_differences],'')}#{(nodes.has_key?(:pull_output) && format.render_pull(nodes[:pull_output]))}" end end end