Last active
August 29, 2015 14:05
-
-
Save manuq/eec269ce7ba00974f46e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# Utility for Puppet that outputs orphaned resources. Orphaned are | |
# resources that where at one point managed by Puppet, but they no | |
# longer are. | |
# | |
# We need to require Puppet because deserializing the report produces | |
# Puppet objects. | |
require 'optparse' | |
require 'yaml' | |
require 'puppet' | |
FILTERED_RESOURCES = ['Schedule[', 'File[/etc/puppet', 'File[/var/lib/puppet', | |
'File[/var/log/puppet', 'File[/var/run/puppet', | |
'configuration', 'Stage[main]', 'Class[Main]', | |
'Class[Settings]', 'Filebucket[puppet]'] | |
# puppet config print lastrunreport | |
$report_path = "/var/lib/puppet/state/last_run_report.yaml" | |
# puppet config print lastrunfile | |
$summary_path = "/var/lib/puppet/state/last_run_summary.yaml" | |
# puppet config print statefile | |
$state_path = "/var/lib/puppet/state/state.yaml" | |
METHODS = %w[report timestamps] | |
$method = "report" | |
OptionParser.new do |opts| | |
opts.banner = "Usage: orphaned.rb [options]" | |
opts.on('-m', '--method TYPE', "report or timestamps. Always used. Default: #{$method}", METHODS) { |m| $method = m } | |
opts.on('-t', '--state PATH', "Path to state.yaml. Default: #{$state_path}") { |p| $state_path = p } | |
opts.on('-r', '--report PATH', "Path to last_run_report.yaml. Used in method report. Default: #{$report_path}") { |p| $report_path = p } | |
opts.on('-s', '--summary PATH', "Path to last_run_summary.yaml. Used in method timestamps. Default: #{$summary_path}") { |p| $summary_path = p } | |
opts.on('-p', '--previous-report PATH', "Path to a previous last_run_report.yaml. If given, output has more detail.") { |p| $previous_report_path = p } | |
end.parse! | |
def parse_last_run(last_run_summary_data) | |
total = last_run_summary_data['time']['total'] | |
seconds_last_run = last_run_summary_data['time']['last_run'] | |
Time.at(seconds_last_run - total - 2) | |
end | |
def get_last_run(last_run_summary_path) | |
data = YAML.load_file(last_run_summary_path) | |
parse_last_run(data) | |
end | |
def parse_state_resources(state_data) | |
resources_data = state_data.select do |k, v| | |
not k.to_s.start_with?(*FILTERED_RESOURCES) | |
end | |
if resources_data.is_a? Array | |
resources_data.to_h | |
else | |
resources_data | |
end | |
end | |
def get_state_resources(state_path) | |
data = YAML.load_file(state_path) | |
parse_state_resources(data) | |
end | |
def parse_old_state_resources(state_data, last_run) | |
resources_data = parse_state_resources(state_data) | |
unmanaged_resources = [] | |
resources_data.each do |k, v| | |
if v[:checked] < last_run | |
unmanaged_resources.push(k) | |
end | |
end | |
return unmanaged_resources | |
end | |
def get_old_state_resources(state_path, last_run) | |
data = YAML.load_file(state_path) | |
parse_old_state_resources(data, last_run) | |
end | |
def parse_report_resources(report_data) | |
resources_data = report_data.resource_statuses.select do |k, v| | |
not k.to_s.start_with?(*FILTERED_RESOURCES) | |
end | |
if resources_data.is_a? Array | |
resources_data.to_h | |
else | |
resources_data | |
end | |
end | |
def get_report_resources(report_path) | |
data = YAML.load_file(report_path) | |
parse_report_resources(data) | |
end | |
def get_orphans_using_timestamps(state_path, summary_path) | |
last_run = get_last_run(summary_path) | |
get_old_state_resources(state_path, last_run) | |
end | |
def get_orphans_using_report(state_path, report_path) | |
state_resources = get_state_resources(state_path) | |
report_resources = get_report_resources(report_path) | |
state_resources.keys - report_resources.keys | |
end | |
def print_detail(orphan_resources, previous_report_path) | |
previous_resources = get_report_resources(previous_report_path) | |
orphan_resources.each do |k| | |
puts k | |
if previous_resources.keys.include? k | |
puts previous_resources[k].to_yaml | |
end | |
end | |
end | |
if $method == 'report' | |
orphans = get_orphans_using_report($state_path, $report_path) | |
else | |
orphans = get_orphans_using_timestamps($state_path, $summary_path) | |
end | |
if $previous_report_path.nil? | |
puts orphans | |
else | |
print_detail(orphans, $previous_report_path) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment