fuel-noop-fixtures/lib/noop/manager/library.rb

297 lines
10 KiB
Ruby

require 'yaml'
require 'set'
module Noop
class Manager
# @return [Array<Pathname>]
def spec_file_names
return @spec_file_names if @spec_file_names
@spec_file_names = []
Noop::Utils.error "No #{Noop::Config.dir_path_task_spec} directory!" unless Noop::Config.dir_path_task_spec.directory?
Noop::Config.dir_path_task_spec.find do |spec_file|
next unless spec_file.file?
next unless spec_file.to_s.end_with? '_spec.rb'
@spec_file_names << spec_file.relative_path_from(Noop::Config.dir_path_task_spec)
end
@spec_file_names
end
# @return [Array<Pathname>]
def hiera_file_names
return @hiera_file_names if @hiera_file_names
@hiera_file_names = []
Noop::Utils.error "No #{Noop::Config.dir_path_hiera} directory!" unless Noop::Config.dir_path_hiera.directory?
Noop::Config.dir_path_hiera.find do |hiera_name|
next unless hiera_name.file?
next unless hiera_name.to_s.end_with? '.yaml'
base_dir = hiera_name.dirname.basename
next if base_dir == Noop::Config.dir_name_hiera_override
next if base_dir == Noop::Config.dir_name_globals
@hiera_file_names << hiera_name.relative_path_from(Noop::Config.dir_path_hiera)
end
@hiera_file_names
end
# @return [Array<Pathname>]
def facts_file_names
return @facts_file_names if @facts_file_names
@facts_file_names = []
Noop::Utils.error "No #{Noop::Config.dir_path_facts} directory!" unless Noop::Config.dir_path_facts.directory?
Noop::Config.dir_path_facts.find do |facts_name|
next unless facts_name.file?
next unless facts_name.to_s.end_with? '.yaml'
next if facts_name.dirname.basename == Noop::Config.dir_name_facts_override
@facts_file_names << facts_name.relative_path_from(Noop::Config.dir_path_facts)
end
@facts_file_names
end
# @return [Array<Pathname>]
def task_file_names
return @task_file_names if @task_file_names
@task_file_names = []
Noop::Utils.error "No #{Noop::Config.dir_path_tasks_local} directory!" unless Noop::Config.dir_path_tasks_local.directory?
Noop::Config.dir_path_tasks_local.find do |task_name|
next unless task_name.file?
next unless task_name.to_s.end_with? '.pp'
@task_file_names << task_name.relative_path_from(Noop::Config.dir_path_tasks_local)
end
@task_file_names
end
# @return [Hash<String => Hash>]
def task_graph_metadata
return @task_graph_metadata if @task_graph_metadata
@task_graph_metadata = {}
Noop::Utils.error "No #{Noop::Config.dir_path_modules_local} directory!" unless Noop::Config.dir_path_modules_local.directory?
Noop::Config.dir_path_modules_local.find do |task_file|
next unless task_file.file?
next unless task_file.to_s.end_with? 'tasks.yaml'
begin
tasks = YAML.load_file task_file
rescue
next
end
tasks.each do |task|
id = task['id']
@task_graph_metadata[id] = task
end
end
@task_graph_metadata.each do |id, group_task|
next unless group_task['type'] == 'group' and group_task['tasks'].is_a? Array
group_task['tasks'].each do |task|
next unless @task_graph_metadata[task]
@task_graph_metadata[task]['groups'] = [] unless @task_graph_metadata[task]['groups'].is_a? Array
@task_graph_metadata[task]['groups'] << id
end
end
@task_graph_metadata
end
# @return [Hash<Pathname => Set>]
def assign_spec_to_roles
return @assign_spec_to_roles if @assign_spec_to_roles
@assign_spec_to_roles = {}
task_graph_metadata.values.each do |task_data|
roles = task_data['groups'] or task_data['roles']
next unless roles.is_a? Array
file_path_manifest = task_data.fetch('parameters', {}).fetch('puppet_manifest', nil)
next unless file_path_manifest
file_path_manifest = Pathname.new file_path_manifest
file_name_manifest = file_path_manifest.relative_path_from Noop::Config.dir_path_tasks_node
file_name_spec = Noop::Utils.convert_to_spec file_name_manifest
roles = Set.new roles
@assign_spec_to_roles[file_name_spec] = Set.new unless @assign_spec_to_roles[file_name_spec].is_a? Set
@assign_spec_to_roles[file_name_spec] += roles
end
@assign_spec_to_roles
end
# @return [Hash<Pathname => Set>]
def assign_hiera_to_roles
return @assign_hiera_to_roles if @assign_hiera_to_roles
@assign_hiera_to_roles = {}
hiera_file_names.each do |hiera_file|
begin
data = YAML.load_file(Noop::Config.dir_path_hiera + hiera_file)
next unless data.is_a? Hash
fqdn = data['fqdn']
next unless fqdn
nodes = data.fetch('network_metadata', {}).fetch('nodes', nil)
next unless nodes
this_node = nodes.find do |node|
node.last['fqdn'] == fqdn
end
node_roles = this_node.last['node_roles']
roles = Set.new
roles.merge node_roles if node_roles.is_a? Array
role = data['role']
roles.add role if role
@assign_hiera_to_roles[hiera_file] = roles
rescue
next
end
end
@assign_hiera_to_roles
end
def assign_spec_to_hiera
return @assign_spec_to_hiera if @assign_spec_to_hiera
@assign_spec_to_hiera = {}
assign_spec_to_roles.each do |file_name_spec, spec_roles|
hiera_files = assign_hiera_to_roles.select do |file_name_hiera, hiera_roles|
hiera_roles.intersect? spec_roles
end.keys
@assign_spec_to_hiera[file_name_spec] = hiera_files if hiera_files.any?
end
@assign_spec_to_hiera
end
# @return [Hash<Pathname => Array>]
def spec_run_metadata
return @spec_run_metadata if @spec_run_metadata
@spec_run_metadata = {}
Noop::Config.dir_path_task_spec.find do |spec_file|
next unless spec_file.file?
next unless spec_file.to_s.end_with? '_spec.rb'
spec_name = spec_file.relative_path_from(Noop::Config.dir_path_task_spec)
spec_data = parse_spec_file spec_file
@spec_run_metadata[spec_name] = spec_data if spec_data.any?
end
@spec_run_metadata
end
# @param [Pathname] task_spec
def parse_spec_file(task_spec)
task_spec_metadata = {}
begin
text = task_spec.read
text.split("\n").each do |line|
line = line.downcase
if line =~ /^\s*#\s*(?:yamls|hiera):\s*(.*)/
task_spec_metadata[:hiera] = get_list_of_yamls $1
end
if line =~ /^\s*#\s*facts:\s*(.*)/
task_spec_metadata[:facts] = get_list_of_yamls $1
end
if line =~ /^\s*#\s*(?:skip_yamls|skip_hiera):\s(.*)/
task_spec_metadata[:skip_hiera] = get_list_of_yamls $1
end
if line =~ /^\s*#\s*skip_facts:\s(.*)/
task_spec_metadata[:skip_facts] = get_list_of_yamls $1
end
if line =~ /disable_spec/
task_spec_metadata[:disable] = true
end
if line =~ /^\s*#\s*run:\s*(.*)/
run_record = get_list_of_yamls $1
if run_record.length >= 2
run_record = {
:hiera => run_record[0],
:facts => run_record[1],
}
task_spec_metadata[:runs] = [] unless task_spec_metadata[:runs].is_a? Array
task_spec_metadata[:runs] << run_record
end
end
end
rescue
return task_spec_metadata
end
task_spec_metadata
end
# @return [Array<Pathname>]
def get_list_of_yamls(line)
line = line.split /\s*,\s*|\s+/
line.map do |yaml|
yaml = Pathname.new yaml
yaml = yaml.sub /$/, '.yaml' unless yaml.extname =~ /\.yaml/i
yaml
end
end
def get_spec_runs(file_name_spec)
file_name_spec = Noop::Utils.convert_to_path file_name_spec
metadata = spec_run_metadata.fetch file_name_spec, {}
metadata[:facts] = [Noop::Config.default_facts_file_name] unless metadata[:facts]
metadata[:hiera] = assign_spec_to_hiera.fetch file_name_spec, [] unless metadata[:hiera]
runs = []
metadata[:facts].product metadata[:hiera] do |facts, hiera|
next if metadata[:skip_hiera].is_a? Array and metadata[:skip_hiera].include? hiera
next if metadata[:skip_facts].is_a? Array and metadata[:skip_facts].include? hiera
run_record = {
:hiera => hiera,
:facts => facts,
}
runs << run_record
end
runs += metadata[:runs] if metadata[:runs].is_a? Array
runs
end
def spec_included?(spec)
filter = options[:filter_specs]
return true unless filter
filter = [filter] unless filter.is_a? Array
filter.include? spec
end
def facts_included?(facts)
filter = options[:filter_facts]
return true unless filter
filter = [filter] unless filter.is_a? Array
filter.include? facts
end
def hiera_included?(hiera)
filter = options[:filter_hiera]
return true unless filter
filter = [filter] unless filter.is_a? Array
filter.include? hiera
end
def skip_globals?(file_name_spec)
return false unless file_name_spec == Noop::Config.spec_name_globals
return true unless options[:filter_specs]
not spec_included? file_name_spec
end
def spec_is_disabled?(file_name_spec)
file_name_spec = Noop::Utils.convert_to_path file_name_spec
spec_run_metadata.fetch(file_name_spec, {}).fetch(:disable, false)
end
def task_list
return @task_list if @task_list
@task_list = []
spec_file_names.each do |file_name_spec|
next if spec_is_disabled? file_name_spec
next if skip_globals? file_name_spec
next unless spec_included? file_name_spec
get_spec_runs(file_name_spec).each do |run|
next unless run[:hiera] and run[:facts]
next unless facts_included? run[:facts]
next unless hiera_included? run[:hiera]
task = Noop::Task.new file_name_spec, run[:hiera], run[:facts]
task.parallel = true if parallel_run?
@task_list << task
end
end
@task_list
end
end
end