Skip to content

Commit 37b35df

Browse files
(PUP-11654) Remove keys from resource_statuses when omitting excess data from report
Previously, when :exclude_unchanged_resources was set to true, the key name would remain in the `resource_statuses` map with an empty hash. This ended up breaking the puppetdb report class because of an assumption that elements in `resource_statuses` would be a Puppet::Resource::Status instance. This change removes the key entirely from `resource_statuses`, so puppetdb no longer errors when interating of the keys. Additionally, there is a nebulous definition of what really a `unchanged_resource` might be; this change expands to to be any resource that is not failed, failed_to_restart, out_of_sync, or skipped. In the future, it may be a good idea to add a state named 'unchanged' instead of relying on the absence of those other 4 attributes listed.
1 parent e95386b commit 37b35df

File tree

2 files changed

+37
-21
lines changed

2 files changed

+37
-21
lines changed

lib/puppet/transaction/report.rb

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Puppet::Transaction::Report
3838
include Puppet::Util::PsychSupport
3939
extend Puppet::Indirector
4040

41+
STATES_FOR_EXCLUSION_FROM_REPORT = [:failed, :failed_to_restart, :out_of_sync, :skipped].freeze
4142
indirects :report, :terminus_class => :processor
4243

4344
# The version of the configuration
@@ -308,14 +309,20 @@ def initialize_from_hash(data)
308309
end
309310
end
310311

311-
def skip_or_to_data_hash(rs)
312-
if rs.nil?
313-
nil
314-
elsif !rs.out_of_sync? && Puppet[:exclude_unchanged_resources]
315-
{}
316-
else
317-
rs.to_data_hash
312+
def resource_unchanged?(rs)
313+
STATES_FOR_EXCLUSION_FROM_REPORT.each do |state|
314+
return false if rs.send(state)
318315
end
316+
true
317+
end
318+
319+
def calculate_resource_statuses
320+
resource_statuses = if Puppet[:exclude_unchanged_resources]
321+
@resource_statuses.reject { |_key, rs| resource_unchanged?(rs) }
322+
else
323+
@resource_statuses
324+
end
325+
Hash[resource_statuses.map { |key, rs| [key, rs.nil? ? nil : rs.to_data_hash] }]
319326
end
320327

321328
def to_data_hash
@@ -333,7 +340,7 @@ def to_data_hash
333340
'environment' => @environment,
334341
'logs' => @logs.map { |log| log.to_data_hash },
335342
'metrics' => Hash[@metrics.map { |key, metric| [key, metric.to_data_hash] }],
336-
'resource_statuses' => Hash[@resource_statuses.map { |key, rs| [key, skip_or_to_data_hash(rs)] }],
343+
'resource_statuses' => calculate_resource_statuses,
337344
'corrective_change' => @corrective_change,
338345
}
339346

spec/unit/transaction/report_spec.rb

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,24 +143,33 @@
143143
end
144144

145145
let(:test_dir) { tmpdir('unchanged_resources') }
146-
def generate_report_and_get_resource_statuses(test_dir)
146+
let(:test_dir2) { tmpdir('unchanged_resources') }
147+
let(:test_file) { tmpfile('some_path')}
148+
it 'should still list "changed" resource statuses but remove "unchanged"' do
147149
transaction = apply_compiled_manifest(<<-END)
150+
notify { "hi": } ~>
151+
exec { "/bin/this_command_does_not_exist":
152+
command => "#{make_absolute('/bin/this_command_does_not_exist')}",
153+
refreshonly => true,
154+
}
148155
file { '#{test_dir}':
149156
ensure => directory
150157
}
158+
file { 'failing_file':
159+
path => '#{test_dir2}',
160+
ensure => file
161+
}
162+
file { 'skipped_file':
163+
path => '#{test_file}',
164+
require => File[failing_file]
165+
}
151166
END
152-
return transaction.report.to_data_hash['resource_statuses']
153-
end
154-
155-
it 'a changed resource is still reported correctly' do
156-
FileUtils.rm_rf(test_dir)
157-
resource_statuses = generate_report_and_get_resource_statuses(test_dir)
158-
expect(resource_statuses["File[#{test_dir}]"]['out_of_sync']).to be_truthy
159-
end
160-
161-
it 'the status for the unchanged resource should be empty' do
162-
resource_statuses = generate_report_and_get_resource_statuses(test_dir)
163-
expect(resource_statuses["File[#{test_dir}]"]).to eq({})
167+
rs = transaction.report.to_data_hash['resource_statuses']
168+
expect(rs["Notify[hi]"]['out_of_sync']).to be true
169+
expect(rs["Exec[/bin/this_command_does_not_exist]"]['failed_to_restart']).to be true
170+
expect(rs["File[failing_file]"]['failed']).to be true
171+
expect(rs["File[skipped_file]"]['skipped']).to be true
172+
expect(rs).to_not have_key(["File[#{test_dir}]"])
164173
end
165174
end
166175

0 commit comments

Comments
 (0)