class Object
Constants
- CommandDeactivateNode
- CommandStoreReport
Public Instance Methods
# File lib/puppet/reports/puppetdb.rb, line 157 def build_events_list(events) profile("Build events list (count: #{events.count})", [:puppetdb, :events_list, :build]) do events.map { |event| event_to_hash(event) } end end
@return Array @api private
# File lib/puppet/reports/puppetdb.rb, line 90 def build_logs_list profile("Build logs list (count: #{logs.count})", [:puppetdb, :logs_list, :build]) do logs.map do |log| { 'file' => log.file, 'line' => log.line, 'level' => log.level, 'message' => log.message, 'source' => log.source, 'tags' => [*log.tags], 'time' => Puppet::Util::Puppetdb.to_wire_time(log.time), } end end end
@return Array[Hash} @api private
# File lib/puppet/reports/puppetdb.rb, line 109 def build_metrics_list profile("Build metrics list (count: #{metrics.count})", [:puppetdb, :metrics_list, :build]) do metrics_list = [] metrics.each do |name, data| metric_hashes = data.values.map {|x| {"category" => data.name, "name" => x.first, "value" => x.last}} metrics_list.concat(metric_hashes) end metrics_list end end
@return Array @api private
# File lib/puppet/reports/puppetdb.rb, line 76 def build_resources_list profile("Build resources list (count: #{resource_statuses.count})", [:puppetdb, :resources_list, :build]) do resources = resource_statuses.values.map { |resource| resource_status_to_hash(resource) } if ! config.include_unchanged_resources? resources.select{ |resource| (! resource["events"].empty?) or resource["skipped"] } else resources end end end
Helper method for accessing the puppetdb configuration
@api private
# File lib/puppet/reports/puppetdb.rb, line 185 def config Puppet::Util::Puppetdb.config end
Returns the location to leave the output. This is really only here for testing. :/
# File lib/puppet/face/storeconfigs.rb, line 103 def destination_file(timestamp) File.expand_path("storeconfigs-#{timestamp.strftime('%Y%m%d%H%M%S')}.tar") end
Convert an instance of ‘Puppet::Transaction::Event` to a hash suitable for sending over the wire to PuppetDB
@return Hash[<String, Object>] @api private
# File lib/puppet/reports/puppetdb.rb, line 146 def event_to_hash(event) { "status" => event.status, "timestamp" => Puppet::Util::Puppetdb.to_wire_time(event.time), "property" => event.property, "new_value" => event.desired_value, "old_value" => event.previous_value, "message" => event.message, } end
Execute a command using Puppet’s execution static method.
@param command [Array<String>, String] the command to execute. If it is
an Array the first element should be the executable and the rest of the elements should be the individual arguments to that executable.
@return [Puppet::Util::Execution::ProcessOutput] output as specified by options @raise [Puppet::ExecutionFailure] if the executed chiled process did not exit with status == 0 and ‘failonfail` is
`true`.
# File lib/puppet/face/storeconfigs.rb, line 115 def execute(command) Puppet::Util::Execution.execute(command) end
@return TrueClass @api private
# File lib/puppet/reports/puppetdb.rb, line 70 def has_failed_event?(resource) resource["events"].any? { |event| event["status"] == 'failed' } end
@return TrueClass @api private
# File lib/puppet/reports/puppetdb.rb, line 64 def has_noop_event?(resource) resource["events"].any? { |event| event["status"] == 'noop' } end
# File lib/puppet/face/node/status.rb, line 74 def headers { "Accept" => "application/json", "Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8", } end
# File lib/puppet/face/storeconfigs.rb, line 119 def node_to_catalog_hash(node, timestamp) resources = node.resources.map { |resource| resource_to_hash(resource) } edges = node.resources.map { |resource| resource_to_edge_hash(resource) } { :environment => "production", :metadata => { :api_version => 1, }, :certname => node.name, :version => node.last_compile || Time.now, :edges => edges, :resources => resources + [stage_main_hash], :timestamp => timestamp, :producer_timestamp => timestamp, } end
Process the report by formatting it into a PuppetDB ‘store report’ command and submitting it.
@return [void]
# File lib/puppet/reports/puppetdb.rb, line 20 def process profile("report#process", [:puppetdb, :report, :process]) do submit_command(self.host, report_to_hash, CommandStoreReport, 6) end nil end
Convert ‘self` (an instance of `Puppet::Transaction::Report`) to a hash suitable for sending over the wire to PuppetDB
@return Hash[<String, Object>] @api private
# File lib/puppet/reports/puppetdb.rb, line 33 def report_to_hash profile("Convert report to wire format hash", [:puppetdb, :report, :convert_to_wire_format_hash]) do if environment.nil? raise Puppet::Error, "Environment is nil, unable to submit report. This may be due a bug with Puppet. Ensure you are running the latest revision, see PUP-2508 for more details." end resources = build_resources_list is_noop = resources.any? { |rs| has_noop_event?(rs) } and resources.none? { |rs| has_failed_event?(rs) } { "certname" => host, "puppet_version" => puppet_version, "report_format" => report_format, "configuration_version" => configuration_version.to_s, "producer_timestamp" => Puppet::Util::Puppetdb.to_wire_time(Time.now), "start_time" => Puppet::Util::Puppetdb.to_wire_time(time), "end_time" => Puppet::Util::Puppetdb.to_wire_time(time + run_duration), "environment" => environment, "transaction_uuid" => transaction_uuid, "status" => status, "noop" => is_noop, "logs" => build_logs_list, "metrics" => build_metrics_list, "resources" => resources, } end end
Convert an instance of ‘Puppet::Resource::Status` to a hash suitable for sending over the wire to PuppetDB
@return Hash[<String, Object>] @api private
# File lib/puppet/reports/puppetdb.rb, line 169 def resource_status_to_hash(resource_status) { "skipped" => resource_status.skipped, "timestamp" => Puppet::Util::Puppetdb.to_wire_time(resource_status.time), "resource_type" => resource_status.resource_type, "resource_title" => resource_status.title.to_s, "file" => resource_status.file, "line" => resource_status.line, "containment_path" => resource_status.containment_path, "events" => build_events_list(resource_status.events), } end
The catalog must have edges, so everything is contained by Stage!
# File lib/puppet/face/storeconfigs.rb, line 164 def resource_to_edge_hash(resource) { 'source' => {'type' => 'Stage', 'title' => 'main'}, 'target' => {'type' => resource.restype, 'title' => resource.title}, 'relationship' => 'contains', } end
# File lib/puppet/face/storeconfigs.rb, line 137 def resource_to_hash(resource) parameters = resource.param_values.inject({}) do |params,param_value| if params.has_key?(param_value.param_name.name) value = [params[param_value.param_name.name],param_value.value].flatten else value = param_value.value end params.merge(param_value.param_name.name => value) end tags = resource.puppet_tags.map(&:name).uniq.sort hash = { :type => resource.restype, :title => resource.title, :exported => true, :parameters => parameters, :tags => tags, } hash[:file] = resource.file if resource.file hash[:line] = resource.line if resource.line hash end
@return Number @api private
# File lib/puppet/reports/puppetdb.rb, line 124 def run_duration # TODO: this is wrong in puppet. I am consistently seeing reports where # start-time + this value is less than the timestamp on the individual # resource events. Not sure what the best short-term fix is yet; the long # term fix is obviously to make the correct data available in puppet. # I've filed a ticket against puppet here: # http://projects.puppetlabs.com/issues/16480 # # NOTE: failed reports have an empty metrics hash. Just send 0 for run time, # since we don't have access to any better information. if metrics["time"] and metrics["time"]["total"] metrics["time"]["total"] else 0 end end
# File lib/puppet/face/storeconfigs.rb, line 172 def stage_main_hash { :type => 'Stage', :title => 'main', :exported => false, :parameters => {}, :tags => ['stage', 'main'], } end