From d40bd7f4d871f0c76a6d931162290e1cd223127e Mon Sep 17 00:00:00 2001 From: Stephen Gelman Date: Sun, 5 Apr 2015 18:30:38 -0500 Subject: [PATCH 01/17] Fix comments in report sanitizer and its spec Correctly identify which versions of puppet produce which report format --- lib/puppet/report_sanitizer.rb | 4 ++-- spec/lib/puppet/report_sanitizer_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index c10553b66..b7d79ead6 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -135,7 +135,7 @@ def report_format(raw) end end - # format version 1 was used by puppet 2.6.x-2.7.12 + # format version 1 was used by puppet 2.6.0-2.6.4 class FormatVersion1 < Base def initialize( log_sanitizer = VersionLogSanitizer.new, @@ -169,7 +169,7 @@ def sanitize(raw) end end - # format version 2 has been used since puppet 2.7.13 + # format version 2 was used by puppet 2.6.5-2.7.11 class FormatVersion2 < FormatVersion1 def initialize( log_sanitizer = LogSanitizer.new, diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index 3b206b84c..0eea61a77 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -92,7 +92,7 @@ end end - describe 'a format version 1 (puppet 2.6.x-2.7.12) report' do + describe 'a format version 1 (puppet 2.6.0-2.6.4) report' do let :report_filename do Rails.root.join('spec', 'fixtures', 'reports', 'puppet26', 'report_ok_service_started_ok.yaml') end @@ -358,7 +358,7 @@ end end - describe 'a format version 2 (puppet 2.7.13+) report' do + describe 'a format version 2 (puppet 2.6.5-2.7.11) report' do let :raw_report do YAML.load(< :true, :deserialize_symbols => true) --- !ruby/object:Puppet::Transaction::Report From 5dbf0d622444855c4c3f4de5926c99c057961b91 Mon Sep 17 00:00:00 2001 From: Stephen Gelman Date: Mon, 6 Apr 2015 02:44:54 +0000 Subject: [PATCH 02/17] Add support for report format 3 - Add new sanitizer for report format 3 - The only difference with report format 3 is an added "environment" field - Add "environment" column to reports table --- ...150405234511_add_environment_to_reports.rb | 5 + lib/puppet/report_sanitizer.rb | 20 ++- spec/lib/puppet/report_sanitizer_spec.rb | 139 ++++++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20150405234511_add_environment_to_reports.rb diff --git a/db/migrate/20150405234511_add_environment_to_reports.rb b/db/migrate/20150405234511_add_environment_to_reports.rb new file mode 100644 index 000000000..d6d94a5a6 --- /dev/null +++ b/db/migrate/20150405234511_add_environment_to_reports.rb @@ -0,0 +1,5 @@ +class AddEnvironmentToReports < ActiveRecord::Migration + def change + add_column :reports, :environment, :string + end +end diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index b7d79ead6..4228494be 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -7,7 +7,12 @@ class << self def sanitize(raw) case when raw.include?('report_format') - format2sanitizer.sanitize(raw) + case raw['report_format'] + when 2 + format2sanitizer.sanitize(raw) + when 3 + format3sanitizer.sanitize(raw) + end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) else @@ -28,6 +33,10 @@ def format1sanitizer() def format2sanitizer() @format2sanitizer ||= ReportSanitizer::FormatVersion2.new end + + def format3sanitizer() + @format3sanitizer ||= ReportSanitizer::FormatVersion3.new + end end module Util @@ -209,4 +218,13 @@ def sanitize(raw) end end end + + # format version 3 was used by puppet 2.7.13-3.2.4 + class FormatVersion3 < FormatVersion2 + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[kind status puppet_version configuration_version environment]) + Util.copy_attributes(sanitized, raw, %w[kind status puppet_version configuration_version environment]) + end + end end diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index 0eea61a77..b0bdba1d6 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -494,5 +494,144 @@ hash["time"].should == Time.parse("2010-07-22 12:19:47.204207 -07:00") end end + + describe 'a format version 3 (puppet 2.7.13-3.2.4) report' do + let :raw_report do + YAML.load(< :true, :deserialize_symbols => true) +--- !ruby/object:Puppet::Transaction::Report + host: localhost + time: 2010-07-22 12:19:47.204207 -07:00 + logs: [] + metrics: + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - config_retrieval + - Config retrieval + - 0.25 + - - total + - Total + - 0.5 + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - failed + - Failed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - changed + - Changed + - 3 + - - total + - Total + - 4 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 0 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 0 + resource_statuses: + File[/etc/motd]: !ruby/object:Puppet::Resource::Status + resource: File[/etc/motd] + file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp + line: 21 + evaluation_time: 0.046776106 + change_count: 1 + out_of_sync_count: 1 + tags: + - file + - class + - motd + - node + - default + time: 2013-10-02 16:54:44.845351 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: content + previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" + desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" + historical_value: + message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" + name: !ruby/sym content_changed + status: success + time: 2013-10-02 16:54:44.885931 -07:00 + out_of_sync: true + changed: true + resource_type: File + title: /etc/motd + skipped: false + failed: false + containment_path: + - Stage[main] + - Motd + - File[/etc/motd] + File[hello.rb]: !ruby/object:Puppet::Resource::Status + resource: File[hello.rb] + file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp + line: 47 + evaluation_time: 0.108021493 + change_count: 0 + out_of_sync_count: 1 + tags: + - file + - hello.rb + - class + - hello + - node + - default + time: 2013-10-02 16:54:49.012379 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: + previous_value: + desired_value: + historical_value: + message: \"Could not find user abcdefghijklmnop\" + status: failure + time: 2013-10-02 16:54:49.120393 -07:00 + out_of_sync: true + changed: false + resource_type: File + title: hello.rb + skipped: false + failed: true + containment_path: + - Stage[main] + - Hello + - File[hello.rb] + configuration_version: 12345 + report_format: 3 + puppet_version: 2.7.20 + kind: apply + environment: production + status: unchanged +HEREDOC + end + + it "should produce a hash of the report" do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment} + hash["report_format"].should == 3 + hash["host"].should == "localhost" + hash["time"].should == Time.parse("2010-07-22 12:19:47.204207 -07:00") + hash["environment"].should == "production" + end + end end end From ad17e93b055599f2794516af045995c12bacd4e1 Mon Sep 17 00:00:00 2001 From: Stephen Gelman Date: Mon, 6 Apr 2015 04:17:12 +0000 Subject: [PATCH 03/17] Add support for report format 4 - Add new sanitizer for report format 4 - property previous_value desired_value and historical_value fields are now allowed to be omitted - Added a "transaction_uuid" field - Added a "containment_path" field to resource statuses - Add "transaction_uuid" column to reports table - Add "containment_path" column to resource_statuses table --- app/models/resource_status.rb | 1 + ...6035502_add_transaction_uuid_to_reports.rb | 5 + ...d_containment_path_to_resource_statuses.rb | 5 + lib/puppet/report_sanitizer.rb | 49 ++++++ spec/lib/puppet/report_sanitizer_spec.rb | 149 ++++++++++++++++++ 5 files changed, 209 insertions(+) create mode 100644 db/migrate/20150406035502_add_transaction_uuid_to_reports.rb create mode 100644 db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb diff --git a/app/models/resource_status.rb b/app/models/resource_status.rb index 042be59c5..9bb25ef48 100644 --- a/app/models/resource_status.rb +++ b/app/models/resource_status.rb @@ -5,6 +5,7 @@ class ResourceStatus < ApplicationRecord accepts_nested_attributes_for :events serialize :tags, Array + serialize :containment_path, Array scope :inspections, -> { joins(:report).where("reports.kind = 'inspect'") } diff --git a/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb b/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb new file mode 100644 index 000000000..101aabfa9 --- /dev/null +++ b/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb @@ -0,0 +1,5 @@ +class AddTransactionUuidToReports < ActiveRecord::Migration + def change + add_column :reports, :transaction_uuid, :string + end +end diff --git a/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb b/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb new file mode 100644 index 000000000..a5e91c4f6 --- /dev/null +++ b/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb @@ -0,0 +1,5 @@ +class AddContainmentPathToResourceStatuses < ActiveRecord::Migration + def change + add_column :resource_statuses, :containment_path, :text + end +end diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index 4228494be..8291e1d2b 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -12,6 +12,8 @@ def sanitize(raw) format2sanitizer.sanitize(raw) when 3 format3sanitizer.sanitize(raw) + when 4 + format4sanitizer.sanitize(raw) end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) @@ -37,6 +39,10 @@ def format2sanitizer() def format3sanitizer() @format3sanitizer ||= ReportSanitizer::FormatVersion3.new end + + def format4sanitizer() + @format4sanitizer ||= ReportSanitizer::FormatVersion4.new + end end module Util @@ -227,4 +233,47 @@ def sanitize(raw) Util.copy_attributes(sanitized, raw, %w[kind status puppet_version configuration_version environment]) end end + + # format version 4 is used by puppet since version 3.3.0 + class FormatVersion4 < FormatVersion3 + def initialize( + log_sanitizer = LogSanitizer.new, + metric_sanitizer = MetricSanitizer.new, + status_sanitizer = FormatVersion4StatusSanitizer.new + ) + super(log_sanitizer, metric_sanitizer, status_sanitizer) + end + + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[kind status puppet_version configuration_version environment transaction_uuid]) + Util.copy_attributes(sanitized, raw, %w[kind status puppet_version configuration_version environment transaction_uuid]) + end + + class FormatVersion4StatusSanitizer < ExtendedStatusSanitizer + def initialize(event_sanitizer = FormatVersion4EventSanitizer.new) + super(event_sanitizer) + end + + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[containment_path]) + Util.copy_attributes(sanitized, raw, %w[containment_path]) + end + + class FormatVersion4EventSanitizer < ExtendedEventSanitizer + def sanitize(raw) + Util.verify_attributes(raw, %w[message status time audited]) + + sanitized = {} + + if raw['name'] + sanitized['name'] = raw['name'].to_s + end + + Util.copy_attributes(sanitized, raw, %w[previous_value desired_value message property status time audited historical_value]) + end + end + end + end end diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index b0bdba1d6..8f114ffc4 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -633,5 +633,154 @@ hash["environment"].should == "production" end end + + describe 'a format version 4 (puppet 3.3.0-) report' do + let :raw_report do + YAML.load(< :true, :deserialize_symbols => true) +--- !ruby/object:Puppet::Transaction::Report + host: localhost + time: 2010-07-22 12:19:47.204207 -07:00 + logs: [] + metrics: + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - config_retrieval + - Config retrieval + - 0.25 + - - total + - Total + - 0.5 + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - failed + - Failed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - changed + - Changed + - 3 + - - total + - Total + - 4 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 0 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 0 + resource_statuses: + File[/etc/motd]: !ruby/object:Puppet::Resource::Status + resource: File[/etc/motd] + file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp + line: 21 + evaluation_time: 0.046776106 + change_count: 1 + out_of_sync_count: 1 + tags: + - file + - class + - motd + - node + - default + time: 2013-10-02 16:54:44.845351 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: content + previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" + desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" + historical_value: + message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" + name: !ruby/sym content_changed + status: success + time: 2013-10-02 16:54:44.885931 -07:00 + out_of_sync: true + changed: true + resource_type: File + title: /etc/motd + skipped: false + failed: false + containment_path: + - Stage[main] + - Motd + - File[/etc/motd] + File[hello.rb]: !ruby/object:Puppet::Resource::Status + resource: File[hello.rb] + file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp + line: 47 + evaluation_time: 0.108021493 + change_count: 0 + out_of_sync_count: 1 + tags: + - file + - hello.rb + - class + - hello + - node + - default + time: 2013-10-02 16:54:49.012379 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + message: \"Could not find user abcdefghijklmnop\" + status: failure + time: 2013-10-02 16:54:49.120393 -07:00 + out_of_sync: true + changed: false + resource_type: File + title: hello.rb + skipped: false + failed: true + containment_path: + - Stage[main] + - Hello + - File[hello.rb] + configuration_version: 12345 + report_format: 4 + puppet_version: 3.3.0 + kind: apply + transaction_uuid: b2b7567c-696a-4250-8d74-e3c5030e1263 + environment: production + status: unchanged +HEREDOC + end + + it "should produce a hash of the report" do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid} + hash["report_format"].should == 4 + hash["host"].should == "localhost" + hash["time"].should == Time.parse("2010-07-22 12:19:47.204207 -07:00") + hash["environment"].should == "production" + hash["transaction_uuid"].should == "b2b7567c-696a-4250-8d74-e3c5030e1263" + end + + it "should have resource_statuses that contain a containment_path" do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash["resource_statuses"].values.each do |resource_status| + resource_status["containment_path"].should be_a(Array) + end + end + + it "should allow resource events that do not contain property previous_value desired_value or historical_value" do + expect { ReportSanitizer.sanitize(raw_report) }.to_not raise_error ArgumentError + end + end end end From e4e9aac93909259e0ade4e755de7e28c20157b70 Mon Sep 17 00:00:00 2001 From: Stephen Gelman Date: Sat, 17 Oct 2015 03:58:38 +0000 Subject: [PATCH 04/17] Fix report format 4 for puppet 4.0 and newer Very frustratingly puppet slightly changed the report format in puppet 4.0 but did not document the change. Information about the change can be found at https://tickets.puppetlabs.com/browse/DOCUMENT-436. In short, this commit takes the hash that is now returned as the tags and converts it into the old style of array. --- lib/puppet/report_sanitizer.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index 8291e1d2b..dffb1400d 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -237,7 +237,7 @@ def sanitize(raw) # format version 4 is used by puppet since version 3.3.0 class FormatVersion4 < FormatVersion3 def initialize( - log_sanitizer = LogSanitizer.new, + log_sanitizer = FormatVersion4LogSanitizer.new, metric_sanitizer = MetricSanitizer.new, status_sanitizer = FormatVersion4StatusSanitizer.new ) @@ -250,6 +250,16 @@ def sanitize(raw) Util.copy_attributes(sanitized, raw, %w[kind status puppet_version configuration_version environment transaction_uuid]) end + class FormatVersion4LogSanitizer < LogSanitizer + def sanitize(raw) + sanitized = super + unless sanitized['tags'].is_a?(Array) + sanitized['tags'] = raw['tags']['hash'].keys + end + sanitized + end + end + class FormatVersion4StatusSanitizer < ExtendedStatusSanitizer def initialize(event_sanitizer = FormatVersion4EventSanitizer.new) super(event_sanitizer) @@ -259,6 +269,11 @@ def sanitize(raw) sanitized = super Util.verify_attributes(raw, %w[containment_path]) Util.copy_attributes(sanitized, raw, %w[containment_path]) + + unless sanitized['tags'].is_a?(Array) + sanitized['tags'] = raw['tags']['hash'].keys + end + sanitized end class FormatVersion4EventSanitizer < ExtendedEventSanitizer From e1d9400a0439f210ab349e86ccfaaf890f50473e Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Tue, 12 Jun 2018 16:50:35 +0200 Subject: [PATCH 05/17] fix rails update related issues with the rebased report sanitation branch --- ...150405234511_add_environment_to_reports.rb | 2 +- ...6035502_add_transaction_uuid_to_reports.rb | 2 +- ...d_containment_path_to_resource_statuses.rb | 2 +- db/schema.rb | 287 +++++++++--------- spec/lib/puppet/report_sanitizer_spec.rb | 2 +- 5 files changed, 146 insertions(+), 149 deletions(-) diff --git a/db/migrate/20150405234511_add_environment_to_reports.rb b/db/migrate/20150405234511_add_environment_to_reports.rb index d6d94a5a6..8fd39889d 100644 --- a/db/migrate/20150405234511_add_environment_to_reports.rb +++ b/db/migrate/20150405234511_add_environment_to_reports.rb @@ -1,4 +1,4 @@ -class AddEnvironmentToReports < ActiveRecord::Migration +class AddEnvironmentToReports < ActiveRecord::Migration[4.2] def change add_column :reports, :environment, :string end diff --git a/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb b/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb index 101aabfa9..22e83940f 100644 --- a/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb +++ b/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb @@ -1,4 +1,4 @@ -class AddTransactionUuidToReports < ActiveRecord::Migration +class AddTransactionUuidToReports < ActiveRecord::Migration[4.2] def change add_column :reports, :transaction_uuid, :string end diff --git a/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb b/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb index a5e91c4f6..006383826 100644 --- a/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb +++ b/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb @@ -1,4 +1,4 @@ -class AddContainmentPathToResourceStatuses < ActiveRecord::Migration +class AddContainmentPathToResourceStatuses < ActiveRecord::Migration[4.2] def change add_column :resource_statuses, :containment_path, :text end diff --git a/db/schema.rb b/db/schema.rb index 4d65b9794..ae658a9c2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,4 +1,3 @@ -# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -11,208 +10,206 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141217071943) do +ActiveRecord::Schema.define(version: 2015_04_06_035704) do - create_table "delayed_job_failures", force: true do |t| - t.string "summary" - t.binary "details", limit: 2147483647 - t.boolean "read", default: false, null: false + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "delayed_job_failures", id: :serial, force: :cascade do |t| + t.string "summary", limit: 255 + t.binary "details" + t.boolean "read", default: false, null: false t.datetime "created_at" t.datetime "updated_at" - t.text "backtrace" + t.text "backtrace" end - create_table "delayed_jobs", force: true do |t| - t.integer "priority", default: 0 - t.integer "attempts", default: 0 - t.binary "handler", limit: 2147483647 - t.text "last_error" + create_table "delayed_jobs", id: :serial, force: :cascade do |t| + t.integer "priority", default: 0 + t.integer "attempts", default: 0 + t.binary "handler" + t.text "last_error" t.datetime "run_at" t.datetime "locked_at" t.datetime "failed_at" - t.string "locked_by" + t.string "locked_by" t.datetime "created_at" t.datetime "updated_at" - t.string "queue" + t.string "queue" + t.index ["failed_at", "run_at", "locked_at", "locked_by"], name: "index_delayed_jobs_multi" + t.index ["priority", "run_at"], name: "delayed_jobs_priority" end - add_index "delayed_jobs", ["failed_at", "run_at", "locked_at", "locked_by"], name: "index_delayed_jobs_multi", using: :btree - add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree - - create_table "metrics", force: true do |t| - t.integer "report_id", null: false - t.string "category" - t.string "name" - t.decimal "value", precision: 12, scale: 6 + create_table "metrics", id: :serial, force: :cascade do |t| + t.integer "report_id", null: false + t.string "category" + t.string "name" + t.decimal "value", precision: 12, scale: 6 + t.index ["report_id", "category", "name"], name: "index_metrics_multi" + t.index ["report_id"], name: "index_metrics_on_report_id" end - add_index "metrics", ["report_id", "category", "name"], name: "index_metrics_multi", using: :btree - add_index "metrics", ["report_id"], name: "index_metrics_on_report_id", using: :btree - - create_table "node_class_memberships", force: true do |t| - t.integer "node_id" - t.integer "node_class_id" + create_table "node_class_memberships", id: :serial, force: :cascade do |t| + t.integer "node_id" + t.integer "node_class_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["node_class_id"], name: "index_node_class_memberships_on_node_class_id" + t.index ["node_id"], name: "index_node_class_memberships_on_node_id" end - add_index "node_class_memberships", ["node_class_id"], name: "index_node_class_memberships_on_node_class_id", using: :btree - add_index "node_class_memberships", ["node_id"], name: "index_node_class_memberships_on_node_id", using: :btree - - create_table "node_classes", force: true do |t| - t.string "name" + create_table "node_classes", id: :serial, force: :cascade do |t| + t.string "name" t.datetime "created_at" t.datetime "updated_at" - t.text "description" + t.text "description" end - create_table "node_group_class_memberships", force: true do |t| - t.integer "node_group_id" - t.integer "node_class_id" + create_table "node_group_class_memberships", id: :serial, force: :cascade do |t| + t.integer "node_group_id" + t.integer "node_class_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["node_class_id"], name: "index_node_group_class_memberships_on_node_class_id" + t.index ["node_group_id"], name: "index_node_group_class_memberships_on_node_group_id" end - add_index "node_group_class_memberships", ["node_class_id"], name: "index_node_group_class_memberships_on_node_class_id", using: :btree - add_index "node_group_class_memberships", ["node_group_id"], name: "index_node_group_class_memberships_on_node_group_id", using: :btree - - create_table "node_group_edges", force: true do |t| - t.integer "to_id" - t.integer "from_id" + create_table "node_group_edges", id: :serial, force: :cascade do |t| + t.integer "to_id" + t.integer "from_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["from_id"], name: "index_node_group_edges_on_from_id" + t.index ["to_id"], name: "index_node_group_edges_on_to_id" end - add_index "node_group_edges", ["from_id"], name: "index_node_group_edges_on_from_id", using: :btree - add_index "node_group_edges", ["to_id"], name: "index_node_group_edges_on_to_id", using: :btree - - create_table "node_group_memberships", force: true do |t| - t.integer "node_id" - t.integer "node_group_id" + create_table "node_group_memberships", id: :serial, force: :cascade do |t| + t.integer "node_id" + t.integer "node_group_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["node_group_id"], name: "index_node_group_memberships_on_node_group_id" + t.index ["node_id"], name: "index_node_group_memberships_on_node_id" end - add_index "node_group_memberships", ["node_group_id"], name: "index_node_group_memberships_on_node_group_id", using: :btree - add_index "node_group_memberships", ["node_id"], name: "index_node_group_memberships_on_node_id", using: :btree - - create_table "node_groups", force: true do |t| - t.string "name" + create_table "node_groups", id: :serial, force: :cascade do |t| + t.string "name" t.datetime "created_at" t.datetime "updated_at" - t.text "description" + t.text "description" end - create_table "nodes", force: true do |t| - t.string "name" - t.text "description" + create_table "nodes", id: :serial, force: :cascade do |t| + t.string "name" + t.text "description" t.datetime "created_at" t.datetime "updated_at" t.datetime "reported_at" - t.integer "last_apply_report_id" - t.string "status" - t.boolean "hidden", default: false - t.integer "last_inspect_report_id" - t.string "environment" - end - - add_index "nodes", ["last_apply_report_id"], name: "index_nodes_on_last_apply_report_id", using: :btree - add_index "nodes", ["name"], name: "uc_node_name", unique: true, using: :btree - - create_table "old_reports", force: true do |t| - t.integer "node_id" - t.text "report", limit: 16777215 + t.integer "last_apply_report_id" + t.string "status" + t.boolean "hidden", default: false + t.integer "last_inspect_report_id" + t.string "environment" + t.index ["last_apply_report_id"], name: "index_nodes_on_last_apply_report_id" + t.index ["name"], name: "uc_node_name", unique: true + end + + create_table "old_reports", id: :serial, force: :cascade do |t| + t.integer "node_id" + t.text "report" t.datetime "created_at" t.datetime "updated_at" - t.string "host" + t.string "host" t.datetime "time" - t.string "status" + t.string "status" end - create_table "parameters", force: true do |t| - t.string "key" - t.text "value" - t.integer "parameterable_id" - t.string "parameterable_type" + create_table "parameters", id: :serial, force: :cascade do |t| + t.string "key" + t.text "value" + t.integer "parameterable_id" + t.string "parameterable_type" t.datetime "created_at" t.datetime "updated_at" + t.index ["parameterable_id", "parameterable_type", "key"], name: "index_parameters_multi" + t.index ["parameterable_type", "parameterable_id"], name: "index_parameters_on_parameterable_type_and_parameterable_id" end - add_index "parameters", ["parameterable_id", "parameterable_type", "key"], name: "index_parameters_multi", using: :btree - add_index "parameters", ["parameterable_type", "parameterable_id"], name: "index_parameters_on_parameterable_type_and_parameterable_id", using: :btree - - create_table "report_logs", force: true do |t| - t.integer "report_id", null: false - t.string "level" - t.text "message" - t.text "source" - t.text "tags" + create_table "report_logs", id: :serial, force: :cascade do |t| + t.integer "report_id", null: false + t.string "level" + t.text "message" + t.text "source" + t.text "tags" t.datetime "time" - t.text "file" - t.integer "line" + t.text "file" + t.integer "line" + t.index ["report_id"], name: "index_report_logs_on_report_id" end - add_index "report_logs", ["report_id"], name: "index_report_logs_on_report_id", using: :btree - - create_table "reports", force: true do |t| - t.integer "node_id" - t.string "host" + create_table "reports", id: :serial, force: :cascade do |t| + t.integer "node_id" + t.string "host" t.datetime "time" - t.string "status" - t.string "kind" - t.string "puppet_version" - t.string "configuration_version" - end - - add_index "reports", ["node_id"], name: "index_reports_on_node_id", using: :btree - add_index "reports", ["time", "node_id", "status"], name: "index_reports_on_time_and_node_id_and_status", using: :btree - - create_table "resource_events", force: true do |t| - t.integer "resource_status_id", null: false - t.text "previous_value" - t.text "desired_value" - t.binary "message", limit: 2147483647 - t.string "name" - t.string "property" - t.string "status" + t.string "status" + t.string "kind" + t.string "puppet_version" + t.string "configuration_version" + t.string "environment" + t.string "transaction_uuid" + t.index ["node_id"], name: "index_reports_on_node_id" + t.index ["time", "node_id", "status"], name: "index_reports_on_time_and_node_id_and_status" + end + + create_table "resource_events", id: :serial, force: :cascade do |t| + t.integer "resource_status_id", null: false + t.text "previous_value" + t.text "desired_value" + t.binary "message" + t.string "name" + t.string "property" + t.string "status" t.datetime "time" - t.text "historical_value" - t.boolean "audited" - end - - add_index "resource_events", ["resource_status_id"], name: "index_resource_events_on_resource_status_id", using: :btree - - create_table "resource_statuses", force: true do |t| - t.integer "report_id", null: false - t.string "resource_type" - t.text "title" - t.decimal "evaluation_time", precision: 12, scale: 6 - t.text "file" - t.integer "line" - t.text "tags" + t.text "historical_value" + t.boolean "audited" + t.index ["resource_status_id"], name: "index_resource_events_on_resource_status_id" + end + + create_table "resource_statuses", id: :serial, force: :cascade do |t| + t.integer "report_id", null: false + t.string "resource_type" + t.text "title" + t.decimal "evaluation_time", precision: 12, scale: 6 + t.text "file" + t.integer "line" + t.text "tags" t.datetime "time" - t.integer "change_count" - t.integer "out_of_sync_count" - t.boolean "skipped" - t.boolean "failed" - t.string "status" - end - - add_index "resource_statuses", ["report_id"], name: "index_resource_statuses_on_report_id", using: :btree - - create_table "timeline_events", force: true do |t| - t.string "event_type" - t.string "subject_type" - t.string "actor_type" - t.string "secondary_subject_type" - t.integer "subject_id" - t.integer "actor_id" - t.integer "secondary_subject_id" + t.integer "change_count" + t.integer "out_of_sync_count" + t.boolean "skipped" + t.boolean "failed" + t.string "status" + t.text "containment_path" + t.index ["report_id"], name: "index_resource_statuses_on_report_id" + end + + create_table "timeline_events", id: :serial, force: :cascade do |t| + t.string "event_type" + t.string "subject_type" + t.string "actor_type" + t.string "secondary_subject_type" + t.integer "subject_id" + t.integer "actor_id" + t.integer "secondary_subject_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["secondary_subject_id", "secondary_subject_type"], name: "index_timeline_events_secondary" + t.index ["subject_id", "subject_type"], name: "index_timeline_events_primary" end - add_index "timeline_events", ["secondary_subject_id", "secondary_subject_type"], name: "index_timeline_events_secondary", using: :btree - add_index "timeline_events", ["subject_id", "subject_type"], name: "index_timeline_events_primary", using: :btree - + add_foreign_key "metrics", "reports", name: "fk_metrics_report_id", on_delete: :cascade + add_foreign_key "report_logs", "reports", name: "fk_report_logs_report_id", on_delete: :cascade + add_foreign_key "reports", "nodes", name: "fk_reports_node_id", on_delete: :cascade + add_foreign_key "resource_events", "resource_statuses", name: "fk_resource_events_resource_status_id", on_delete: :cascade + add_foreign_key "resource_statuses", "reports", name: "fk_resource_statuses_report_id", on_delete: :cascade end diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index 8f114ffc4..bce7ca356 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -779,7 +779,7 @@ end it "should allow resource events that do not contain property previous_value desired_value or historical_value" do - expect { ReportSanitizer.sanitize(raw_report) }.to_not raise_error ArgumentError + expect { ReportSanitizer.sanitize(raw_report) }.to_not raise_error end end end From 2aeeafd5ce6d6901296391b96acbdc12dda87742 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Tue, 12 Jun 2018 22:23:32 +0200 Subject: [PATCH 06/17] move the report format test data to the fixtures directory --- lib/puppet/report_sanitizer.rb | 3 + spec/fixtures/reports/formats/00_changes.yaml | 101 +++++ spec/fixtures/reports/formats/01_changes.yaml | 262 ++++++++++++ spec/fixtures/reports/formats/02_failing.yaml | 121 ++++++ spec/fixtures/reports/formats/03_failing.yaml | 122 ++++++ spec/fixtures/reports/formats/04_failing.yaml | 119 ++++++ spec/lib/puppet/report_sanitizer_spec.rb | 401 +----------------- 7 files changed, 745 insertions(+), 384 deletions(-) create mode 100644 spec/fixtures/reports/formats/00_changes.yaml create mode 100644 spec/fixtures/reports/formats/01_changes.yaml create mode 100644 spec/fixtures/reports/formats/02_failing.yaml create mode 100644 spec/fixtures/reports/formats/03_failing.yaml create mode 100644 spec/fixtures/reports/formats/04_failing.yaml diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index dffb1400d..e6a833069 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -2,6 +2,9 @@ # using safe_yaml into structures expected by the model code. # Note that this must be updated whenever any of those changes. # +# Report Format Docs: +# https://github.com/puppetlabs/puppet-docs/blob/master/source/_includes/reportformat +# module ReportSanitizer #:nodoc: class << self def sanitize(raw) diff --git a/spec/fixtures/reports/formats/00_changes.yaml b/spec/fixtures/reports/formats/00_changes.yaml new file mode 100644 index 000000000..075c26004 --- /dev/null +++ b/spec/fixtures/reports/formats/00_changes.yaml @@ -0,0 +1,101 @@ +--- !ruby/object:Puppet::Transaction::Report +host: sample_node +logs: +- !ruby/object:Puppet::Util::Log + level: :info + message: Applying configuration version '1258679330' + source: Puppet + tags: + - info + time: 2009-11-19 17:08:50.557829 -08:00 +- !ruby/object:Puppet::Util::Log + level: :info + message: Adding /tmp/puppet_test(6d0007e52f7afb7d5a0650b0ffb8a4d1) + source: Filebucket[/tmp/puppet/var/clientbucket] + tags: + - info + time: 2009-11-19 17:08:50.605975 -08:00 +- !ruby/object:Puppet::Util::Log + file: /tmp/puppet/manifests/site.pp + level: :info + line: 4 + message: Filebucketed /tmp/puppet_test to puppet with sum 6d0007e52f7afb7d5a0650b0ffb8a4d1 + source: //Node[default]/File[/tmp/puppet_test] + tags: + - file + - node + - default + - class + - main + - info + time: 2009-11-19 17:08:50.607171 -08:00 + version: 1258679330 +- !ruby/object:Puppet::Util::Log + file: /tmp/puppet/manifests/site.pp + level: :notice + line: 4 + message: content changed '{md5}6d0007e52f7afb7d5a0650b0ffb8a4d1' to 'unknown checksum' + source: //Node[default]/File[/tmp/puppet_test]/content + tags: + - file + - node + - default + - class + - main + - content + - notice + time: 2009-11-19 17:08:50.625690 -08:00 + version: 1258679330 +metrics: + time: !ruby/object:Puppet::Util::Metric + label: Time + name: time + values: + - - :config_retrieval + - Config retrieval + - 0.185256958007812 + - - :total + - Total + - 0.253255844116211 + - - :file + - File + - 0.0679988861083984 + resources: !ruby/object:Puppet::Util::Metric + label: Resources + name: resources + values: + - - :out_of_sync + - Out of sync + - 1 + - - :total + - Total + - 3 + - - :scheduled + - Scheduled + - 1 + - - :skipped + - Skipped + - 0 + - - :applied + - Applied + - 1 + - - :restarted + - Restarted + - 0 + - - :failed_restarts + - Failed restarts + - 0 + - - :failed + - Failed + - 0 + changes: !ruby/object:Puppet::Util::Metric + label: Changes + name: changes + values: + - - :total + - Total + - 1 +records: {} + +time: 2009-11-19 17:08:50.631428 -08:00 + diff --git a/spec/fixtures/reports/formats/01_changes.yaml b/spec/fixtures/reports/formats/01_changes.yaml new file mode 100644 index 000000000..6e8850432 --- /dev/null +++ b/spec/fixtures/reports/formats/01_changes.yaml @@ -0,0 +1,262 @@ +--- !ruby/object:Puppet::Transaction::Report + external_times: + !ruby/sym config_retrieval: 0.158488988876343 + host: puppet.puppetlabs.vm + logs: + - !ruby/object:Puppet::Util::Log + level: !ruby/sym info + message: Caching catalog for puppet.puppetlabs.vm + source: Puppet + tags: + - info + time: 2010-07-22 12:19:47.204207 -07:00 + version: &id001 2.6.0 + - !ruby/object:Puppet::Util::Log + level: !ruby/sym info + message: Applying configuration version '1279826342' + source: Puppet + tags: + - info + time: 2010-07-22 12:19:47.259181 -07:00 + version: *id001 + - !ruby/object:Puppet::Util::Log + file: &id002 /etc/puppet/manifests/site.pp + level: !ruby/sym notice + line: 9 + message: &id003 executed successfully + source: &id004 "/Stage[main]//Node[default]/Exec[/bin/true]/returns" + tags: + - notice + - exec + - node + - default + - class + time: 2010-07-22 12:19:47.360749 -07:00 + version: 1279826342 + - !ruby/object:Puppet::Util::Log + file: *id002 + level: !ruby/sym notice + line: 8 + message: &id005 ensure changed 'stopped' to 'running' + source: &id006 "/Stage[main]//Node[default]/Service[mysqld]/ensure" + tags: + - notice + - service + - mysqld + - node + - default + - class + time: 2010-07-22 12:19:48.921554 -07:00 + version: 1279826342 + metrics: + time: !ruby/object:Puppet::Util::Metric + label: Time + name: time + values: + - - schedule + - Schedule + - 0.001672 + - - service + - Service + - 1.555161 + - - config_retrieval + - Config retrieval + - 0.158488988876343 + - - filebucket + - Filebucket + - 0.000237 + - - exec + - Exec + - 0.100309 + resources: !ruby/object:Puppet::Util::Metric + label: Resources + name: resources + values: + - - !ruby/sym total + - Total + - 9 + - - !ruby/sym changed + - Changed + - 2 + - - !ruby/sym out_of_sync + - Out of sync + - 2 + changes: !ruby/object:Puppet::Util::Metric + label: Changes + name: changes + values: + - - !ruby/sym total + - Total + - 2 + events: !ruby/object:Puppet::Util::Metric + label: Events + name: events + values: + - - !ruby/sym total + - Total + - 2 + - - success + - Success + - 2 + resource_statuses: + "Schedule[weekly]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.00033 + events: [] + file: + line: + resource: "Schedule[weekly]" + source_description: "/Schedule[weekly]" + tags: + - schedule + - weekly + time: 2010-07-22 12:19:47.364377 -07:00 + version: 1279826342 + "Filebucket[puppet]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.000237 + events: [] + file: + line: + resource: "Filebucket[puppet]" + source_description: "/Filebucket[puppet]" + tags: + - filebucket + - puppet + time: 2010-07-22 12:19:47.365218 -07:00 + version: 1279826342 + "Exec[/bin/true]": !ruby/object:Puppet::Resource::Status + change_count: 1 + changed: true + evaluation_time: 0.100309 + events: + - !ruby/object:Puppet::Transaction::Event + default_log_level: !ruby/sym notice + desired_value: + - "0" + file: *id002 + line: 9 + message: *id003 + name: !ruby/sym executed_command + previous_value: !ruby/sym notrun + property: returns + resource: "Exec[/bin/true]" + source_description: *id004 + status: success + tags: + - exec + - node + - default + - class + time: 2010-07-22 12:19:47.360626 -07:00 + version: 1279826342 + failed: true + file: *id002 + line: 9 + out_of_sync: true + resource: "Exec[/bin/true]" + source_description: "/Stage[main]//Node[default]/Exec[/bin/true]" + tags: + - exec + - node + - default + - class + time: 2010-07-22 12:19:47.262652 -07:00 + version: 1279826342 + "Schedule[hourly]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.000255 + events: [] + file: + line: + resource: "Schedule[hourly]" + source_description: "/Schedule[hourly]" + tags: + - schedule + - hourly + time: 2010-07-22 12:19:47.261846 -07:00 + version: 1279826342 + "Schedule[daily]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.000216 + events: [] + file: + line: + resource: "Schedule[daily]" + source_description: "/Schedule[daily]" + tags: + - schedule + - daily + time: 2010-07-22 12:19:47.366606 -07:00 + version: 1279826342 + "Schedule[monthly]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.000432 + events: [] + file: + line: + resource: "Schedule[monthly]" + source_description: "/Schedule[monthly]" + tags: + - schedule + - monthly + time: 2010-07-22 12:19:47.260865 -07:00 + version: 1279826342 + "Schedule[puppet]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.000243 + events: [] + file: + line: + resource: "Schedule[puppet]" + source_description: "/Schedule[puppet]" + tags: + - schedule + - puppet + time: 2010-07-22 12:19:48.923135 -07:00 + version: 1279826342 + "Schedule[never]": !ruby/object:Puppet::Resource::Status + evaluation_time: 0.000196 + events: [] + file: + line: + resource: "Schedule[never]" + source_description: "/Schedule[never]" + tags: + - schedule + - never + time: 2010-07-22 12:19:47.365927 -07:00 + version: 1279826342 + "Service[mysqld]": !ruby/object:Puppet::Resource::Status + change_count: 1 + changed: true + evaluation_time: 1.555161 + events: + - !ruby/object:Puppet::Transaction::Event + default_log_level: !ruby/sym notice + desired_value: !ruby/sym running + file: *id002 + line: 8 + message: *id005 + name: !ruby/sym service_started + previous_value: !ruby/sym stopped + property: ensure + resource: "Service[mysqld]" + source_description: *id006 + status: success + tags: + - service + - mysqld + - node + - default + - class + time: 2010-07-22 12:19:48.921431 -07:00 + version: 1279826342 + file: *id002 + line: 8 + out_of_sync: true + resource: "Service[mysqld]" + source_description: "/Stage[main]//Node[default]/Service[mysqld]" + tags: + - service + - mysqld + - node + - default + - class + time: 2010-07-22 12:19:47.367360 -07:00 + version: 1279826342 + time: 2010-07-22 12:19:46.169915 -07:00 diff --git a/spec/fixtures/reports/formats/02_failing.yaml b/spec/fixtures/reports/formats/02_failing.yaml new file mode 100644 index 000000000..2d64b9d47 --- /dev/null +++ b/spec/fixtures/reports/formats/02_failing.yaml @@ -0,0 +1,121 @@ +--- !ruby/object:Puppet::Transaction::Report + host: localhost + time: 2010-07-22 12:19:47.204207 -07:00 + logs: [] + metrics: + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - config_retrieval + - Config retrieval + - 0.25 + - - total + - Total + - 0.5 + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - failed + - Failed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - changed + - Changed + - 3 + - - total + - Total + - 4 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 0 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 0 + resource_statuses: + File[/etc/motd]: !ruby/object:Puppet::Resource::Status + resource: File[/etc/motd] + file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp + line: 21 + evaluation_time: 0.046776106 + change_count: 1 + out_of_sync_count: 1 + tags: + - file + - class + - motd + - node + - default + time: 2013-10-02 16:54:44.845351 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: content + previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" + desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" + historical_value: + message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" + name: !ruby/sym content_changed + status: success + time: 2013-10-02 16:54:44.885931 -07:00 + out_of_sync: true + changed: true + resource_type: File + title: /etc/motd + skipped: false + failed: false + containment_path: + - Stage[main] + - Motd + - File[/etc/motd] + File[hello.rb]: !ruby/object:Puppet::Resource::Status + resource: File[hello.rb] + file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp + line: 47 + evaluation_time: 0.108021493 + change_count: 0 + out_of_sync_count: 1 + tags: + - file + - hello.rb + - class + - hello + - node + - default + time: 2013-10-02 16:54:49.012379 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: + previous_value: + desired_value: + historical_value: + message: \"Could not find user abcdefghijklmnop\" + status: failure + time: 2013-10-02 16:54:49.120393 -07:00 + out_of_sync: true + changed: false + resource_type: File + title: hello.rb + skipped: false + failed: true + containment_path: + - Stage[main] + - Hello + - File[hello.rb] + configuration_version: 12345 + report_format: 2 + puppet_version: 2.6.5 + kind: apply + status: unchanged diff --git a/spec/fixtures/reports/formats/03_failing.yaml b/spec/fixtures/reports/formats/03_failing.yaml new file mode 100644 index 000000000..82361e530 --- /dev/null +++ b/spec/fixtures/reports/formats/03_failing.yaml @@ -0,0 +1,122 @@ +--- !ruby/object:Puppet::Transaction::Report + host: localhost + time: 2010-07-22 12:19:47.204207 -07:00 + logs: [] + metrics: + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - config_retrieval + - Config retrieval + - 0.25 + - - total + - Total + - 0.5 + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - failed + - Failed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - changed + - Changed + - 3 + - - total + - Total + - 4 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 0 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 0 + resource_statuses: + File[/etc/motd]: !ruby/object:Puppet::Resource::Status + resource: File[/etc/motd] + file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp + line: 21 + evaluation_time: 0.046776106 + change_count: 1 + out_of_sync_count: 1 + tags: + - file + - class + - motd + - node + - default + time: 2013-10-02 16:54:44.845351 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: content + previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" + desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" + historical_value: + message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" + name: !ruby/sym content_changed + status: success + time: 2013-10-02 16:54:44.885931 -07:00 + out_of_sync: true + changed: true + resource_type: File + title: /etc/motd + skipped: false + failed: false + containment_path: + - Stage[main] + - Motd + - File[/etc/motd] + File[hello.rb]: !ruby/object:Puppet::Resource::Status + resource: File[hello.rb] + file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp + line: 47 + evaluation_time: 0.108021493 + change_count: 0 + out_of_sync_count: 1 + tags: + - file + - hello.rb + - class + - hello + - node + - default + time: 2013-10-02 16:54:49.012379 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: + previous_value: + desired_value: + historical_value: + message: \"Could not find user abcdefghijklmnop\" + status: failure + time: 2013-10-02 16:54:49.120393 -07:00 + out_of_sync: true + changed: false + resource_type: File + title: hello.rb + skipped: false + failed: true + containment_path: + - Stage[main] + - Hello + - File[hello.rb] + configuration_version: 12345 + report_format: 3 + puppet_version: 2.7.20 + kind: apply + environment: production + status: unchanged diff --git a/spec/fixtures/reports/formats/04_failing.yaml b/spec/fixtures/reports/formats/04_failing.yaml new file mode 100644 index 000000000..178d7f544 --- /dev/null +++ b/spec/fixtures/reports/formats/04_failing.yaml @@ -0,0 +1,119 @@ +--- !ruby/object:Puppet::Transaction::Report + host: localhost + time: 2010-07-22 12:19:47.204207 -07:00 + logs: [] + metrics: + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - config_retrieval + - Config retrieval + - 0.25 + - - total + - Total + - 0.5 + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - failed + - Failed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - changed + - Changed + - 3 + - - total + - Total + - 4 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 0 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 0 + resource_statuses: + File[/etc/motd]: !ruby/object:Puppet::Resource::Status + resource: File[/etc/motd] + file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp + line: 21 + evaluation_time: 0.046776106 + change_count: 1 + out_of_sync_count: 1 + tags: + - file + - class + - motd + - node + - default + time: 2013-10-02 16:54:44.845351 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: content + previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" + desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" + historical_value: + message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" + name: !ruby/sym content_changed + status: success + time: 2013-10-02 16:54:44.885931 -07:00 + out_of_sync: true + changed: true + resource_type: File + title: /etc/motd + skipped: false + failed: false + containment_path: + - Stage[main] + - Motd + - File[/etc/motd] + File[hello.rb]: !ruby/object:Puppet::Resource::Status + resource: File[hello.rb] + file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp + line: 47 + evaluation_time: 0.108021493 + change_count: 0 + out_of_sync_count: 1 + tags: + - file + - hello.rb + - class + - hello + - node + - default + time: 2013-10-02 16:54:49.012379 -07:00 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + message: \"Could not find user abcdefghijklmnop\" + status: failure + time: 2013-10-02 16:54:49.120393 -07:00 + out_of_sync: true + changed: false + resource_type: File + title: hello.rb + skipped: false + failed: true + containment_path: + - Stage[main] + - Hello + - File[hello.rb] + configuration_version: 12345 + report_format: 4 + puppet_version: 3.3.0 + kind: apply + transaction_uuid: b2b7567c-696a-4250-8d74-e3c5030e1263 + environment: production + status: unchanged diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index bce7ca356..cb7009800 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -4,10 +4,19 @@ extend DescribeReports describe 'when sanitizing' do + + let(:formats_dir) do + Rails.root.join('spec', 'fixtures', 'reports', 'formats') + end + let(:report_filename) do + File.join(formats_dir, report_file) + end + let(:raw_report) do + YAML.load_file(report_filename, safe: :true, deserialize_symbols: true) + end + describe 'a format version 0 (puppet 0.25.x) report' do - let :raw_report do - YAML.load_file(Rails.root.join('spec', 'fixtures', 'reports', 'puppet25', '1_changed_0_failures.yml'), :safe => :true, :deserialize_symbols => true) - end + let(:report_file) { '00_changes.yaml' } it "should produce a hash of the report" do hash = ReportSanitizer.sanitize(raw_report) @@ -93,12 +102,7 @@ end describe 'a format version 1 (puppet 2.6.0-2.6.4) report' do - let :report_filename do - Rails.root.join('spec', 'fixtures', 'reports', 'puppet26', 'report_ok_service_started_ok.yaml') - end - let :raw_report do - YAML.load_file(report_filename, :safe => :true, :deserialize_symbols => true) - end + let(:report_file) { '01_changes.yaml' } it "should fill in change_count=0 wherever a report is missing change_count attributes" do report_yaml = File.read(report_filename) @@ -359,131 +363,7 @@ end describe 'a format version 2 (puppet 2.6.5-2.7.11) report' do - let :raw_report do - YAML.load(< :true, :deserialize_symbols => true) ---- !ruby/object:Puppet::Transaction::Report - host: localhost - time: 2010-07-22 12:19:47.204207 -07:00 - logs: [] - metrics: - time: !ruby/object:Puppet::Util::Metric - name: time - label: Time - values: - - - config_retrieval - - Config retrieval - - 0.25 - - - total - - Total - - 0.5 - resources: !ruby/object:Puppet::Util::Metric - name: resources - label: Resources - values: - - - failed - - Failed - - 1 - - - out_of_sync - - Out of sync - - 2 - - - changed - - Changed - - 3 - - - total - - Total - - 4 - events: !ruby/object:Puppet::Util::Metric - name: events - label: Events - values: - - - total - - Total - - 0 - changes: !ruby/object:Puppet::Util::Metric - name: changes - label: Changes - values: - - - total - - Total - - 0 - resource_statuses: - File[/etc/motd]: !ruby/object:Puppet::Resource::Status - resource: File[/etc/motd] - file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp - line: 21 - evaluation_time: 0.046776106 - change_count: 1 - out_of_sync_count: 1 - tags: - - file - - class - - motd - - node - - default - time: 2013-10-02 16:54:44.845351 -07:00 - events: - - !ruby/object:Puppet::Transaction::Event - audited: false - property: content - previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" - desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" - historical_value: - message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" - name: !ruby/sym content_changed - status: success - time: 2013-10-02 16:54:44.885931 -07:00 - out_of_sync: true - changed: true - resource_type: File - title: /etc/motd - skipped: false - failed: false - containment_path: - - Stage[main] - - Motd - - File[/etc/motd] - File[hello.rb]: !ruby/object:Puppet::Resource::Status - resource: File[hello.rb] - file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp - line: 47 - evaluation_time: 0.108021493 - change_count: 0 - out_of_sync_count: 1 - tags: - - file - - hello.rb - - class - - hello - - node - - default - time: 2013-10-02 16:54:49.012379 -07:00 - events: - - !ruby/object:Puppet::Transaction::Event - audited: false - property: - previous_value: - desired_value: - historical_value: - message: \"Could not find user abcdefghijklmnop\" - status: failure - time: 2013-10-02 16:54:49.120393 -07:00 - out_of_sync: true - changed: false - resource_type: File - title: hello.rb - skipped: false - failed: true - containment_path: - - Stage[main] - - Hello - - File[hello.rb] - configuration_version: 12345 - report_format: 2 - puppet_version: 2.6.5 - kind: apply - status: unchanged -HEREDOC - end + let(:report_file) { '02_failing.yaml' } it "should produce a hash of the report" do hash = ReportSanitizer.sanitize(raw_report) @@ -496,132 +376,7 @@ end describe 'a format version 3 (puppet 2.7.13-3.2.4) report' do - let :raw_report do - YAML.load(< :true, :deserialize_symbols => true) ---- !ruby/object:Puppet::Transaction::Report - host: localhost - time: 2010-07-22 12:19:47.204207 -07:00 - logs: [] - metrics: - time: !ruby/object:Puppet::Util::Metric - name: time - label: Time - values: - - - config_retrieval - - Config retrieval - - 0.25 - - - total - - Total - - 0.5 - resources: !ruby/object:Puppet::Util::Metric - name: resources - label: Resources - values: - - - failed - - Failed - - 1 - - - out_of_sync - - Out of sync - - 2 - - - changed - - Changed - - 3 - - - total - - Total - - 4 - events: !ruby/object:Puppet::Util::Metric - name: events - label: Events - values: - - - total - - Total - - 0 - changes: !ruby/object:Puppet::Util::Metric - name: changes - label: Changes - values: - - - total - - Total - - 0 - resource_statuses: - File[/etc/motd]: !ruby/object:Puppet::Resource::Status - resource: File[/etc/motd] - file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp - line: 21 - evaluation_time: 0.046776106 - change_count: 1 - out_of_sync_count: 1 - tags: - - file - - class - - motd - - node - - default - time: 2013-10-02 16:54:44.845351 -07:00 - events: - - !ruby/object:Puppet::Transaction::Event - audited: false - property: content - previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" - desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" - historical_value: - message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" - name: !ruby/sym content_changed - status: success - time: 2013-10-02 16:54:44.885931 -07:00 - out_of_sync: true - changed: true - resource_type: File - title: /etc/motd - skipped: false - failed: false - containment_path: - - Stage[main] - - Motd - - File[/etc/motd] - File[hello.rb]: !ruby/object:Puppet::Resource::Status - resource: File[hello.rb] - file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp - line: 47 - evaluation_time: 0.108021493 - change_count: 0 - out_of_sync_count: 1 - tags: - - file - - hello.rb - - class - - hello - - node - - default - time: 2013-10-02 16:54:49.012379 -07:00 - events: - - !ruby/object:Puppet::Transaction::Event - audited: false - property: - previous_value: - desired_value: - historical_value: - message: \"Could not find user abcdefghijklmnop\" - status: failure - time: 2013-10-02 16:54:49.120393 -07:00 - out_of_sync: true - changed: false - resource_type: File - title: hello.rb - skipped: false - failed: true - containment_path: - - Stage[main] - - Hello - - File[hello.rb] - configuration_version: 12345 - report_format: 3 - puppet_version: 2.7.20 - kind: apply - environment: production - status: unchanged -HEREDOC - end + let(:report_file) { '03_failing.yaml' } it "should produce a hash of the report" do hash = ReportSanitizer.sanitize(raw_report) @@ -634,130 +389,8 @@ end end - describe 'a format version 4 (puppet 3.3.0-) report' do - let :raw_report do - YAML.load(< :true, :deserialize_symbols => true) ---- !ruby/object:Puppet::Transaction::Report - host: localhost - time: 2010-07-22 12:19:47.204207 -07:00 - logs: [] - metrics: - time: !ruby/object:Puppet::Util::Metric - name: time - label: Time - values: - - - config_retrieval - - Config retrieval - - 0.25 - - - total - - Total - - 0.5 - resources: !ruby/object:Puppet::Util::Metric - name: resources - label: Resources - values: - - - failed - - Failed - - 1 - - - out_of_sync - - Out of sync - - 2 - - - changed - - Changed - - 3 - - - total - - Total - - 4 - events: !ruby/object:Puppet::Util::Metric - name: events - label: Events - values: - - - total - - Total - - 0 - changes: !ruby/object:Puppet::Util::Metric - name: changes - label: Changes - values: - - - total - - Total - - 0 - resource_statuses: - File[/etc/motd]: !ruby/object:Puppet::Resource::Status - resource: File[/etc/motd] - file: /etc/puppetlabs/puppet/modules/motd/manifests/init.pp - line: 21 - evaluation_time: 0.046776106 - change_count: 1 - out_of_sync_count: 1 - tags: - - file - - class - - motd - - node - - default - time: 2013-10-02 16:54:44.845351 -07:00 - events: - - !ruby/object:Puppet::Transaction::Event - audited: false - property: content - previous_value: \"{md5}576c30100670abe54a2446d05d72e4cf\" - desired_value: \"{md5}892b87473b3ce3afbcb28198ac02f02d\" - historical_value: - message: \"content changed '{md5}576c30100670abe54a2446d05d72e4cf' to '{md5}892b87473b3ce3afbcb28198ac02f02d'\" - name: !ruby/sym content_changed - status: success - time: 2013-10-02 16:54:44.885931 -07:00 - out_of_sync: true - changed: true - resource_type: File - title: /etc/motd - skipped: false - failed: false - containment_path: - - Stage[main] - - Motd - - File[/etc/motd] - File[hello.rb]: !ruby/object:Puppet::Resource::Status - resource: File[hello.rb] - file: /etc/puppetlabs/puppet/modules/hello/manifests/init.pp - line: 47 - evaluation_time: 0.108021493 - change_count: 0 - out_of_sync_count: 1 - tags: - - file - - hello.rb - - class - - hello - - node - - default - time: 2013-10-02 16:54:49.012379 -07:00 - events: - - !ruby/object:Puppet::Transaction::Event - audited: false - message: \"Could not find user abcdefghijklmnop\" - status: failure - time: 2013-10-02 16:54:49.120393 -07:00 - out_of_sync: true - changed: false - resource_type: File - title: hello.rb - skipped: false - failed: true - containment_path: - - Stage[main] - - Hello - - File[hello.rb] - configuration_version: 12345 - report_format: 4 - puppet_version: 3.3.0 - kind: apply - transaction_uuid: b2b7567c-696a-4250-8d74-e3c5030e1263 - environment: production - status: unchanged -HEREDOC - end + describe 'a format version 4 (puppet 3.3.0-) report' do + let(:report_file) { '04_failing.yaml' } it "should produce a hash of the report" do hash = ReportSanitizer.sanitize(raw_report) From 13082b5fbc19232577e16abd42728f37fcbb0fba Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Tue, 12 Jun 2018 23:10:34 +0200 Subject: [PATCH 07/17] Add support for report format 5 There are only two new fields in the report model: - catalog_uuid - cached_catalog_status The dashboard database will track them now but they are not otherwise used for now. --- ...80612210108_add_catalog_uuid_to_reports.rb | 5 + ...10_add_cached_catalog_status_to_reports.rb | 5 + db/schema.rb | 4 +- lib/puppet/report_sanitizer.rb | 17 +- spec/fixtures/reports/formats/05_failing.yaml | 340 ++++++++++++++++++ spec/lib/puppet/report_sanitizer_spec.rb | 20 +- 6 files changed, 388 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20180612210108_add_catalog_uuid_to_reports.rb create mode 100644 db/migrate/20180612210310_add_cached_catalog_status_to_reports.rb create mode 100644 spec/fixtures/reports/formats/05_failing.yaml diff --git a/db/migrate/20180612210108_add_catalog_uuid_to_reports.rb b/db/migrate/20180612210108_add_catalog_uuid_to_reports.rb new file mode 100644 index 000000000..4b3b3a8d4 --- /dev/null +++ b/db/migrate/20180612210108_add_catalog_uuid_to_reports.rb @@ -0,0 +1,5 @@ +class AddCatalogUuidToReports < ActiveRecord::Migration[5.2] + def change + add_column :reports, :catalog_uuid, :string + end +end diff --git a/db/migrate/20180612210310_add_cached_catalog_status_to_reports.rb b/db/migrate/20180612210310_add_cached_catalog_status_to_reports.rb new file mode 100644 index 000000000..f668a26a9 --- /dev/null +++ b/db/migrate/20180612210310_add_cached_catalog_status_to_reports.rb @@ -0,0 +1,5 @@ +class AddCachedCatalogStatusToReports < ActiveRecord::Migration[5.2] + def change + add_column :reports, :cached_catalog_status, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index ae658a9c2..f92c01b02 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2015_04_06_035704) do +ActiveRecord::Schema.define(version: 2018_06_12_210310) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -157,6 +157,8 @@ t.string "configuration_version" t.string "environment" t.string "transaction_uuid" + t.string "catalog_uuid" + t.string "cached_catalog_status" t.index ["node_id"], name: "index_reports_on_node_id" t.index ["time", "node_id", "status"], name: "index_reports_on_time_and_node_id_and_status" end diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index e6a833069..369b522e4 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -17,6 +17,8 @@ def sanitize(raw) format3sanitizer.sanitize(raw) when 4 format4sanitizer.sanitize(raw) + when 5 + format5sanitizer.sanitize(raw) end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) @@ -46,6 +48,10 @@ def format3sanitizer() def format4sanitizer() @format4sanitizer ||= ReportSanitizer::FormatVersion4.new end + + def format5sanitizer() + @format5sanitizer ||= ReportSanitizer::FormatVersion5.new + end end module Util @@ -237,7 +243,7 @@ def sanitize(raw) end end - # format version 4 is used by puppet since version 3.3.0 + # format version 4 is used by puppet 3.3.0-4.3.2 class FormatVersion4 < FormatVersion3 def initialize( log_sanitizer = FormatVersion4LogSanitizer.new, @@ -294,4 +300,13 @@ def sanitize(raw) end end end + + class FormatVersion5 < FormatVersion4 + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[catalog_uuid cached_catalog_status]) + Util.copy_attributes(sanitized, raw, %w[catalog_uuid cached_catalog_status]) + end + end + end diff --git a/spec/fixtures/reports/formats/05_failing.yaml b/spec/fixtures/reports/formats/05_failing.yaml new file mode 100644 index 000000000..b1360e8c4 --- /dev/null +++ b/spec/fixtures/reports/formats/05_failing.yaml @@ -0,0 +1,340 @@ +--- !ruby/object:Puppet::Transaction::Report +metrics: + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - total + - Total + - 9 + - - skipped + - Skipped + - 0 + - - failed + - Failed + - 1 + - - failed_to_restart + - Failed to restart + - 0 + - - restarted + - Restarted + - 0 + - - changed + - Changed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - scheduled + - Scheduled + - 0 + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - exec + - Exec + - 0.000414109 + - - notify + - Notify + - 0.000299196 + - - schedule + - Schedule + - 0.00021121800000000002 + - - filebucket + - Filebucket + - 5.9153e-05 + - - config_retrieval + - Config retrieval + - 0.091350051 + - - total + - Total + - 0.092333727 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 1 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 2 + - - failure + - Failure + - 1 + - - success + - Success + - 1 +logs: +- !ruby/object:Puppet::Util::Log + level: :err + message: Could not find command '/usr/bin/thisdoesnotexist' + source: Puppet + tags: + - err + time: '2018-06-12T22:42:23.280034671+02:00' + file: + line: +- !ruby/object:Puppet::Util::Log + level: :err + message: 'change from notrun to 0 failed: Could not find command ''/usr/bin/thisdoesnotexist''' + source: "/Stage[main]/Main/Exec[/usr/bin/thisdoesnotexist]/returns" + tags: + - err + - exec + - class + time: '2018-06-12T22:42:23.280172624+02:00' + file: "/tmp/puppet/test.pp" + line: 2 +- !ruby/object:Puppet::Util::Log + level: :notice + message: hello world + source: Puppet + tags: + - notice + time: '2018-06-12T22:42:23.280526359+02:00' + file: + line: +- !ruby/object:Puppet::Util::Log + level: :notice + message: defined 'message' as 'hello world' + source: "/Stage[main]/Main/Notify[hello world]/message" + tags: + - notice + - notify + - class + time: '2018-06-12T22:42:23.280611559+02:00' + file: "/tmp/puppet/test.pp" + line: 4 +- !ruby/object:Puppet::Util::Log + level: :notice + message: Applied catalog in 0.01 seconds + source: Puppet + tags: + - notice + time: '2018-06-12T22:42:23.290708149+02:00' + file: + line: +resource_statuses: + Exec[/usr/bin/thisdoesnotexist]: !ruby/object:Puppet::Resource::Status + title: "/usr/bin/thisdoesnotexist" + file: "/tmp/puppet/test.pp" + line: 2 + resource: Exec[/usr/bin/thisdoesnotexist] + resource_type: Exec + containment_path: + - Stage[main] + - Main + - Exec[/usr/bin/thisdoesnotexist] + evaluation_time: 0.000414109 + tags: + - exec + - class + time: '2018-06-12T22:42:23.279808312+02:00' + failed: true + changed: false + out_of_sync: true + skipped: false + change_count: 0 + out_of_sync_count: 1 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: returns + previous_value: :notrun + desired_value: + - '0' + historical_value: + message: 'change from notrun to 0 failed: Could not find command ''/usr/bin/thisdoesnotexist''' + name: :executed_command + status: failure + time: 2018-06-12 22:42:23.280119835 +02:00 + Notify[hello world]: !ruby/object:Puppet::Resource::Status + title: hello world + file: "/tmp/puppet/test.pp" + line: 4 + resource: Notify[hello world] + resource_type: Notify + containment_path: + - Stage[main] + - Main + - Notify[hello world] + evaluation_time: 0.000299196 + tags: + - notify + - class + time: '2018-06-12T22:42:23.280350710+02:00' + failed: false + changed: true + out_of_sync: true + skipped: false + change_count: 1 + out_of_sync_count: 1 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: message + previous_value: :absent + desired_value: hello world + historical_value: + message: defined 'message' as 'hello world' + name: :message_changed + status: success + time: 2018-06-12 22:42:23.280493320 +02:00 + Schedule[puppet]: !ruby/object:Puppet::Resource::Status + title: puppet + file: + line: + resource: Schedule[puppet] + resource_type: Schedule + containment_path: + - Schedule[puppet] + evaluation_time: 4.5947e-05 + tags: + - schedule + - puppet + time: '2018-06-12T22:42:23.280903759+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + Schedule[hourly]: !ruby/object:Puppet::Resource::Status + title: hourly + file: + line: + resource: Schedule[hourly] + resource_type: Schedule + containment_path: + - Schedule[hourly] + evaluation_time: 3.3584e-05 + tags: + - schedule + - hourly + time: '2018-06-12T22:42:23.281022745+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + Schedule[daily]: !ruby/object:Puppet::Resource::Status + title: daily + file: + line: + resource: Schedule[daily] + resource_type: Schedule + containment_path: + - Schedule[daily] + evaluation_time: 2.9777e-05 + tags: + - schedule + - daily + time: '2018-06-12T22:42:23.281123256+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + Schedule[weekly]: !ruby/object:Puppet::Resource::Status + title: weekly + file: + line: + resource: Schedule[weekly] + resource_type: Schedule + containment_path: + - Schedule[weekly] + evaluation_time: 2.9812e-05 + tags: + - schedule + - weekly + time: '2018-06-12T22:42:23.281225104+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + Schedule[monthly]: !ruby/object:Puppet::Resource::Status + title: monthly + file: + line: + resource: Schedule[monthly] + resource_type: Schedule + containment_path: + - Schedule[monthly] + evaluation_time: 2.9958e-05 + tags: + - schedule + - monthly + time: '2018-06-12T22:42:23.281355041+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + Schedule[never]: !ruby/object:Puppet::Resource::Status + title: never + file: + line: + resource: Schedule[never] + resource_type: Schedule + containment_path: + - Schedule[never] + evaluation_time: 4.214e-05 + tags: + - schedule + - never + time: '2018-06-12T22:42:23.281454416+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + Filebucket[puppet]: !ruby/object:Puppet::Resource::Status + title: puppet + file: + line: + resource: Filebucket[puppet] + resource_type: Filebucket + containment_path: + - Filebucket[puppet] + evaluation_time: 5.9153e-05 + tags: + - filebucket + - puppet + time: '2018-06-12T22:42:23.281583621+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] +host: report-test.example.com +time: 2018-06-12 22:42:23.273615216 +02:00 +kind: apply +report_format: 5 +puppet_version: 4.5.0 +configuration_version: 1528836143 +transaction_uuid: 439b4577-1b26-4313-91ea-3e2812d41d22 +code_id: +catalog_uuid: da1beb33-3775-4c12-88f5-78ad84a54988 +cached_catalog_status: not_used +environment: production +status: failed diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index cb7009800..f88490178 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -389,7 +389,7 @@ end end - describe 'a format version 4 (puppet 3.3.0-) report' do + describe 'a format version 4 (puppet 3.3.0-4.3.2) report' do let(:report_file) { '04_failing.yaml' } it "should produce a hash of the report" do @@ -415,5 +415,23 @@ expect { ReportSanitizer.sanitize(raw_report) }.to_not raise_error end end + + describe 'a format version 5 (puppet 4.4.0-4.5.3) report' do + let(:report_file) { '05_failing.yaml' } + + it 'should produce a hash of the report' do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid catalog_uuid cached_catalog_status} + hash['report_format'].should == 5 + hash['host'].should == 'report-test.example.com' + hash['time'].should == Time.parse('2018-06-12 22:42:23.273615216 +02:00') + hash['environment'].should == 'production' + hash['transaction_uuid'].should == '439b4577-1b26-4313-91ea-3e2812d41d22' + hash['catalog_uuid'].should == 'da1beb33-3775-4c12-88f5-78ad84a54988' + hash['cached_catalog_status'].should == 'not_used' + end + end + end end From 3e0f09d3c1e58ecccf3f03557b1f112c90084a44 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Thu, 14 Jun 2018 00:42:44 +0200 Subject: [PATCH 08/17] Add support for report format 6 There are a few more additions to report, resource_status and event: - report: noop, noop_pending, corrective_change, master_used - resource_status: corrective_change - event: corrective_change, redacted The dashboard database will track them now but they are not otherwise used for now. --- .../20180613224704_add_report_format6.rb | 13 + db/schema.rb | 9 +- lib/puppet/report_sanitizer.rb | 42 ++ spec/fixtures/reports/formats/06_failing.yaml | 361 ++++++++++++++++++ spec/lib/puppet/report_sanitizer_spec.rb | 22 ++ 5 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20180613224704_add_report_format6.rb create mode 100644 spec/fixtures/reports/formats/06_failing.yaml diff --git a/db/migrate/20180613224704_add_report_format6.rb b/db/migrate/20180613224704_add_report_format6.rb new file mode 100644 index 000000000..c574e4f8b --- /dev/null +++ b/db/migrate/20180613224704_add_report_format6.rb @@ -0,0 +1,13 @@ +class AddReportFormat6 < ActiveRecord::Migration[5.2] + def change + add_column :reports, :noop, :boolean + add_column :reports, :noop_pending, :boolean + add_column :reports, :corrective_change, :boolean + add_column :reports, :master_used, :string + + add_column :resource_statuses, :corrective_change, :boolean + + add_column :resource_events, :corrective_change, :boolean + add_column :resource_events, :redacted, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index f92c01b02..fc71efbea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_06_12_210310) do +ActiveRecord::Schema.define(version: 2018_06_13_224704) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -159,6 +159,10 @@ t.string "transaction_uuid" t.string "catalog_uuid" t.string "cached_catalog_status" + t.boolean "noop" + t.boolean "noop_pending" + t.boolean "corrective_change" + t.string "master_used" t.index ["node_id"], name: "index_reports_on_node_id" t.index ["time", "node_id", "status"], name: "index_reports_on_time_and_node_id_and_status" end @@ -174,6 +178,8 @@ t.datetime "time" t.text "historical_value" t.boolean "audited" + t.boolean "corrective_change" + t.boolean "redacted" t.index ["resource_status_id"], name: "index_resource_events_on_resource_status_id" end @@ -192,6 +198,7 @@ t.boolean "failed" t.string "status" t.text "containment_path" + t.boolean "corrective_change" t.index ["report_id"], name: "index_resource_statuses_on_report_id" end diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index 369b522e4..bb88e16b4 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -19,6 +19,8 @@ def sanitize(raw) format4sanitizer.sanitize(raw) when 5 format5sanitizer.sanitize(raw) + else + format6sanitizer.sanitize(raw) end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) @@ -52,6 +54,10 @@ def format4sanitizer() def format5sanitizer() @format5sanitizer ||= ReportSanitizer::FormatVersion5.new end + + def format6sanitizer() + @format6sanitizer ||= ReportSanitizer::FormatVersion6.new + end end module Util @@ -309,4 +315,40 @@ def sanitize(raw) end end + class FormatVersion6 < FormatVersion5 + def initialize( + log_sanitizer = FormatVersion4LogSanitizer.new, + metric_sanitizer = MetricSanitizer.new, + status_sanitizer = FormatVersion5StatusSanitizer.new + ) + super(log_sanitizer, metric_sanitizer, status_sanitizer) + end + + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[noop noop_pending corrective_change master_used]) + Util.copy_attributes(sanitized, raw, %w[noop noop_pending corrective_change master_used]) + end + + class FormatVersion5StatusSanitizer < FormatVersion4StatusSanitizer + def initialize(event_sanitizer = FormatVersion5EventSanitizer.new) + super(event_sanitizer) + end + + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[corrective_change]) + Util.copy_attributes(sanitized, raw, %w[corrective_change]) + end + + class FormatVersion5EventSanitizer < FormatVersion4EventSanitizer + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[corrective_change redacted]) + Util.copy_attributes(sanitized, raw, %w[corrective_change redacted]) + end + end + end + end + end diff --git a/spec/fixtures/reports/formats/06_failing.yaml b/spec/fixtures/reports/formats/06_failing.yaml new file mode 100644 index 000000000..2d4cb3e5a --- /dev/null +++ b/spec/fixtures/reports/formats/06_failing.yaml @@ -0,0 +1,361 @@ +--- !ruby/object:Puppet::Transaction::Report +metrics: + resources: !ruby/object:Puppet::Util::Metric + name: resources + label: Resources + values: + - - total + - Total + - 9 + - - skipped + - Skipped + - 0 + - - failed + - Failed + - 1 + - - failed_to_restart + - Failed to restart + - 0 + - - restarted + - Restarted + - 0 + - - changed + - Changed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - scheduled + - Scheduled + - 0 + - - corrective_change + - Corrective change + - 0 + time: !ruby/object:Puppet::Util::Metric + name: time + label: Time + values: + - - exec + - Exec + - 0.000517577 + - - notify + - Notify + - 0.000341475 + - - schedule + - Schedule + - 0.000293712 + - - filebucket + - Filebucket + - 4.6623e-05 + - - config_retrieval + - Config retrieval + - 0.136173907 + - - total + - Total + - 0.137373294 + changes: !ruby/object:Puppet::Util::Metric + name: changes + label: Changes + values: + - - total + - Total + - 1 + events: !ruby/object:Puppet::Util::Metric + name: events + label: Events + values: + - - total + - Total + - 2 + - - failure + - Failure + - 1 + - - success + - Success + - 1 +logs: +- !ruby/object:Puppet::Util::Log + level: :err + message: Could not find command '/usr/bin/thisdoesnotexist' + source: Puppet + tags: + - err + time: '2018-06-12T23:17:11.345405537+02:00' + file: + line: +- !ruby/object:Puppet::Util::Log + level: :err + message: 'change from notrun to 0 failed: Could not find command ''/usr/bin/thisdoesnotexist''' + source: "/Stage[main]/Main/Exec[/usr/bin/thisdoesnotexist]/returns" + tags: + - err + - exec + - class + time: '2018-06-12T23:17:11.345582063+02:00' + file: "/tmp/puppet/test.pp" + line: 2 +- !ruby/object:Puppet::Util::Log + level: :notice + message: hello world + source: Puppet + tags: + - notice + time: '2018-06-12T23:17:11.346050745+02:00' + file: + line: +- !ruby/object:Puppet::Util::Log + level: :notice + message: defined 'message' as 'hello world' + source: "/Stage[main]/Main/Notify[hello world]/message" + tags: + - notice + - notify + - class + time: '2018-06-12T23:17:11.346107414+02:00' + file: "/tmp/puppet/test.pp" + line: 4 +- !ruby/object:Puppet::Util::Log + level: :notice + message: Applied catalog in 0.02 seconds + source: Puppet + tags: + - notice + time: '2018-06-12T23:17:11.361657755+02:00' + file: + line: +resource_statuses: + Exec[/usr/bin/thisdoesnotexist]: !ruby/object:Puppet::Resource::Status + title: "/usr/bin/thisdoesnotexist" + file: "/tmp/puppet/test.pp" + line: 2 + resource: Exec[/usr/bin/thisdoesnotexist] + resource_type: Exec + containment_path: + - Stage[main] + - Main + - Exec[/usr/bin/thisdoesnotexist] + evaluation_time: 0.000517577 + tags: + - exec + - class + time: '2018-06-12T23:17:11.345153098+02:00' + failed: true + changed: false + out_of_sync: true + skipped: false + change_count: 0 + out_of_sync_count: 1 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: returns + previous_value: :notrun + desired_value: + - '0' + historical_value: + message: 'change from notrun to 0 failed: Could not find command ''/usr/bin/thisdoesnotexist''' + name: :executed_command + status: failure + time: 2018-06-12 23:17:11.345516498 +02:00 + redacted: + corrective_change: false + corrective_change: false + Notify[hello world]: !ruby/object:Puppet::Resource::Status + title: hello world + file: "/tmp/puppet/test.pp" + line: 4 + resource: Notify[hello world] + resource_type: Notify + containment_path: + - Stage[main] + - Main + - Notify[hello world] + evaluation_time: 0.000341475 + tags: + - notify + - class + time: '2018-06-12T23:17:11.345812992+02:00' + failed: false + changed: true + out_of_sync: true + skipped: false + change_count: 1 + out_of_sync_count: 1 + events: + - !ruby/object:Puppet::Transaction::Event + audited: false + property: message + previous_value: :absent + desired_value: hello world + historical_value: + message: defined 'message' as 'hello world' + name: :message_changed + status: success + time: 2018-06-12 23:17:11.346006481 +02:00 + redacted: + corrective_change: false + corrective_change: false + Schedule[puppet]: !ruby/object:Puppet::Resource::Status + title: puppet + file: + line: + resource: Schedule[puppet] + resource_type: Schedule + containment_path: + - Schedule[puppet] + evaluation_time: 6.0116e-05 + tags: + - schedule + - puppet + time: '2018-06-12T23:17:11.346551592+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[hourly]: !ruby/object:Puppet::Resource::Status + title: hourly + file: + line: + resource: Schedule[hourly] + resource_type: Schedule + containment_path: + - Schedule[hourly] + evaluation_time: 6.2587e-05 + tags: + - schedule + - hourly + time: '2018-06-12T23:17:11.346681112+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[daily]: !ruby/object:Puppet::Resource::Status + title: daily + file: + line: + resource: Schedule[daily] + resource_type: Schedule + containment_path: + - Schedule[daily] + evaluation_time: 5.0456e-05 + tags: + - schedule + - daily + time: '2018-06-12T23:17:11.346810263+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[weekly]: !ruby/object:Puppet::Resource::Status + title: weekly + file: + line: + resource: Schedule[weekly] + resource_type: Schedule + containment_path: + - Schedule[weekly] + evaluation_time: 5.5423e-05 + tags: + - schedule + - weekly + time: '2018-06-12T23:17:11.346922374+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[monthly]: !ruby/object:Puppet::Resource::Status + title: monthly + file: + line: + resource: Schedule[monthly] + resource_type: Schedule + containment_path: + - Schedule[monthly] + evaluation_time: 3.5182e-05 + tags: + - schedule + - monthly + time: '2018-06-12T23:17:11.347041081+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[never]: !ruby/object:Puppet::Resource::Status + title: never + file: + line: + resource: Schedule[never] + resource_type: Schedule + containment_path: + - Schedule[never] + evaluation_time: 2.9948e-05 + tags: + - schedule + - never + time: '2018-06-12T23:17:11.347141060+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Filebucket[puppet]: !ruby/object:Puppet::Resource::Status + title: puppet + file: + line: + resource: Filebucket[puppet] + resource_type: Filebucket + containment_path: + - Filebucket[puppet] + evaluation_time: 4.6623e-05 + tags: + - filebucket + - puppet + time: '2018-06-12T23:17:11.347242685+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false +host: report-test.example.com +time: 2018-06-12 23:17:11.338306228 +02:00 +kind: apply +report_format: 6 +puppet_version: 4.10.11 +configuration_version: 1528838231 +transaction_uuid: 2374a3c0-7426-474e-a2d4-cd10ab2a3834 +code_id: +catalog_uuid: e10613b7-eb6e-4532-929f-9662308ff418 +cached_catalog_status: not_used +master_used: +environment: production +status: failed +noop: false +noop_pending: false +corrective_change: false +transaction_completed: true diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index f88490178..d2668236b 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -433,5 +433,27 @@ end end + describe 'a format version 6 (puppet 4.6.0-4.10.x) report' do + let(:report_file) { '06_failing.yaml' } + + it 'should produce a hash of the report' do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid catalog_uuid cached_catalog_status noop noop_pending corrective_change master_used} + hash['report_format'].should == 6 + hash['host'].should == 'report-test.example.com' + hash['time'].should == Time.parse('2018-06-12 23:17:11.338306228 +02:00') + hash['noop'].should == false + hash['noop_pending'].should == false + hash['corrective_change'].should == false + hash['master_used'].should == nil + resource_status = hash['resource_statuses']['Notify[hello world]'] + resource_status['corrective_change'].should == false + event = resource_status['events'].first + event['audited'].should == false + event['corrective_change'].should == false + end + end + end end From 2dee94cf0a7db93b69e451fd08ecebeb9f2c0f5f Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Thu, 14 Jun 2018 02:28:50 +0200 Subject: [PATCH 09/17] Add support for report format 7 This format removes the field kind from the report. Since this is heavily used we set it and remove the old fix where sanitation was bypassed. Also the field master_used does not appear now for apply runs. --- app/models/report.rb | 7 - lib/puppet/report_sanitizer.rb | 16 +- spec/fixtures/reports/formats/07_failing.yaml | 350 ++++++++++++++++++ spec/lib/puppet/report_sanitizer_spec.rb | 13 + 4 files changed, 378 insertions(+), 8 deletions(-) create mode 100644 spec/fixtures/reports/formats/07_failing.yaml diff --git a/app/models/report.rb b/app/models/report.rb index 1894395f4..efcc3d54a 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -186,18 +186,11 @@ def munge add_status_to_resource_status add_missing_metrics recalculate_report_status - fix_kind_for_puppet5 self end private - # Report format 7 from Puppet 5 is missing "kind" leading to - # "Validation failed: Kind can't be blank" - def fix_kind_for_puppet5 - self.kind = 'apply' if self.kind.blank? - end - # Report format 2 knows nothing about pending status def recalculate_report_status self.status = 'pending' if resource_statuses.any? {|rs| rs.status == 'pending' } && diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index bb88e16b4..ade27eef0 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -19,8 +19,10 @@ def sanitize(raw) format4sanitizer.sanitize(raw) when 5 format5sanitizer.sanitize(raw) - else + when 6 format6sanitizer.sanitize(raw) + else + format7sanitizer.sanitize(raw) end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) @@ -58,6 +60,10 @@ def format5sanitizer() def format6sanitizer() @format6sanitizer ||= ReportSanitizer::FormatVersion6.new end + + def format7sanitizer() + @format7sanitizer ||= ReportSanitizer::FormatVersion7.new + end end module Util @@ -351,4 +357,12 @@ def sanitize(raw) end end + class FormatVersion7 < FormatVersion6 + def sanitize(raw) + raw['kind'] = 'apply' + raw['master_used'] ||= nil + super + end + end + end diff --git a/spec/fixtures/reports/formats/07_failing.yaml b/spec/fixtures/reports/formats/07_failing.yaml new file mode 100644 index 000000000..cab60c5b3 --- /dev/null +++ b/spec/fixtures/reports/formats/07_failing.yaml @@ -0,0 +1,350 @@ +--- !ruby/object:Puppet::Transaction::Report +host: report-test.example.com +time: '2018-06-12T23:28:04.451061885+02:00' +configuration_version: 1528838884 +transaction_uuid: 47d84414-28a7-4421-b885-bde4a01c77d3 +report_format: 7 +puppet_version: 5.0.0 +status: failed +noop: false +noop_pending: false +environment: production +logs: +- level: err + message: Could not find command '/usr/bin/thisdoesnotexist' + source: Puppet + tags: + - err + time: '2018-06-12T23:28:04.459959267+02:00' + file: + line: +- level: err + message: 'change from ''notrun'' to [''0''] failed: Could not find command ''/usr/bin/thisdoesnotexist''' + source: "/Stage[main]/Main/Exec[/usr/bin/thisdoesnotexist]/returns" + tags: + - err + - exec + - class + time: '2018-06-12T23:28:04.460976182+02:00' + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 2 +- level: notice + message: hello world + source: Puppet + tags: + - notice + time: '2018-06-12T23:28:04.461342764+02:00' + file: + line: +- level: notice + message: defined 'message' as 'hello world' + source: "/Stage[main]/Main/Notify[hello world]/message" + tags: + - notice + - notify + - class + time: '2018-06-12T23:28:04.461696600+02:00' + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 4 +- level: notice + message: Applied catalog in 0.03 seconds + source: Puppet + tags: + - notice + time: '2018-06-12T23:28:04.481229577+02:00' + file: + line: +metrics: + resources: + name: resources + label: Resources + values: + - - total + - Total + - 9 + - - skipped + - Skipped + - 0 + - - failed + - Failed + - 1 + - - failed_to_restart + - Failed to restart + - 0 + - - restarted + - Restarted + - 0 + - - changed + - Changed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - scheduled + - Scheduled + - 0 + - - corrective_change + - Corrective change + - 1 + time: + name: time + label: Time + values: + - - exec + - Exec + - 0.00155394 + - - notify + - Notify + - 0.000614684 + - - schedule + - Schedule + - 0.000269875 + - - filebucket + - Filebucket + - 5.1092e-05 + - - config_retrieval + - Config retrieval + - 0.091083196 + - - total + - Total + - 0.093572787 + changes: + name: changes + label: Changes + values: + - - total + - Total + - 1 + events: + name: events + label: Events + values: + - - total + - Total + - 2 + - - failure + - Failure + - 1 + - - success + - Success + - 1 +resource_statuses: + Exec[/usr/bin/thisdoesnotexist]: + title: "/usr/bin/thisdoesnotexist" + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 2 + resource: Exec[/usr/bin/thisdoesnotexist] + resource_type: Exec + containment_path: + - Stage[main] + - Main + - Exec[/usr/bin/thisdoesnotexist] + evaluation_time: 0.00155394 + tags: + - exec + - class + time: '2018-06-12T23:28:04.459487618+02:00' + failed: true + changed: false + out_of_sync: true + skipped: false + change_count: 0 + out_of_sync_count: 1 + events: + - audited: false + property: returns + previous_value: notrun + desired_value: + - '0' + historical_value: + message: 'change from ''notrun'' to [''0''] failed: Could not find command ''/usr/bin/thisdoesnotexist''' + name: executed_command + status: failure + time: '2018-06-12T23:28:04.460057602+02:00' + redacted: + corrective_change: true + corrective_change: true + Notify[hello world]: + title: hello world + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 4 + resource: Notify[hello world] + resource_type: Notify + containment_path: + - Stage[main] + - Main + - Notify[hello world] + evaluation_time: 0.000614684 + tags: + - notify + - class + time: '2018-06-12T23:28:04.461169639+02:00' + failed: false + changed: true + out_of_sync: true + skipped: false + change_count: 1 + out_of_sync_count: 1 + events: + - audited: false + property: message + previous_value: absent + desired_value: hello world + historical_value: + message: defined 'message' as 'hello world' + name: message_changed + status: success + time: '2018-06-12T23:28:04.461309649+02:00' + redacted: + corrective_change: false + corrective_change: false + Schedule[puppet]: + title: puppet + file: + line: + resource: Schedule[puppet] + resource_type: Schedule + containment_path: + - Schedule[puppet] + evaluation_time: 6.6871e-05 + tags: + - schedule + - puppet + time: '2018-06-12T23:28:04.462135498+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[hourly]: + title: hourly + file: + line: + resource: Schedule[hourly] + resource_type: Schedule + containment_path: + - Schedule[hourly] + evaluation_time: 3.6614e-05 + tags: + - schedule + - hourly + time: '2018-06-12T23:28:04.462265658+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[daily]: + title: daily + file: + line: + resource: Schedule[daily] + resource_type: Schedule + containment_path: + - Schedule[daily] + evaluation_time: 4.5934e-05 + tags: + - schedule + - daily + time: '2018-06-12T23:28:04.462368566+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[weekly]: + title: weekly + file: + line: + resource: Schedule[weekly] + resource_type: Schedule + containment_path: + - Schedule[weekly] + evaluation_time: 3.9213e-05 + tags: + - schedule + - weekly + time: '2018-06-12T23:28:04.462479254+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[monthly]: + title: monthly + file: + line: + resource: Schedule[monthly] + resource_type: Schedule + containment_path: + - Schedule[monthly] + evaluation_time: 3.942e-05 + tags: + - schedule + - monthly + time: '2018-06-12T23:28:04.462583464+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[never]: + title: never + file: + line: + resource: Schedule[never] + resource_type: Schedule + containment_path: + - Schedule[never] + evaluation_time: 4.1823e-05 + tags: + - schedule + - never + time: '2018-06-12T23:28:04.462685982+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Filebucket[puppet]: + title: puppet + file: + line: + resource: Filebucket[puppet] + resource_type: Filebucket + containment_path: + - Filebucket[puppet] + evaluation_time: 5.1092e-05 + tags: + - filebucket + - puppet + time: '2018-06-12T23:28:04.462794279+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false +corrective_change: true +catalog_uuid: 392570aa-d507-4a7e-aabe-0ec4e76f1f45 +cached_catalog_status: not_used diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index d2668236b..c01e2bf6a 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -455,5 +455,18 @@ end end + describe 'a format version 7 (puppet 5.0.0-5.3.x) report' do + let(:report_file) { '07_failing.yaml' } + + it 'should produce a hash of the report' do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid catalog_uuid cached_catalog_status noop noop_pending corrective_change master_used} + hash['report_format'].should == 7 + hash['host'].should == 'report-test.example.com' + hash['kind'].should == 'apply' + end + end + end end From 9fb95cd1447522561ed859d732df7076f2850579 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Thu, 14 Jun 2018 02:36:09 +0200 Subject: [PATCH 10/17] Change example times for format version reports This is a simple change to some of the format report timestamps so we can load them all for the testing of the parsing etc. --- spec/fixtures/reports/formats/03_failing.yaml | 2 +- spec/fixtures/reports/formats/04_failing.yaml | 2 +- spec/lib/puppet/report_sanitizer_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/fixtures/reports/formats/03_failing.yaml b/spec/fixtures/reports/formats/03_failing.yaml index 82361e530..a294582b5 100644 --- a/spec/fixtures/reports/formats/03_failing.yaml +++ b/spec/fixtures/reports/formats/03_failing.yaml @@ -1,6 +1,6 @@ --- !ruby/object:Puppet::Transaction::Report host: localhost - time: 2010-07-22 12:19:47.204207 -07:00 + time: 2010-07-22 13:19:47.204207 -07:00 logs: [] metrics: time: !ruby/object:Puppet::Util::Metric diff --git a/spec/fixtures/reports/formats/04_failing.yaml b/spec/fixtures/reports/formats/04_failing.yaml index 178d7f544..bfc29c5f9 100644 --- a/spec/fixtures/reports/formats/04_failing.yaml +++ b/spec/fixtures/reports/formats/04_failing.yaml @@ -1,6 +1,6 @@ --- !ruby/object:Puppet::Transaction::Report host: localhost - time: 2010-07-22 12:19:47.204207 -07:00 + time: 2010-07-22 14:19:47.204207 -07:00 logs: [] metrics: time: !ruby/object:Puppet::Util::Metric diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index c01e2bf6a..a7a15b1ae 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -384,7 +384,7 @@ hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment} hash["report_format"].should == 3 hash["host"].should == "localhost" - hash["time"].should == Time.parse("2010-07-22 12:19:47.204207 -07:00") + hash["time"].should == Time.parse("2010-07-22 13:19:47.204207 -07:00") hash["environment"].should == "production" end end @@ -398,7 +398,7 @@ hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid} hash["report_format"].should == 4 hash["host"].should == "localhost" - hash["time"].should == Time.parse("2010-07-22 12:19:47.204207 -07:00") + hash["time"].should == Time.parse("2010-07-22 14:19:47.204207 -07:00") hash["environment"].should == "production" hash["transaction_uuid"].should == "b2b7567c-696a-4250-8d74-e3c5030e1263" end From 06a507163f910c0ff84d6b8e5c1c106101fdab0a Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Thu, 14 Jun 2018 18:21:43 +0200 Subject: [PATCH 11/17] Add support for report format 8 This format update simply adds the transaction_completed field to the report model. --- .../20180614161626_add_report_format8.rb | 5 + db/schema.rb | 3 +- lib/puppet/report_sanitizer.rb | 16 +- spec/fixtures/reports/formats/08_failing.yaml | 351 ++++++++++++++++++ spec/lib/puppet/report_sanitizer_spec.rb | 13 + 5 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20180614161626_add_report_format8.rb create mode 100644 spec/fixtures/reports/formats/08_failing.yaml diff --git a/db/migrate/20180614161626_add_report_format8.rb b/db/migrate/20180614161626_add_report_format8.rb new file mode 100644 index 000000000..024cebb15 --- /dev/null +++ b/db/migrate/20180614161626_add_report_format8.rb @@ -0,0 +1,5 @@ +class AddReportFormat8 < ActiveRecord::Migration[5.2] + def change + add_column :reports, :transaction_completed, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index fc71efbea..ea2281ad5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_06_13_224704) do +ActiveRecord::Schema.define(version: 2018_06_14_161626) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -163,6 +163,7 @@ t.boolean "noop_pending" t.boolean "corrective_change" t.string "master_used" + t.boolean "transaction_completed" t.index ["node_id"], name: "index_reports_on_node_id" t.index ["time", "node_id", "status"], name: "index_reports_on_time_and_node_id_and_status" end diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index ade27eef0..debca6efa 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -21,8 +21,10 @@ def sanitize(raw) format5sanitizer.sanitize(raw) when 6 format6sanitizer.sanitize(raw) - else + when 7 format7sanitizer.sanitize(raw) + else + format8sanitizer.sanitize(raw) end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) @@ -64,6 +66,10 @@ def format6sanitizer() def format7sanitizer() @format7sanitizer ||= ReportSanitizer::FormatVersion7.new end + + def format8sanitizer() + @format8sanitizer ||= ReportSanitizer::FormatVersion8.new + end end module Util @@ -365,4 +371,12 @@ def sanitize(raw) end end + class FormatVersion8 < FormatVersion7 + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[transaction_completed]) + Util.copy_attributes(sanitized, raw, %w[transaction_completed]) + end + end + end diff --git a/spec/fixtures/reports/formats/08_failing.yaml b/spec/fixtures/reports/formats/08_failing.yaml new file mode 100644 index 000000000..c71e40049 --- /dev/null +++ b/spec/fixtures/reports/formats/08_failing.yaml @@ -0,0 +1,351 @@ +--- !ruby/object:Puppet::Transaction::Report +host: report-test.example.com +time: '2018-06-12T23:30:03.087762562+02:00' +configuration_version: 1528839003 +transaction_uuid: 5338a066-4f08-49e0-b747-bd4245b80898 +report_format: 8 +puppet_version: 5.4.0 +status: failed +transaction_completed: true +noop: false +noop_pending: false +environment: production +logs: +- level: err + message: Could not find command '/usr/bin/thisdoesnotexist' + source: Puppet + tags: + - err + time: '2018-06-12T23:30:03.095655048+02:00' + file: + line: +- level: err + message: 'change from ''notrun'' to [''0''] failed: Could not find command ''/usr/bin/thisdoesnotexist''' + source: "/Stage[main]/Main/Exec[/usr/bin/thisdoesnotexist]/returns" + tags: + - err + - exec + - class + time: '2018-06-12T23:30:03.096930899+02:00' + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 2 +- level: notice + message: hello world + source: Puppet + tags: + - notice + time: '2018-06-12T23:30:03.097659564+02:00' + file: + line: +- level: notice + message: defined 'message' as 'hello world' + source: "/Stage[main]/Main/Notify[hello world]/message" + tags: + - notice + - notify + - class + time: '2018-06-12T23:30:03.098071425+02:00' + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 4 +- level: notice + message: Applied catalog in 0.02 seconds + source: Puppet + tags: + - notice + time: '2018-06-12T23:30:03.107773307+02:00' + file: + line: +metrics: + resources: + name: resources + label: Resources + values: + - - total + - Total + - 9 + - - skipped + - Skipped + - 0 + - - failed + - Failed + - 1 + - - failed_to_restart + - Failed to restart + - 0 + - - restarted + - Restarted + - 0 + - - changed + - Changed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - scheduled + - Scheduled + - 0 + - - corrective_change + - Corrective change + - 0 + time: + name: time + label: Time + values: + - - exec + - Exec + - 0.001959372 + - - notify + - Notify + - 0.000765967 + - - schedule + - Schedule + - 0.00027547 + - - filebucket + - Filebucket + - 3.9389e-05 + - - config_retrieval + - Config retrieval + - 0.100191276 + - - total + - Total + - 0.10323147399999999 + changes: + name: changes + label: Changes + values: + - - total + - Total + - 1 + events: + name: events + label: Events + values: + - - total + - Total + - 2 + - - failure + - Failure + - 1 + - - success + - Success + - 1 +resource_statuses: + Exec[/usr/bin/thisdoesnotexist]: + title: "/usr/bin/thisdoesnotexist" + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 2 + resource: Exec[/usr/bin/thisdoesnotexist] + resource_type: Exec + containment_path: + - Stage[main] + - Main + - Exec[/usr/bin/thisdoesnotexist] + evaluation_time: 0.001959372 + tags: + - exec + - class + time: '2018-06-12T23:30:03.095167960+02:00' + failed: true + changed: false + out_of_sync: true + skipped: false + change_count: 0 + out_of_sync_count: 1 + events: + - audited: false + property: returns + previous_value: notrun + desired_value: + - '0' + historical_value: + message: 'change from ''notrun'' to [''0''] failed: Could not find command ''/usr/bin/thisdoesnotexist''' + name: executed_command + status: failure + time: '2018-06-12T23:30:03.095788580+02:00' + redacted: + corrective_change: false + corrective_change: false + Notify[hello world]: + title: hello world + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 4 + resource: Notify[hello world] + resource_type: Notify + containment_path: + - Stage[main] + - Main + - Notify[hello world] + evaluation_time: 0.000765967 + tags: + - notify + - class + time: '2018-06-12T23:30:03.097381928+02:00' + failed: false + changed: true + out_of_sync: true + skipped: false + change_count: 1 + out_of_sync_count: 1 + events: + - audited: false + property: message + previous_value: absent + desired_value: hello world + historical_value: + message: defined 'message' as 'hello world' + name: message_changed + status: success + time: '2018-06-12T23:30:03.097619296+02:00' + redacted: + corrective_change: false + corrective_change: false + Schedule[puppet]: + title: puppet + file: + line: + resource: Schedule[puppet] + resource_type: Schedule + containment_path: + - Schedule[puppet] + evaluation_time: 6.0737e-05 + tags: + - schedule + - puppet + time: '2018-06-12T23:30:03.098449273+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[hourly]: + title: hourly + file: + line: + resource: Schedule[hourly] + resource_type: Schedule + containment_path: + - Schedule[hourly] + evaluation_time: 4.5278e-05 + tags: + - schedule + - hourly + time: '2018-06-12T23:30:03.098573639+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[daily]: + title: daily + file: + line: + resource: Schedule[daily] + resource_type: Schedule + containment_path: + - Schedule[daily] + evaluation_time: 4.7564e-05 + tags: + - schedule + - daily + time: '2018-06-12T23:30:03.098679267+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[weekly]: + title: weekly + file: + line: + resource: Schedule[weekly] + resource_type: Schedule + containment_path: + - Schedule[weekly] + evaluation_time: 3.5012e-05 + tags: + - schedule + - weekly + time: '2018-06-12T23:30:03.098784860+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[monthly]: + title: monthly + file: + line: + resource: Schedule[monthly] + resource_type: Schedule + containment_path: + - Schedule[monthly] + evaluation_time: 3.0778e-05 + tags: + - schedule + - monthly + time: '2018-06-12T23:30:03.098907615+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[never]: + title: never + file: + line: + resource: Schedule[never] + resource_type: Schedule + containment_path: + - Schedule[never] + evaluation_time: 5.6101e-05 + tags: + - schedule + - never + time: '2018-06-12T23:30:03.098995239+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Filebucket[puppet]: + title: puppet + file: + line: + resource: Filebucket[puppet] + resource_type: Filebucket + containment_path: + - Filebucket[puppet] + evaluation_time: 3.9389e-05 + tags: + - filebucket + - puppet + time: '2018-06-12T23:30:03.099118894+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false +corrective_change: false +catalog_uuid: cf6ff162-4ece-4fb6-bd4d-2923ddb563fa +cached_catalog_status: not_used diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index a7a15b1ae..f0e06d5bd 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -468,5 +468,18 @@ end end + describe 'a format version 8 (puppet 5.4.0-5.4.x) report' do + let(:report_file) { '08_failing.yaml' } + + it 'should produce a hash of the report' do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid catalog_uuid cached_catalog_status noop noop_pending corrective_change master_used transaction_completed} + hash['report_format'].should == 8 + hash['transaction_completed'].should == true + end + end + + end end From 83eacc9a9e263fc85f68040ecd34215be6b59a55 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Thu, 14 Jun 2018 23:07:28 +0200 Subject: [PATCH 12/17] Add support for report format 9 This adds provider_used to the resource_status model --- .../20180614210435_add_report_format9.rb | 5 + db/schema.rb | 3 +- lib/puppet/report_sanitizer.rb | 34 +- spec/fixtures/reports/formats/09_failing.yaml | 366 ++++++++++++++++++ spec/lib/puppet/report_sanitizer_spec.rb | 14 + 5 files changed, 416 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20180614210435_add_report_format9.rb create mode 100644 spec/fixtures/reports/formats/09_failing.yaml diff --git a/db/migrate/20180614210435_add_report_format9.rb b/db/migrate/20180614210435_add_report_format9.rb new file mode 100644 index 000000000..95f8e0524 --- /dev/null +++ b/db/migrate/20180614210435_add_report_format9.rb @@ -0,0 +1,5 @@ +class AddReportFormat9 < ActiveRecord::Migration[5.2] + def change + add_column :resource_statuses, :provider_used, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index ea2281ad5..4d71079db 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_06_14_161626) do +ActiveRecord::Schema.define(version: 2018_06_14_210435) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -200,6 +200,7 @@ t.string "status" t.text "containment_path" t.boolean "corrective_change" + t.string "provider_used" t.index ["report_id"], name: "index_resource_statuses_on_report_id" end diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index debca6efa..6854b194b 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -23,8 +23,10 @@ def sanitize(raw) format6sanitizer.sanitize(raw) when 7 format7sanitizer.sanitize(raw) - else + when 8 format8sanitizer.sanitize(raw) + else + format9sanitizer.sanitize(raw) end when raw.include?('resource_statuses') format1sanitizer.sanitize(raw) @@ -70,6 +72,10 @@ def format7sanitizer() def format8sanitizer() @format8sanitizer ||= ReportSanitizer::FormatVersion8.new end + + def format9sanitizer() + @format9sanitizer ||= ReportSanitizer::FormatVersion9.new + end end module Util @@ -331,7 +337,7 @@ class FormatVersion6 < FormatVersion5 def initialize( log_sanitizer = FormatVersion4LogSanitizer.new, metric_sanitizer = MetricSanitizer.new, - status_sanitizer = FormatVersion5StatusSanitizer.new + status_sanitizer = FormatVersion6StatusSanitizer.new ) super(log_sanitizer, metric_sanitizer, status_sanitizer) end @@ -342,8 +348,8 @@ def sanitize(raw) Util.copy_attributes(sanitized, raw, %w[noop noop_pending corrective_change master_used]) end - class FormatVersion5StatusSanitizer < FormatVersion4StatusSanitizer - def initialize(event_sanitizer = FormatVersion5EventSanitizer.new) + class FormatVersion6StatusSanitizer < FormatVersion4StatusSanitizer + def initialize(event_sanitizer = FormatVersion6EventSanitizer.new) super(event_sanitizer) end @@ -353,7 +359,7 @@ def sanitize(raw) Util.copy_attributes(sanitized, raw, %w[corrective_change]) end - class FormatVersion5EventSanitizer < FormatVersion4EventSanitizer + class FormatVersion6EventSanitizer < FormatVersion4EventSanitizer def sanitize(raw) sanitized = super Util.verify_attributes(raw, %w[corrective_change redacted]) @@ -379,4 +385,22 @@ def sanitize(raw) end end + class FormatVersion9 < FormatVersion8 + def initialize( + log_sanitizer = FormatVersion4LogSanitizer.new, + metric_sanitizer = MetricSanitizer.new, + status_sanitizer = FormatVersion9StatusSanitizer.new + ) + super(log_sanitizer, metric_sanitizer, status_sanitizer) + end + + class FormatVersion9StatusSanitizer < FormatVersion6StatusSanitizer + def sanitize(raw) + sanitized = super + Util.verify_attributes(raw, %w[provider_used]) + Util.copy_attributes(sanitized, raw, %w[provider_used]) + end + end + end + end diff --git a/spec/fixtures/reports/formats/09_failing.yaml b/spec/fixtures/reports/formats/09_failing.yaml new file mode 100644 index 000000000..98149913a --- /dev/null +++ b/spec/fixtures/reports/formats/09_failing.yaml @@ -0,0 +1,366 @@ +--- !ruby/object:Puppet::Transaction::Report +host: report-test.example.com +time: '2018-06-12T23:31:23.617459229+02:00' +configuration_version: 1528839083 +transaction_uuid: 7f1aae13-2e4b-40a8-8946-8dfa138efccf +report_format: 9 +puppet_version: 5.5.0 +status: failed +transaction_completed: true +noop: false +noop_pending: false +environment: production +logs: +- level: err + message: Could not find command '/usr/bin/thisdoesnotexist' + source: Puppet + tags: + - err + time: '2018-06-12T23:31:23.624318609+02:00' + file: + line: +- level: err + message: 'change from ''notrun'' to [''0''] failed: Could not find command ''/usr/bin/thisdoesnotexist''' + source: "/Stage[main]/Main/Exec[/usr/bin/thisdoesnotexist]/returns" + tags: + - err + - exec + - class + time: '2018-06-12T23:31:23.625230131+02:00' + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 2 +- level: notice + message: hello world + source: Puppet + tags: + - notice + time: '2018-06-12T23:31:23.625552739+02:00' + file: + line: +- level: notice + message: defined 'message' as 'hello world' + source: "/Stage[main]/Main/Notify[hello world]/message" + tags: + - notice + - notify + - class + time: '2018-06-12T23:31:23.625881970+02:00' + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 4 +- level: notice + message: Applied catalog in 0.02 seconds + source: Puppet + tags: + - notice + time: '2018-06-12T23:31:23.636582286+02:00' + file: + line: +metrics: + resources: + name: resources + label: Resources + values: + - - total + - Total + - 9 + - - skipped + - Skipped + - 0 + - - failed + - Failed + - 1 + - - failed_to_restart + - Failed to restart + - 0 + - - restarted + - Restarted + - 0 + - - changed + - Changed + - 1 + - - out_of_sync + - Out of sync + - 2 + - - scheduled + - Scheduled + - 0 + - - corrective_change + - Corrective change + - 0 + time: + name: time + label: Time + values: + - - exec + - Exec + - 0.001325921 + - - notify + - Notify + - 0.000548334 + - - schedule + - Schedule + - 0.000248223 + - - filebucket + - Filebucket + - 5.3079e-05 + - - config_retrieval + - Config retrieval + - 0.088663979 + - - transaction_evaluation + - Transaction evaluation + - 0.005367110000406683 + - - catalog_application + - Catalog application + - 0.01686296299976675 + - - total + - Total + - 0.11306960900017343 + changes: + name: changes + label: Changes + values: + - - total + - Total + - 1 + events: + name: events + label: Events + values: + - - total + - Total + - 2 + - - failure + - Failure + - 1 + - - success + - Success + - 1 +resource_statuses: + Exec[/usr/bin/thisdoesnotexist]: + title: "/usr/bin/thisdoesnotexist" + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 2 + resource: Exec[/usr/bin/thisdoesnotexist] + resource_type: Exec + provider_used: posix + containment_path: + - Stage[main] + - Main + - Exec[/usr/bin/thisdoesnotexist] + evaluation_time: 0.001325921 + tags: + - exec + - class + time: '2018-06-12T23:31:23.623974516+02:00' + failed: true + changed: false + out_of_sync: true + skipped: false + change_count: 0 + out_of_sync_count: 1 + events: + - audited: false + property: returns + previous_value: notrun + desired_value: + - '0' + historical_value: + message: 'change from ''notrun'' to [''0''] failed: Could not find command ''/usr/bin/thisdoesnotexist''' + name: executed_command + status: failure + time: '2018-06-12T23:31:23.624410261+02:00' + redacted: + corrective_change: false + corrective_change: false + Notify[hello world]: + title: hello world + file: "/home/azuber/tmp/puppet-report-generator/test.pp" + line: 4 + resource: Notify[hello world] + resource_type: Notify + provider_used: + containment_path: + - Stage[main] + - Main + - Notify[hello world] + evaluation_time: 0.000548334 + tags: + - notify + - class + time: '2018-06-12T23:31:23.625402508+02:00' + failed: false + changed: true + out_of_sync: true + skipped: false + change_count: 1 + out_of_sync_count: 1 + events: + - audited: false + property: message + previous_value: absent + desired_value: hello world + historical_value: + message: defined 'message' as 'hello world' + name: message_changed + status: success + time: '2018-06-12T23:31:23.625524733+02:00' + redacted: + corrective_change: false + corrective_change: false + Schedule[puppet]: + title: puppet + file: + line: + resource: Schedule[puppet] + resource_type: Schedule + provider_used: + containment_path: + - Schedule[puppet] + evaluation_time: 5.964e-05 + tags: + - schedule + - puppet + time: '2018-06-12T23:31:23.626201047+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[hourly]: + title: hourly + file: + line: + resource: Schedule[hourly] + resource_type: Schedule + provider_used: + containment_path: + - Schedule[hourly] + evaluation_time: 3.846e-05 + tags: + - schedule + - hourly + time: '2018-06-12T23:31:23.626310018+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[daily]: + title: daily + file: + line: + resource: Schedule[daily] + resource_type: Schedule + provider_used: + containment_path: + - Schedule[daily] + evaluation_time: 3.9011e-05 + tags: + - schedule + - daily + time: '2018-06-12T23:31:23.626403824+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[weekly]: + title: weekly + file: + line: + resource: Schedule[weekly] + resource_type: Schedule + provider_used: + containment_path: + - Schedule[weekly] + evaluation_time: 3.774e-05 + tags: + - schedule + - weekly + time: '2018-06-12T23:31:23.626502575+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[monthly]: + title: monthly + file: + line: + resource: Schedule[monthly] + resource_type: Schedule + provider_used: + containment_path: + - Schedule[monthly] + evaluation_time: 3.1703e-05 + tags: + - schedule + - monthly + time: '2018-06-12T23:31:23.626592123+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Schedule[never]: + title: never + file: + line: + resource: Schedule[never] + resource_type: Schedule + provider_used: + containment_path: + - Schedule[never] + evaluation_time: 4.1669e-05 + tags: + - schedule + - never + time: '2018-06-12T23:31:23.626677117+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false + Filebucket[puppet]: + title: puppet + file: + line: + resource: Filebucket[puppet] + resource_type: Filebucket + provider_used: + containment_path: + - Filebucket[puppet] + evaluation_time: 5.3079e-05 + tags: + - filebucket + - puppet + time: '2018-06-12T23:31:23.626774252+02:00' + failed: false + changed: false + out_of_sync: false + skipped: false + change_count: 0 + out_of_sync_count: 0 + events: [] + corrective_change: false +corrective_change: false +catalog_uuid: 7a50702d-3c15-443a-82c0-e5466812c940 +cached_catalog_status: not_used diff --git a/spec/lib/puppet/report_sanitizer_spec.rb b/spec/lib/puppet/report_sanitizer_spec.rb index f0e06d5bd..823b1ffb0 100644 --- a/spec/lib/puppet/report_sanitizer_spec.rb +++ b/spec/lib/puppet/report_sanitizer_spec.rb @@ -480,6 +480,20 @@ end end + describe 'a format version 9 (puppet 5.5.0-latest) report' do + let(:report_file) { '09_failing.yaml' } + + it 'should produce a hash of the report' do + hash = ReportSanitizer.sanitize(raw_report) + hash.should be_a(Hash) + hash.keys.should =~ %w{host time logs metrics resource_statuses kind configuration_version puppet_version report_format status environment transaction_uuid catalog_uuid cached_catalog_status noop noop_pending corrective_change master_used transaction_completed} + hash['report_format'].should == 9 + hash['host'].should == 'report-test.example.com' + resource_status = hash['resource_statuses']['Exec[/usr/bin/thisdoesnotexist]'] + resource_status['provider_used'].should == 'posix' + end + end + end end From d015b6a8779bd5bb32207d6ada84a6596226135f Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Mon, 18 Jun 2018 14:01:53 +0200 Subject: [PATCH 13/17] ensure master_use is present in the right place --- lib/puppet/report_sanitizer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index 6854b194b..8f07d2097 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -344,6 +344,7 @@ def initialize( def sanitize(raw) sanitized = super + raw['master_used'] ||= nil Util.verify_attributes(raw, %w[noop noop_pending corrective_change master_used]) Util.copy_attributes(sanitized, raw, %w[noop noop_pending corrective_change master_used]) end @@ -372,7 +373,6 @@ def sanitize(raw) class FormatVersion7 < FormatVersion6 def sanitize(raw) raw['kind'] = 'apply' - raw['master_used'] ||= nil super end end From a33485347f9dfe1098fd3c71d61d66ab2efdb269 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Mon, 18 Jun 2018 16:00:08 +0200 Subject: [PATCH 14/17] improve sanitizer error messages --- lib/puppet/report_sanitizer.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index 8f07d2097..8a582572b 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -25,7 +25,12 @@ def sanitize(raw) format7sanitizer.sanitize(raw) when 8 format8sanitizer.sanitize(raw) + when 9 + format9sanitizer.sanitize(raw) else + msg = "Sanitizer: Unknown report format #{raw['report_format']}, " + + "using format 9 and hoping for the best" + Rails.logger.warn(msg) format9sanitizer.sanitize(raw) end when raw.include?('resource_statuses') @@ -33,6 +38,14 @@ def sanitize(raw) else format0sanitizer.sanitize(raw) end + rescue => e + host = raw['host'] || 'unknown_host' + format_version = raw['report_format'] || 'unknown_version' + puppet_version = raw['puppet_version'] || 'unknown_version' + msg = "Sanitizer error, #{host}, report format #{format_version}, " + + "puppet version #{puppet_version}: #{e.message}" + Rails.logger.error(msg) + raise e, msg, e.backtrace end private @@ -82,7 +95,7 @@ module Util class << self def verify_attributes(raw, names) names.each do |n| - raise ArgumentError, "required attribute not present: #{n}" unless raw.include?(n) + raise StandardError, "required attribute not present: #{n}" unless raw.include?(n) end end From 9fe49a306cd8ccef9dcb444272bff1632deca5bb Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Mon, 18 Jun 2018 18:01:47 +0200 Subject: [PATCH 15/17] make sure the optional new parameters have defaults --- lib/puppet/report_sanitizer.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index 8a582572b..8d8249224 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -341,6 +341,7 @@ def sanitize(raw) class FormatVersion5 < FormatVersion4 def sanitize(raw) sanitized = super + raw['catalog_uuid'] ||= nil Util.verify_attributes(raw, %w[catalog_uuid cached_catalog_status]) Util.copy_attributes(sanitized, raw, %w[catalog_uuid cached_catalog_status]) end @@ -393,6 +394,7 @@ def sanitize(raw) class FormatVersion8 < FormatVersion7 def sanitize(raw) sanitized = super + raw['transaction_completed'] ||= nil Util.verify_attributes(raw, %w[transaction_completed]) Util.copy_attributes(sanitized, raw, %w[transaction_completed]) end @@ -410,6 +412,7 @@ def initialize( class FormatVersion9StatusSanitizer < FormatVersion6StatusSanitizer def sanitize(raw) sanitized = super + raw['provider_used'] ||= nil Util.verify_attributes(raw, %w[provider_used]) Util.copy_attributes(sanitized, raw, %w[provider_used]) end From c08b4a4e27a4d550c7c3ca21efd5603aca899e54 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Fri, 22 Jun 2018 11:29:37 +0200 Subject: [PATCH 16/17] use a sane log level default for prduction --- config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 6476dbc2e..5f60d52ad 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -51,7 +51,7 @@ # Use the lowest log level to ensure availability of diagnostic information # when problems arise. - config.log_level = :debug + config.log_level = :warn # Prepend all log lines with the following tags. config.log_tags = [ :request_id ] From df73f063ef2bc7fda32ab03aa779fc75bb0e09a8 Mon Sep 17 00:00:00 2001 From: Andreas Zuber Date: Tue, 21 Aug 2018 14:17:04 +0200 Subject: [PATCH 17/17] some updates to the readme --- README.markdown | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 77fdb5edf..e0b483d28 100644 --- a/README.markdown +++ b/README.markdown @@ -8,8 +8,7 @@ nodes, and view inventory data and backed-up file contents. Dependencies ------------ -* Ruby 1.8.7, 1.9.3, 2.0.0 or 2.1.x -* Bundler >= 1.1 +* Ruby 2.2, 2.3, 2.4, 2.5 * MySQL >= 5.1 or PostgreSQL >= 9.0 Fast Install @@ -41,11 +40,16 @@ cp config/settings.yml.example config/settings.yml && \ cp config/database.yml.example config/database.yml && \ vim config/database.yml ```` -* Install Puppet Dashboard +* Install Puppet Dashboard Dependencies ```` gem install bundler && \ -bundle install --deployment && \ -echo "secret_token: '$(bundle exec rake secret)'" >> config/settings.yml && \ +bundle install --deployment +```` +* You need to create a secret for production and either set it via environment variable: + `export SECRET_KEY_BASE=$(bundle exec rails secret)` + or follow the instructions in config/secrets.yml to setup an encrypted secret. +* Setup database and pre-compile assets +```` RAILS_ENV=production bundle exec rake db:setup && \ RAILS_ENV=production bundle exec rake assets:precompile ```` @@ -64,7 +68,7 @@ Dashboard is currently configured to serve static assets when `RAILS_ENV=product environments, you may wish to farm this out to Apache or nginx. Additionally, you must explicitly precompile assets for production using: - * `RAILS_ENV=production bundle exec rake assets:precompile` + * `SECRET_KEY_BASE=none RAILS_ENV=production bundle exec rails assets:precompile` Contributing ------------