166 lines
5.5 KiB
Ruby
166 lines
5.5 KiB
Ruby
require 'erb'
|
|
|
|
module Noop
|
|
class Task
|
|
|
|
# Dumps the entire catalog structure to the text
|
|
# representation in the Puppet language
|
|
# @param context [Object] the context from the rspec test
|
|
# @param resources_filter [Array] the list of resources to dump. Dump all resources if not given
|
|
def catalog_dump(context, resources_filter = [])
|
|
catalog = context.subject
|
|
catalog = catalog.call if catalog.is_a? Proc
|
|
text = ''
|
|
resources_filter = [resources_filter] unless resources_filter.is_a? Array
|
|
catalog.resources.select do |catalog_resource|
|
|
if catalog_resource.type == 'Class'
|
|
next false if %w(main Settings).include? catalog_resource.title.to_s
|
|
end
|
|
next true unless resources_filter.any?
|
|
resources_filter.find do |filter_resource|
|
|
resources_are_same? catalog_resource, filter_resource
|
|
end
|
|
end.sort_by do |catalog_resource|
|
|
catalog_resource.to_s
|
|
end.each do |catalog_resource|
|
|
text += dump_resource(catalog_resource) + "\n"
|
|
text += "\n"
|
|
end
|
|
text
|
|
end
|
|
|
|
# Takes a parameter value and formats it to the literal value
|
|
# that could be placed in the Puppet manifest
|
|
# @param value [String, Array, Hash, true, false, nil]
|
|
# @return [String]
|
|
def parameter_value_format(value)
|
|
case value
|
|
when TrueClass then 'true'
|
|
when FalseClass then 'false'
|
|
when NilClass then 'undef'
|
|
when Array then begin
|
|
array = value.collect do |v|
|
|
parameter_value_format v
|
|
end.join(', ')
|
|
"[ #{array} ]"
|
|
end
|
|
when Hash then begin
|
|
hash = value.keys.sort do |a, b|
|
|
a.to_s <=> b.to_s
|
|
end.collect do |key|
|
|
"#{parameter_value_format key.to_s} => #{parameter_value_format value[key]}"
|
|
end.join(', ')
|
|
"{ #{hash} }"
|
|
end
|
|
when Numeric, Symbol then parameter_value_format value.to_s
|
|
when String then begin
|
|
# escapes single quote characters and wrap into them
|
|
"'#{value.gsub "'", '\\\\\''}'"
|
|
end
|
|
else value.to_s
|
|
end
|
|
end
|
|
|
|
# Take a resource object and generate a manifest representation of it
|
|
# in the Puppet language. Replaces "to_manifest" Puppet function which
|
|
# is not working correctly.
|
|
# @param resource [Puppet::Resource]
|
|
# @return [String]
|
|
def dump_resource(resource)
|
|
return '' unless resource.is_a? Puppet::Resource or resource.is_a? Puppet::Parser::Resource
|
|
attributes = resource.keys
|
|
if attributes.include?(:name) and resource[:name] == resource[:title]
|
|
attributes.delete(:name)
|
|
end
|
|
attribute_max_length = attributes.inject(0) do |max_length, attribute|
|
|
attribute.to_s.length > max_length ? attribute.to_s.length : max_length
|
|
end
|
|
attributes.sort!
|
|
if attributes.first != :ensure && attributes.include?(:ensure)
|
|
attributes.delete(:ensure)
|
|
attributes.unshift(:ensure)
|
|
end
|
|
attributes_text_block = attributes.map { |attribute|
|
|
value = resource[attribute]
|
|
" #{attribute.to_s.ljust attribute_max_length} => #{parameter_value_format value},\n"
|
|
}.join
|
|
"#{resource.type.to_s.downcase} { '#{resource.title.to_s}' :\n#{attributes_text_block}}"
|
|
end
|
|
|
|
# This function preprocesses both saved and generated
|
|
# catalogs before they will be compared. It allows us to ignore
|
|
# irrelevant changes in the catalogs:
|
|
# * ignore trailing whitespaces
|
|
# * ignore empty lines
|
|
# @param data [String]
|
|
# @return [String]
|
|
def preprocess_catalog_data(data)
|
|
clear_data = []
|
|
data.to_s.split("\n").each do |line|
|
|
line = line.rstrip
|
|
next if line == ''
|
|
clear_data << line
|
|
end
|
|
clear_data.join "\n"
|
|
end
|
|
|
|
# Check if two resources have same type and title
|
|
# @param res1 [Puppet::Resource]
|
|
# @param res2 [Puppet::Resource]
|
|
# @return [TrueClass, False,Class]
|
|
def resources_are_same?(res1, res2)
|
|
res1 = res1.to_s.downcase.gsub %r|'"|, ''
|
|
res2 = res2.to_s.downcase.gsub %r|'"|, ''
|
|
res1 == res2
|
|
end
|
|
|
|
# @return [Pathname]
|
|
def dir_name_catalogs
|
|
Pathname.new 'catalogs'
|
|
end
|
|
|
|
# @return [Pathname]
|
|
def dir_path_catalogs
|
|
Noop::Config.dir_path_root + dir_name_catalogs
|
|
end
|
|
|
|
# @return [Pathname]
|
|
def file_name_task_catalog
|
|
Noop::Utils.convert_to_path "#{file_name_base_task_report}.pp"
|
|
end
|
|
|
|
# @return [Pathname]
|
|
def file_path_task_catalog
|
|
dir_path_catalogs + file_name_task_catalog
|
|
end
|
|
|
|
# Write the catalog file of this task
|
|
# using the data from RSpec context
|
|
# @param context [Object] the context from the rspec test
|
|
# @return [void]
|
|
def file_write_task_catalog(context)
|
|
dir_path_catalogs.mkpath
|
|
error "Catalog directory '#{dir_path_catalogs}' doesn't exist!" unless dir_path_catalogs.directory?
|
|
debug "Writing catalog file: #{file_path_task_catalog}"
|
|
File.open(file_path_task_catalog.to_s, 'w') do |file|
|
|
file.puts catalog_dump context
|
|
end
|
|
end
|
|
|
|
# Check if the catalog file exists for this task
|
|
# @return [true,false]
|
|
def file_present_task_catalog?
|
|
file_path_task_catalog.file?
|
|
end
|
|
|
|
# Read the catalog file of this task
|
|
# @return [String]
|
|
def file_read_task_catalog
|
|
return unless file_present_task_catalog?
|
|
debug "Reading catalog file: #{file_path_task_catalog}"
|
|
file_path_task_catalog.read
|
|
end
|
|
|
|
end
|
|
end
|