abide_dev_utils 0.10.1 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +7 -1
- data/Gemfile.lock +25 -19
- data/Rakefile +28 -0
- data/abide_dev_utils.gemspec +1 -0
- data/lib/abide_dev_utils/cem/benchmark.rb +490 -0
- data/lib/abide_dev_utils/cem/generate/coverage_report.rb +380 -0
- data/lib/abide_dev_utils/cem/generate/reference.rb +319 -0
- data/lib/abide_dev_utils/cem/generate.rb +11 -0
- data/lib/abide_dev_utils/cem/hiera_data/mapping_data/map_data.rb +110 -0
- data/lib/abide_dev_utils/cem/hiera_data/mapping_data/mixins.rb +46 -0
- data/lib/abide_dev_utils/cem/hiera_data/mapping_data.rb +146 -0
- data/lib/abide_dev_utils/cem/hiera_data/resource_data/control.rb +127 -0
- data/lib/abide_dev_utils/cem/hiera_data/resource_data/parameters.rb +90 -0
- data/lib/abide_dev_utils/cem/hiera_data/resource_data/resource.rb +102 -0
- data/lib/abide_dev_utils/cem/hiera_data/resource_data.rb +310 -0
- data/lib/abide_dev_utils/cem/hiera_data.rb +7 -0
- data/lib/abide_dev_utils/cem/mapping/mapper.rb +282 -0
- data/lib/abide_dev_utils/cem/validate/resource_data.rb +33 -0
- data/lib/abide_dev_utils/cem/validate.rb +10 -0
- data/lib/abide_dev_utils/cem.rb +1 -0
- data/lib/abide_dev_utils/cli/cem.rb +98 -0
- data/lib/abide_dev_utils/dot_number_comparable.rb +75 -0
- data/lib/abide_dev_utils/errors/cem.rb +32 -0
- data/lib/abide_dev_utils/errors/general.rb +8 -2
- data/lib/abide_dev_utils/errors/ppt.rb +4 -0
- data/lib/abide_dev_utils/errors.rb +6 -0
- data/lib/abide_dev_utils/markdown.rb +104 -0
- data/lib/abide_dev_utils/ppt/class_utils.rb +1 -1
- data/lib/abide_dev_utils/ppt/code_gen/data_types.rb +64 -0
- data/lib/abide_dev_utils/ppt/code_gen/generate.rb +15 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource.rb +59 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource_types/base.rb +93 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource_types/class.rb +17 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource_types/manifest.rb +16 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource_types/parameter.rb +16 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource_types/strings.rb +13 -0
- data/lib/abide_dev_utils/ppt/code_gen/resource_types.rb +6 -0
- data/lib/abide_dev_utils/ppt/code_gen.rb +15 -0
- data/lib/abide_dev_utils/ppt/code_introspection.rb +102 -0
- data/lib/abide_dev_utils/ppt/facter_utils.rb +140 -0
- data/lib/abide_dev_utils/ppt/hiera.rb +300 -0
- data/lib/abide_dev_utils/ppt/puppet_module.rb +75 -0
- data/lib/abide_dev_utils/ppt.rb +6 -5
- data/lib/abide_dev_utils/validate.rb +14 -0
- data/lib/abide_dev_utils/version.rb +1 -1
- data/lib/abide_dev_utils/xccdf/parser/helpers.rb +146 -0
- data/lib/abide_dev_utils/xccdf/parser/objects.rb +87 -144
- data/lib/abide_dev_utils/xccdf/parser.rb +5 -0
- data/lib/abide_dev_utils/xccdf/utils.rb +89 -0
- data/lib/abide_dev_utils/xccdf.rb +3 -0
- metadata +50 -3
- data/lib/abide_dev_utils/ppt/coverage.rb +0 -86
@@ -0,0 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'abide_dev_utils/ppt/code_gen/resource_types/class'
|
4
|
+
require 'abide_dev_utils/ppt/code_gen/resource_types/manifest'
|
5
|
+
require 'abide_dev_utils/ppt/code_gen/resource_types/parameter'
|
6
|
+
require 'abide_dev_utils/ppt/code_gen/resource_types/strings'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'abide_dev_utils/ppt/code_gen/data_types'
|
4
|
+
require 'abide_dev_utils/ppt/code_gen/resource'
|
5
|
+
require 'abide_dev_utils/ppt/code_gen/resource_types'
|
6
|
+
|
7
|
+
module AbideDevUtils
|
8
|
+
module Ppt
|
9
|
+
module CodeGen
|
10
|
+
def self.generate_a_manifest
|
11
|
+
Manifest.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'puppet_pal'
|
4
|
+
require_relative 'code_gen/data_types'
|
5
|
+
|
6
|
+
module AbideDevUtils
|
7
|
+
module Ppt
|
8
|
+
module CodeIntrospection
|
9
|
+
class Manifest
|
10
|
+
attr_reader :manifest_file
|
11
|
+
|
12
|
+
def initialize(manifest_file)
|
13
|
+
@manifest_file = File.expand_path(manifest_file)
|
14
|
+
raise ArgumentError, "File #{@manifest_file} is not a file" unless File.file?(@manifest_file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def ast
|
18
|
+
@ast ||= Puppet::Pal::Compiler.new(nil).parse_file(manifest_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
def declaration
|
22
|
+
@declaration ||= Declaration.new(ast)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Declaration
|
27
|
+
include AbideDevUtils::Ppt::CodeGen::DataTypes
|
28
|
+
attr_reader :ast
|
29
|
+
|
30
|
+
def initialize(ast)
|
31
|
+
@ast = ast.definitions.first
|
32
|
+
end
|
33
|
+
|
34
|
+
def parameters?
|
35
|
+
ast.respond_to? :parameters
|
36
|
+
end
|
37
|
+
|
38
|
+
def parameters
|
39
|
+
return unless parameters?
|
40
|
+
|
41
|
+
@parameters ||= ast.parameters.map { |p| Parameter.new(p) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Parameter
|
46
|
+
include AbideDevUtils::Ppt::CodeGen::DataTypes
|
47
|
+
attr_reader :ast
|
48
|
+
|
49
|
+
def initialize(param_ast)
|
50
|
+
@ast = param_ast
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_a(raw: false)
|
54
|
+
[type_expr(raw: raw), name(raw: raw), value(raw: raw)]
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_h(raw: false)
|
58
|
+
{
|
59
|
+
type_expr: type_expr(raw: raw),
|
60
|
+
name: name(raw: raw),
|
61
|
+
value: value(raw: raw),
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s(raw: false)
|
66
|
+
stra = [type_expr(raw: raw), name(raw: raw)]
|
67
|
+
stra << '=' if value? && !raw
|
68
|
+
stra << value(raw: raw)
|
69
|
+
stra.compact.join(' ')
|
70
|
+
end
|
71
|
+
|
72
|
+
def name(raw: false)
|
73
|
+
return ast.name if raw
|
74
|
+
|
75
|
+
"$#{ast.name}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def value?
|
79
|
+
ast.respond_to? :value
|
80
|
+
end
|
81
|
+
|
82
|
+
def value(raw: false)
|
83
|
+
return unless value?
|
84
|
+
return ast.value if raw
|
85
|
+
|
86
|
+
display_value(ast)
|
87
|
+
end
|
88
|
+
|
89
|
+
def type_expr?
|
90
|
+
ast.respond_to? :type_expr
|
91
|
+
end
|
92
|
+
|
93
|
+
def type_expr(raw: false)
|
94
|
+
return unless type_expr?
|
95
|
+
return ast.type_expr if raw
|
96
|
+
|
97
|
+
display_type_expr(ast)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'facterdb'
|
5
|
+
|
6
|
+
module AbideDevUtils
|
7
|
+
module Ppt
|
8
|
+
# Methods relating to Facter
|
9
|
+
module FacterUtils
|
10
|
+
class << self
|
11
|
+
attr_writer :current_version
|
12
|
+
|
13
|
+
def current_version
|
14
|
+
return latest_version unless defined?(@current_version)
|
15
|
+
|
16
|
+
@current_version
|
17
|
+
end
|
18
|
+
|
19
|
+
def use_version(version)
|
20
|
+
self.current_version = version
|
21
|
+
current_version
|
22
|
+
end
|
23
|
+
|
24
|
+
def with_version(version, reset: true)
|
25
|
+
return unless block_given?
|
26
|
+
|
27
|
+
old_ver = current_version.dup
|
28
|
+
use_version(version)
|
29
|
+
output = yield
|
30
|
+
use_version(old_ver) if reset
|
31
|
+
output
|
32
|
+
end
|
33
|
+
|
34
|
+
def fact_files
|
35
|
+
@fact_files ||= FacterDB.facterdb_fact_files.each_with_object({}) do |f, h|
|
36
|
+
facter_version = file_facter_version(f)
|
37
|
+
h[facter_version] = [] unless h.key?(facter_version)
|
38
|
+
h[facter_version] << f
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def fact_sets(facter_version: current_version)
|
43
|
+
@fact_sets ||= fact_files[facter_version].each_with_object({}) do |fp, h|
|
44
|
+
h[facter_version] = [] unless h.key?(facter_version)
|
45
|
+
h[facter_version] << JSON.parse(File.read(fp))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def file_facter_version(path)
|
50
|
+
File.basename(File.dirname(path))
|
51
|
+
end
|
52
|
+
|
53
|
+
def all_versions
|
54
|
+
@all_versions ||= fact_files.keys.sort
|
55
|
+
end
|
56
|
+
|
57
|
+
def latest_version
|
58
|
+
@latest_version ||= all_versions[-1]
|
59
|
+
end
|
60
|
+
|
61
|
+
def previous_major_version(facter_version = current_version)
|
62
|
+
@previous_major_version_map ||= {}
|
63
|
+
|
64
|
+
majver = facter_version.split('.')[0]
|
65
|
+
return @previous_major_version_map[majver] if @previous_major_version_map.key?(majver)
|
66
|
+
|
67
|
+
prev_majver = (majver.to_i - 1).to_s
|
68
|
+
prev_ver = all_versions.select { |v| v.start_with?(prev_majver) }.max
|
69
|
+
return nil if prev_ver.to_i < 1
|
70
|
+
|
71
|
+
@previous_major_version_map[majver] = prev_ver
|
72
|
+
@previous_major_version_map[majver]
|
73
|
+
end
|
74
|
+
|
75
|
+
def recurse_versions(version = current_version, &block)
|
76
|
+
use_version(version)
|
77
|
+
output = yield
|
78
|
+
return output unless output.nil? || output.empty?
|
79
|
+
|
80
|
+
prev_ver = previous_major_version(version).dup
|
81
|
+
return nil if prev_ver.nil?
|
82
|
+
|
83
|
+
recurse_versions(prev_ver, &block)
|
84
|
+
rescue SystemStackError
|
85
|
+
locals = {
|
86
|
+
prev_ver_map: @previous_major_version_map,
|
87
|
+
current_version: current_version,
|
88
|
+
}
|
89
|
+
raise "Failed to find output while recursing versions. Locals: #{locals}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def recursive_facts_for_os(os_name, os_release_major = nil, os_hardware: 'x86_64')
|
93
|
+
saved_ver = current_version.dup
|
94
|
+
output = recurse_versions do
|
95
|
+
facts_for_os(os_name, os_release_major, os_hardware: os_hardware)
|
96
|
+
end
|
97
|
+
use_version(saved_ver)
|
98
|
+
output
|
99
|
+
end
|
100
|
+
|
101
|
+
def facts_for_os(os_name, os_release_major = nil, os_hardware: 'x86_64', facter_version: current_version)
|
102
|
+
cache_key = "#{os_name.downcase}_#{os_release_major}_#{os_hardware}"
|
103
|
+
return @facts_for_os[cache_key] if @facts_for_os&.key?(cache_key)
|
104
|
+
|
105
|
+
fact_file = fact_files[facter_version].find do |f|
|
106
|
+
name_parts = File.basename(f, '.facts').split('-')
|
107
|
+
name = name_parts[0]
|
108
|
+
relmaj = name_parts.length >= 3 ? name_parts[1] : nil
|
109
|
+
hardware = name_parts[-1]
|
110
|
+
name == os_name.downcase && relmaj == os_release_major && hardware == os_hardware
|
111
|
+
end
|
112
|
+
return if fact_file.nil? || fact_file.empty?
|
113
|
+
|
114
|
+
@facts_for_os = {} unless defined?(@facts_for_os)
|
115
|
+
@facts_for_os[cache_key] = JSON.parse(File.read(fact_file))
|
116
|
+
@facts_for_os[cache_key]
|
117
|
+
end
|
118
|
+
|
119
|
+
def resolve_dot_path(dot_path, facter_version: latest_version)
|
120
|
+
path_array = dot_path.delete_prefix('facts.').split('.')
|
121
|
+
resolved = fact_sets[facter_version].map do |fs|
|
122
|
+
fs.dig(*path_array)
|
123
|
+
end
|
124
|
+
resolved.compact.uniq
|
125
|
+
end
|
126
|
+
|
127
|
+
def resolve_related_dot_paths(*dot_paths, facter_version: current_version)
|
128
|
+
resolved = []
|
129
|
+
fact_sets[facter_version].map do |fs|
|
130
|
+
resolved << dot_paths.map do |p|
|
131
|
+
path_array = p.delete_prefix('facts.').split('.')
|
132
|
+
fs.dig(*path_array)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
resolved
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,300 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'abide_dev_utils/validate'
|
5
|
+
require 'abide_dev_utils/ppt/facter_utils'
|
6
|
+
|
7
|
+
module AbideDevUtils
|
8
|
+
module Ppt
|
9
|
+
# Module for working with Hiera
|
10
|
+
module Hiera
|
11
|
+
INTERP_PATTERN = /%{([^{}]+)}/.freeze
|
12
|
+
FACT_PATTERN = /%{facts\.([^{}]+)}/.freeze
|
13
|
+
DEFAULT_FACTER_VERSION = '3.14'
|
14
|
+
DEFAULT_CONFIG_FILE = 'hiera.yaml'
|
15
|
+
|
16
|
+
def self.facter_version=(version)
|
17
|
+
@facter_version = AbideDevUtils::Ppt::FacterUtils.use_version(version.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.facter_version
|
21
|
+
@facter_version
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.default_datadir=(dir)
|
25
|
+
edir = File.expand_path(dir)
|
26
|
+
raise "Dir #{edir} not found" unless File.directory?(edir)
|
27
|
+
|
28
|
+
@default_datadir = edir
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.default_datadir
|
32
|
+
@default_datadir
|
33
|
+
end
|
34
|
+
|
35
|
+
# Represents a Hiera configuration file
|
36
|
+
class Config
|
37
|
+
def initialize(path = DEFAULT_CONFIG_FILE, facter_version: DEFAULT_FACTER_VERSION)
|
38
|
+
@path = File.expand_path(path)
|
39
|
+
raise "Hiera config file at path #{@path} not found!" unless File.file?(@path)
|
40
|
+
|
41
|
+
@root_dir = File.dirname(@path)
|
42
|
+
@conf = YAML.load_file(File.expand_path(path))
|
43
|
+
@by_name_path_store = {}
|
44
|
+
AbideDevUtils::Ppt::Hiera.facter_version = facter_version
|
45
|
+
if @conf['defaults'].key?('datadir')
|
46
|
+
AbideDevUtils::Ppt::Hiera.default_datadir = File.join(@root_dir, @conf['defaults']['datadir'])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def hierarchy
|
51
|
+
@hierarchy ||= Hierarchy.new(@conf['hierarchy'], AbideDevUtils::Ppt::Hiera.default_datadir)
|
52
|
+
end
|
53
|
+
|
54
|
+
def version
|
55
|
+
@version ||= @conf['version']
|
56
|
+
end
|
57
|
+
|
58
|
+
def defaults
|
59
|
+
@defaults ||= @conf['defaults']
|
60
|
+
end
|
61
|
+
|
62
|
+
def default_datadir
|
63
|
+
AbideDevUtils::Ppt::Hiera.default_datadir
|
64
|
+
end
|
65
|
+
|
66
|
+
def default_data_hash
|
67
|
+
@default_data_hash ||= defaults['data_hash']
|
68
|
+
end
|
69
|
+
|
70
|
+
def local_hiera_files(hierarchy_name: nil)
|
71
|
+
if hierarchy_name
|
72
|
+
hierarchy.entry_by_name(hierarchy_name).local_files
|
73
|
+
else
|
74
|
+
hierarchy.entries.map(&:local_files).flatten
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def local_hiera_files_with_fact(fact_str, value = nil, hierarchy_name: nil)
|
79
|
+
if hierarchy_name
|
80
|
+
hierarchy.entry_by_name(hierarchy_name).local_files_with_fact(fact_str, value)
|
81
|
+
else
|
82
|
+
hierarchy.entries.map { |e| e.local_files_with_fact(fact_str, value) }.flatten
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def local_hiera_files_with_facts(*fact_arrays, hierarchy_name: nil)
|
87
|
+
if hierarchy_name
|
88
|
+
hierarchy.entry_by_name(hierarchy_name).local_files_with_facts(*fact_arrays)
|
89
|
+
else
|
90
|
+
hierarchy.entries.map { |e| e.local_files_with_fact(*fact_arrays) }.flatten
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Represents the "hierarchy" section of the Hiera config
|
96
|
+
class Hierarchy
|
97
|
+
attr_reader :default_datadir, :entries
|
98
|
+
|
99
|
+
def initialize(hierarchy, default_datadir)
|
100
|
+
@hierarchy = hierarchy
|
101
|
+
@default_datadir = File.expand_path(default_datadir)
|
102
|
+
@entries = @hierarchy.map { |h| HierarchyEntry.new(h) }
|
103
|
+
@by_name_store = {}
|
104
|
+
@paths_by_name_store = {}
|
105
|
+
end
|
106
|
+
|
107
|
+
def method_missing(m, *args, &block)
|
108
|
+
if %i[each each_with_object each_with_index select reject map].include?(m)
|
109
|
+
@entries.send(m, *args, &block)
|
110
|
+
else
|
111
|
+
super
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def respond_to_missing?(m, include_private = false)
|
116
|
+
%i[each each_with_object each_with_index select reject map].include?(m) || super
|
117
|
+
end
|
118
|
+
|
119
|
+
def entry_by_name(name)
|
120
|
+
AbideDevUtils::Validate.populated_string(name)
|
121
|
+
return @by_name_store[name] if @by_name_store[name]
|
122
|
+
|
123
|
+
found = @entries.select { |x| x.name == name }
|
124
|
+
AbideDevUtils::Validate.not_empty(found, "Hierarchy entry for name '#{name}' not found")
|
125
|
+
@by_name_store[name] = found[0]
|
126
|
+
@by_name_store[name]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Represents a single entry in the hierarchy
|
131
|
+
class HierarchyEntry
|
132
|
+
attr_reader :entry, :name, :paths
|
133
|
+
|
134
|
+
def initialize(entry)
|
135
|
+
@entry = entry
|
136
|
+
@name = @entry['name']
|
137
|
+
@paths = @entry.key?('path') ? create_paths(@entry['path']) : create_paths(*@entry['paths'])
|
138
|
+
end
|
139
|
+
|
140
|
+
def local_files
|
141
|
+
@local_files ||= paths.map(&:local_files).flatten
|
142
|
+
end
|
143
|
+
|
144
|
+
def local_files_with_fact(fact_str, value = nil)
|
145
|
+
paths.map { |p| p.local_files_with_fact(fact_str, value) }.flatten
|
146
|
+
end
|
147
|
+
|
148
|
+
def local_files_with_facts(*fact_arrays)
|
149
|
+
paths.map { |p| p.local_files_with_facts(*fact_arrays) }.flatten
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_s
|
153
|
+
name
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def create_paths(*paths)
|
159
|
+
paths.map { |p| HierarchyEntryPath.new(p) }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Represents a Hiera entry path
|
164
|
+
class HierarchyEntryPath
|
165
|
+
attr_reader :path
|
166
|
+
|
167
|
+
def initialize(path)
|
168
|
+
@path = path
|
169
|
+
end
|
170
|
+
|
171
|
+
def path_parts
|
172
|
+
@path_parts ||= path.split('/')
|
173
|
+
end
|
174
|
+
|
175
|
+
def interpolation
|
176
|
+
@interpolation ||= path.scan(INTERP_PATTERN).flatten
|
177
|
+
end
|
178
|
+
|
179
|
+
def interpolation?
|
180
|
+
!interpolation.empty?
|
181
|
+
end
|
182
|
+
|
183
|
+
def facts
|
184
|
+
@facts ||= path.scan(FACT_PATTERN).flatten
|
185
|
+
end
|
186
|
+
|
187
|
+
def facts?
|
188
|
+
!facts.empty?
|
189
|
+
end
|
190
|
+
|
191
|
+
def possible_fact_values
|
192
|
+
@possible_fact_values ||= AbideDevUtils::Ppt::FacterUtils.resolve_related_dot_paths(*facts)
|
193
|
+
end
|
194
|
+
|
195
|
+
def local_files
|
196
|
+
@local_files ||= find_local_files.flatten
|
197
|
+
end
|
198
|
+
|
199
|
+
def local_files_with_fact(fact_str, value = nil)
|
200
|
+
local_files.select do |lf|
|
201
|
+
# The match below is case-insentive for convenience
|
202
|
+
(value.nil? ? lf.fact_values.key?(fact_str) : (lf.fact_values[fact_str]&.match?(/#{value}/i) || false))
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def local_files_with_facts(*fact_arrays)
|
207
|
+
return local_files_with_fact(*fact_arrays[0]) if fact_arrays.length == 1
|
208
|
+
|
209
|
+
start_fact = fact_arrays[0][0]
|
210
|
+
last_fact = nil
|
211
|
+
memo = {}
|
212
|
+
with_facts = []
|
213
|
+
fact_arrays.each do |fa|
|
214
|
+
cur_fact = fa[0]
|
215
|
+
memo[cur_fact] = local_files_with_fact(*fa)
|
216
|
+
if cur_fact == start_fact
|
217
|
+
with_facts = memo[cur_fact]
|
218
|
+
else
|
219
|
+
last_paths = memo[last_fact].map(&:path)
|
220
|
+
cur_paths = memo[cur_fact].map(&:path)
|
221
|
+
with_facts.reject! { |x| last_paths.difference(cur_paths).include?(x.path) }
|
222
|
+
end
|
223
|
+
last_fact = cur_fact
|
224
|
+
end
|
225
|
+
with_facts.flatten.uniq(&:path)
|
226
|
+
end
|
227
|
+
|
228
|
+
def to_s
|
229
|
+
path
|
230
|
+
end
|
231
|
+
|
232
|
+
private
|
233
|
+
|
234
|
+
def find_local_files
|
235
|
+
new_paths = []
|
236
|
+
possible_fact_values.each do |pfv|
|
237
|
+
new_path = path.dup
|
238
|
+
pfv.each do |v|
|
239
|
+
next unless v
|
240
|
+
|
241
|
+
new_path.sub!(FACT_PATTERN, v)
|
242
|
+
end
|
243
|
+
new_paths << EntryPathLocalFile.new(new_path, facts, possible_fact_values)
|
244
|
+
end
|
245
|
+
new_paths.uniq(&:path).select(&:exist?)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# Represents a local file derived from a Hiera path
|
250
|
+
class EntryPathLocalFile
|
251
|
+
attr_reader :path, :facts
|
252
|
+
|
253
|
+
def initialize(path, facts, possible_fact_values)
|
254
|
+
@path = File.expand_path(File.join(AbideDevUtils::Ppt::Hiera.default_datadir, path))
|
255
|
+
@facts = facts
|
256
|
+
@possible_fact_values = possible_fact_values
|
257
|
+
end
|
258
|
+
|
259
|
+
def fact_values
|
260
|
+
@fact_values ||= fact_values_for_path
|
261
|
+
end
|
262
|
+
|
263
|
+
def path_parts
|
264
|
+
@path_parts ||= path.split('/')
|
265
|
+
end
|
266
|
+
|
267
|
+
def exist?
|
268
|
+
File.file?(path)
|
269
|
+
end
|
270
|
+
|
271
|
+
def to_s
|
272
|
+
path
|
273
|
+
end
|
274
|
+
|
275
|
+
def to_h
|
276
|
+
{
|
277
|
+
path: path,
|
278
|
+
facts: facts
|
279
|
+
}
|
280
|
+
end
|
281
|
+
|
282
|
+
private
|
283
|
+
|
284
|
+
def fact_values_for_path
|
285
|
+
no_fext_path_parts = path_parts.map { |part| File.basename(part, '.yaml') }
|
286
|
+
valid_fact_values = @possible_fact_values.select do |pfv|
|
287
|
+
pfv.all? { |v| no_fext_path_parts.include?(v) }
|
288
|
+
end
|
289
|
+
valid_fact_values.uniq! # Removes duplicate arrays, not duplicate fact values
|
290
|
+
valid_fact_values.flatten!
|
291
|
+
return {} if valid_fact_values.empty?
|
292
|
+
|
293
|
+
fact_vals = {}
|
294
|
+
facts.each_index { |idx| fact_vals[facts[idx]] = valid_fact_values[idx] }
|
295
|
+
fact_vals
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
require 'abide_dev_utils/validate'
|
6
|
+
require 'abide_dev_utils/ppt/hiera'
|
7
|
+
|
8
|
+
module AbideDevUtils
|
9
|
+
module Ppt
|
10
|
+
# Class for working with Puppet Modules
|
11
|
+
class PuppetModule
|
12
|
+
DEF_FILES = {
|
13
|
+
metadata: 'metadata.json',
|
14
|
+
readme: 'README.md',
|
15
|
+
reference: 'REFERENCE.md',
|
16
|
+
changelog: 'CHANGELOG.md',
|
17
|
+
hiera_config: 'hiera.yaml',
|
18
|
+
fixtures: '.fixtures.yml',
|
19
|
+
rubocop: '.rubocop.yml',
|
20
|
+
sync: '.sync.yml',
|
21
|
+
pdkignore: '.pdkignore',
|
22
|
+
gitignore: '.gitignore'
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
attr_reader :directory, :special_files
|
26
|
+
|
27
|
+
def initialize(directory = Dir.pwd)
|
28
|
+
AbideDevUtils::Validate.directory(directory)
|
29
|
+
@directory = directory
|
30
|
+
@special_files = DEF_FILES.dup.transform_values { |v| File.expand_path(File.join(@directory, v)) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def name(strip_namespace: false)
|
34
|
+
strip_namespace ? metadata['name'].split('-')[-1] : metadata['name']
|
35
|
+
end
|
36
|
+
|
37
|
+
def metadata
|
38
|
+
@metadata ||= JSON.parse(File.read(special_files[:metadata]))
|
39
|
+
end
|
40
|
+
|
41
|
+
def supported_os
|
42
|
+
@supported_os ||= find_supported_os
|
43
|
+
end
|
44
|
+
|
45
|
+
def hiera_conf
|
46
|
+
@hiera_conf ||= AbideDevUtils::Ppt::Hiera::Config.new(special_files[:hiera_config])
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def find_supported_os
|
52
|
+
return [] unless metadata['operatingsystem_support']
|
53
|
+
|
54
|
+
metadata['operatingsystem_support'].each_with_object([]) do |os, arr|
|
55
|
+
os['operatingsystemrelease'].each do |r|
|
56
|
+
arr << "#{os['operatingsystem']}::#{r}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def in_dir
|
62
|
+
return unless block_given?
|
63
|
+
|
64
|
+
current = Dir.pwd
|
65
|
+
if current == File.expand_path(directory)
|
66
|
+
yield
|
67
|
+
else
|
68
|
+
Dir.chdir(directory)
|
69
|
+
yield
|
70
|
+
Dir.chdir(current)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/abide_dev_utils/ppt.rb
CHANGED
@@ -3,7 +3,13 @@
|
|
3
3
|
require 'abide_dev_utils/output'
|
4
4
|
require 'abide_dev_utils/validate'
|
5
5
|
require 'abide_dev_utils/errors'
|
6
|
+
require 'abide_dev_utils/ppt/api'
|
7
|
+
require 'abide_dev_utils/ppt/code_gen'
|
8
|
+
require 'abide_dev_utils/ppt/code_introspection'
|
6
9
|
require 'abide_dev_utils/ppt/class_utils'
|
10
|
+
require 'abide_dev_utils/ppt/facter_utils'
|
11
|
+
require 'abide_dev_utils/ppt/hiera'
|
12
|
+
require 'abide_dev_utils/ppt/puppet_module'
|
7
13
|
|
8
14
|
module AbideDevUtils
|
9
15
|
module Ppt
|
@@ -63,11 +69,6 @@ module AbideDevUtils
|
|
63
69
|
AbideDevUtils::Output.simple('Successfully fixed all classes.')
|
64
70
|
end
|
65
71
|
|
66
|
-
def self.generate_coverage_report(puppet_class_dir, hiera_path, profile = nil)
|
67
|
-
require 'abide_dev_utils/ppt/coverage'
|
68
|
-
CoverageReport.generate(puppet_class_dir, hiera_path, profile)
|
69
|
-
end
|
70
|
-
|
71
72
|
def self.build_new_object(type, name, opts)
|
72
73
|
require 'abide_dev_utils/ppt/new_obj'
|
73
74
|
AbideDevUtils::Ppt::NewObjectBuilder.new(
|
@@ -3,7 +3,12 @@
|
|
3
3
|
require 'abide_dev_utils/errors'
|
4
4
|
|
5
5
|
module AbideDevUtils
|
6
|
+
# Methods used for validating data
|
6
7
|
module Validate
|
8
|
+
def self.puppet_module_directory(path = Dir.pwd)
|
9
|
+
raise AbideDevUtils::Errors::Ppt::NotModuleDirError, path unless File.file?(File.join(path, 'metadata.json'))
|
10
|
+
end
|
11
|
+
|
7
12
|
def self.filesystem_path(path)
|
8
13
|
raise AbideDevUtils::Errors::FileNotFoundError, path unless File.exist?(path)
|
9
14
|
end
|
@@ -22,6 +27,15 @@ module AbideDevUtils
|
|
22
27
|
raise AbideDevUtils::Errors::PathNotDirectoryError, path unless File.directory?(path)
|
23
28
|
end
|
24
29
|
|
30
|
+
def self.populated_string(thing)
|
31
|
+
raise AbideDevUtils::Errors::NotPopulatedStringError, 'Object is nil' if thing.nil?
|
32
|
+
|
33
|
+
unless thing.instance_of?(String)
|
34
|
+
raise AbideDevUtils::Errors::NotPopulatedStringError, "Object is not a String. Type: #{thing.class}"
|
35
|
+
end
|
36
|
+
raise AbideDevUtils::Errors::NotPopulatedStringError, 'String is empty' if thing.empty?
|
37
|
+
end
|
38
|
+
|
25
39
|
def self.not_empty(thing, msg)
|
26
40
|
raise AbideDevUtils::Errors::ObjectEmptyError, msg if thing.empty?
|
27
41
|
end
|