fuel-noop-fixtures/lib/noop/task/catalog.rb

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