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 ------------ 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/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/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 ] 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..8fd39889d --- /dev/null +++ b/db/migrate/20150405234511_add_environment_to_reports.rb @@ -0,0 +1,5 @@ +class AddEnvironmentToReports < ActiveRecord::Migration[4.2] + def change + add_column :reports, :environment, :string + end +end 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..22e83940f --- /dev/null +++ b/db/migrate/20150406035502_add_transaction_uuid_to_reports.rb @@ -0,0 +1,5 @@ +class AddTransactionUuidToReports < ActiveRecord::Migration[4.2] + 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..006383826 --- /dev/null +++ b/db/migrate/20150406035704_add_containment_path_to_resource_statuses.rb @@ -0,0 +1,5 @@ +class AddContainmentPathToResourceStatuses < ActiveRecord::Migration[4.2] + def change + add_column :resource_statuses, :containment_path, :text + end +end 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/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/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/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 4d65b9794..4d71079db 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,217 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141217071943) do +ActiveRecord::Schema.define(version: 2018_06_14_210435) 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.string "catalog_uuid" + t.string "cached_catalog_status" + t.boolean "noop" + 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 + + 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.boolean "corrective_change" + t.boolean "redacted" + 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.boolean "corrective_change" + t.string "provider_used" + 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/lib/puppet/report_sanitizer.rb b/lib/puppet/report_sanitizer.rb index c10553b66..8d8249224 100644 --- a/lib/puppet/report_sanitizer.rb +++ b/lib/puppet/report_sanitizer.rb @@ -2,17 +2,50 @@ # 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) case when raw.include?('report_format') - format2sanitizer.sanitize(raw) + case raw['report_format'] + when 2 + format2sanitizer.sanitize(raw) + when 3 + format3sanitizer.sanitize(raw) + when 4 + format4sanitizer.sanitize(raw) + when 5 + format5sanitizer.sanitize(raw) + when 6 + format6sanitizer.sanitize(raw) + when 7 + 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') format1sanitizer.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 @@ -28,13 +61,41 @@ def format1sanitizer() def format2sanitizer() @format2sanitizer ||= ReportSanitizer::FormatVersion2.new end + + def format3sanitizer() + @format3sanitizer ||= ReportSanitizer::FormatVersion3.new + end + + def format4sanitizer() + @format4sanitizer ||= ReportSanitizer::FormatVersion4.new + end + + def format5sanitizer() + @format5sanitizer ||= ReportSanitizer::FormatVersion5.new + end + + def format6sanitizer() + @format6sanitizer ||= ReportSanitizer::FormatVersion6.new + end + + def format7sanitizer() + @format7sanitizer ||= ReportSanitizer::FormatVersion7.new + end + + def format8sanitizer() + @format8sanitizer ||= ReportSanitizer::FormatVersion8.new + end + + def format9sanitizer() + @format9sanitizer ||= ReportSanitizer::FormatVersion9.new + end end 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 @@ -135,7 +196,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 +230,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, @@ -209,4 +270,153 @@ 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 + + # format version 4 is used by puppet 3.3.0-4.3.2 + class FormatVersion4 < FormatVersion3 + def initialize( + log_sanitizer = FormatVersion4LogSanitizer.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 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) + end + + 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 + 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 + + 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 + end + + class FormatVersion6 < FormatVersion5 + def initialize( + log_sanitizer = FormatVersion4LogSanitizer.new, + metric_sanitizer = MetricSanitizer.new, + status_sanitizer = FormatVersion6StatusSanitizer.new + ) + super(log_sanitizer, metric_sanitizer, status_sanitizer) + end + + 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 + + class FormatVersion6StatusSanitizer < FormatVersion4StatusSanitizer + def initialize(event_sanitizer = FormatVersion6EventSanitizer.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 FormatVersion6EventSanitizer < 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 + + class FormatVersion7 < FormatVersion6 + def sanitize(raw) + raw['kind'] = 'apply' + super + end + end + + 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 + 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 + raw['provider_used'] ||= nil + 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/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..a294582b5 --- /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 13: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..bfc29c5f9 --- /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 14: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/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/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/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/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/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 3b206b84c..823b1ffb0 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) @@ -92,13 +101,8 @@ end end - describe 'a format version 1 (puppet 2.6.x-2.7.12) 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 + describe 'a format version 1 (puppet 2.6.0-2.6.4) report' do + 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) @@ -358,132 +362,8 @@ end end - describe 'a format version 2 (puppet 2.7.13+) 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 + describe 'a format version 2 (puppet 2.6.5-2.7.11) report' do + let(:report_file) { '02_failing.yaml' } it "should produce a hash of the report" do hash = ReportSanitizer.sanitize(raw_report) @@ -494,5 +374,126 @@ 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(:report_file) { '03_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} + hash["report_format"].should == 3 + hash["host"].should == "localhost" + hash["time"].should == Time.parse("2010-07-22 13:19:47.204207 -07:00") + hash["environment"].should == "production" + end + end + + 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 + 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 14: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 + 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 + + 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 + + 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 + + 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 + + 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