module Chef::DataCollector::RunEndMessage
Public Class Methods
Source
# File lib/chef/data_collector/run_end_message.rb, line 42 def construct_message(data_collector, status) action_collection = data_collector.action_collection run_status = data_collector.run_status node = data_collector.node message = { "chef_server_fqdn" => URI(Chef::Config[:chef_server_url]).host, "entity_uuid" => Chef::Config[:chef_guid], "expanded_run_list" => data_collector.expanded_run_list, "id" => run_status&.run_id, "message_version" => "1.1.0", "message_type" => "run_converge", "node" => node&.data_for_save || {}, "node_name" => node&.name || data_collector.node_name, "organization_name" => organization, "resources" => all_action_records(action_collection), "run_id" => run_status&.run_id, "run_list" => node&.run_list&.for_json || [], "cookbooks" => ( node && node["cookbooks"] ) || {}, "policy_name" => node&.policy_name, "policy_group" => node&.policy_group, "start_time" => run_status&.start_time&.utc&.iso8601, "end_time" => run_status&.end_time&.utc&.iso8601, "source" => solo_run? ? "chef_solo" : "chef_client", "status" => status, "total_resource_count" => all_action_records(action_collection).count, "updated_resource_count" => updated_resource_count(action_collection), "deprecations" => data_collector.deprecations.to_a, } if run_status&.exception message["error"] = { "class" => run_status.exception.class, "message" => run_status.exception.message, "backtrace" => run_status.exception.backtrace, "description" => data_collector.error_description, } end message end
Construct the message payload that is sent to the DataCollector
server at the end of a Chef
run.
@param data_collector [Chef::DataCollector::Reporter] the calling data_collector instance @param status [String] the overall status of the run, either “success” or “failure”
@return [Hash] A hash containing the run end message data.
Private Class Methods
Source
# File lib/chef/data_collector/run_end_message.rb, line 106 def action_record_for_json(action_record) new_resource = action_record.new_resource current_resource = action_record.current_resource after_resource = action_record.after_resource hash = { "type" => new_resource.resource_name.to_sym, "name" => new_resource.name.to_s, "id" => safe_resource_identity(new_resource), "after" => safe_state_for_resource_reporter(after_resource || new_resource), "before" => safe_state_for_resource_reporter(current_resource), "duration" => action_record.elapsed_time.nil? ? "" : (action_record.elapsed_time * 1000).to_i.to_s, "delta" => new_resource.respond_to?(:diff) && updated_or_failed?(action_record) ? new_resource.diff : "", "ignore_failure" => new_resource.ignore_failure, "result" => action_record.action.to_s, "status" => action_record_status_for_json(action_record), } # don't use the new_resource for the after_resource if it is skipped or failed if action_record.status == :skipped || action_record.status == :failed || action_record.status == :unprocessed hash["after"] = {} end if new_resource.cookbook_name hash["cookbook_name"] = new_resource.cookbook_name hash["cookbook_version"] = new_resource.cookbook_version&.version hash["recipe_name"] = new_resource.recipe_name end hash["conditional"] = action_record.conditional.to_text if action_record.status == :skipped unless action_record.exception.nil? hash["error_message"] = action_record.exception.message hash["error"] = { "class" => action_record.exception.class, "message" => action_record.exception.message, "backtrace" => action_record.exception.backtrace, "description" => action_record.error_description, } end hash end
@return [Hash] the Hash representation of the action_record for sending as JSON
Source
# File lib/chef/data_collector/run_end_message.rb, line 178 def action_record_status_for_json(action_record) action = action_record.status.to_s action = "up-to-date" if action == "up_to_date" action end
Helper to convert action record status (symbols) to strings for the Data Collector server. Does a bit of necessary underscores-to-dashes conversion to comply with the Data Collector API.
@return [String] resource status (
Source
# File lib/chef/data_collector/run_end_message.rb, line 94 def action_records(action_collection) return [] if action_collection.nil? action_collection.action_records end
@return [Array<Chef::ActionCollection::ActionRecord>] list of all action_records
for all resources
Source
# File lib/chef/data_collector/run_end_message.rb, line 101 def all_action_records(action_collection) action_records(action_collection).map { |rec| action_record_for_json(rec) } end
@return [Array<Hash>] list of all action_records
rendered as a Hash for sending to JSON
Source
# File lib/chef/data_collector/run_end_message.rb, line 157 def safe_resource_identity(new_resource) new_resource.identity.to_s rescue => e "unknown identity (due to #{e.class})" end
If the identity property of a resource has been lazied (via a lazy name resource) evaluating it for an unprocessed resource (where the preconditions have not been met) may cause the lazy evaluator to throw – and would otherwise crash the data collector.
@return [String] the resource’s identity property
Source
# File lib/chef/data_collector/run_end_message.rb, line 167 def safe_state_for_resource_reporter(resource) resource ? resource.state_for_resource_reporter : {} rescue {} end
FIXME: This is likely necessary due to the same lazy issue with properties and failing resources?
@return [Hash] the resource’s reported state properties
Source
# File lib/chef/data_collector/run_end_message.rb, line 185 def updated_or_failed?(action_record) action_record.status == :updated || action_record.status == :failed end
@return [Boolean] True if the resource was updated or failed
Source
# File lib/chef/data_collector/run_end_message.rb, line 87 def updated_resource_count(action_collection) return 0 if action_collection.nil? action_collection.filtered_collection(up_to_date: false, skipped: false, unprocessed: false, failed: false).count end
@return [Integer] the number of resources successfully updated in the chef-client run