kafo 3.0.0 → 5.0.1
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/LICENSE.txt +619 -9
- data/README.md +36 -11
- data/Rakefile +7 -1
- data/doc/kafo_run.png +0 -0
- data/doc/kafo_run.uml +2 -2
- data/lib/kafo/base_context.rb +9 -1
- data/lib/kafo/configuration.rb +36 -11
- data/lib/kafo/execution_environment.rb +84 -0
- data/lib/kafo/exit_handler.rb +9 -4
- data/lib/kafo/fact_writer.rb +24 -0
- data/lib/kafo/hiera_configurer.rb +19 -93
- data/lib/kafo/hook_context.rb +37 -11
- data/lib/kafo/kafo_configure.rb +12 -17
- data/lib/kafo/puppet_command.rb +27 -3
- data/lib/kafo/puppet_configurer.rb +9 -15
- data/lib/kafo/puppet_module.rb +5 -1
- data/lib/kafo/scenario_manager.rb +13 -6
- data/lib/kafo/version.rb +1 -1
- data/modules/kafo_configure/spec/fixtures/manifests/site.pp +0 -0
- metadata +16 -9
- data/lib/kafo/password_manager.rb +0 -47
data/lib/kafo/hook_context.rb
CHANGED
@@ -6,14 +6,7 @@ module Kafo
|
|
6
6
|
attr_reader :kafo
|
7
7
|
|
8
8
|
def self.execute(kafo, &hook)
|
9
|
-
|
10
|
-
# instance_exec can be later changed to instance eval when people stop using |kafo| in their hooks
|
11
|
-
# and rely only on hook context DSL
|
12
|
-
if hook.arity > 0
|
13
|
-
kafo.logger.warn "Hook '#{name}' is using block with arguments which is DEPRECATED, access to kafo instance is " +
|
14
|
-
"provided by hook DSL, please remove |kafo| from your hook block"
|
15
|
-
end
|
16
|
-
new(kafo).instance_exec(kafo, &hook)
|
9
|
+
new(kafo).instance_eval(&hook)
|
17
10
|
end
|
18
11
|
|
19
12
|
def initialize(kafo)
|
@@ -29,7 +22,7 @@ module Kafo
|
|
29
22
|
end
|
30
23
|
|
31
24
|
# if you want to add new app_option be sure to do as soon as possible (usually boot hook)
|
32
|
-
# otherwise it may be
|
25
|
+
# otherwise it may be too late (e.g. when displaying help)
|
33
26
|
# examples:
|
34
27
|
# app_option '--log-level', 'LEVEL', 'Log level for log file output', :default => config.app[:log_level]:
|
35
28
|
# app_option ['-n', '--noop'], :flag, 'Run puppet in noop mode?', :default => false
|
@@ -37,6 +30,12 @@ module Kafo
|
|
37
30
|
self.kafo.class.app_option(*args)
|
38
31
|
end
|
39
32
|
|
33
|
+
# Returns whether the given app option exists. This is useful when there's a conditional option that is
|
34
|
+
# determined during boot; this helper can be used in later hooks to determine whether the option exists.
|
35
|
+
def app_option?(option)
|
36
|
+
self.kafo.config.app.key?(option.to_sym)
|
37
|
+
end
|
38
|
+
|
40
39
|
# examples:
|
41
40
|
# app_value(:log_level)
|
42
41
|
# note the dash to underscore convention
|
@@ -72,6 +71,14 @@ module Kafo
|
|
72
71
|
!mod.nil? && mod.enabled?
|
73
72
|
end
|
74
73
|
|
74
|
+
# Check if a module is present in the current configuration.
|
75
|
+
# examples:
|
76
|
+
# module_present?('example')
|
77
|
+
def module_present?(module_name)
|
78
|
+
mod = self.kafo.module(module_name)
|
79
|
+
!mod.nil?
|
80
|
+
end
|
81
|
+
|
75
82
|
# You can trigger installer exit by this method. You must specify exit code as a first
|
76
83
|
# argument. You can also specify a symbol alias which is built-in (see exit_handler.rb
|
77
84
|
# for more details).
|
@@ -93,14 +100,33 @@ module Kafo
|
|
93
100
|
self.kafo.config.set_custom(key, value)
|
94
101
|
end
|
95
102
|
|
103
|
+
# Load a custom fact from the custom fact storage as saved by store_custom_fact
|
104
|
+
def get_custom_fact(key)
|
105
|
+
self.kafo.config.get_custom_fact(key)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Store a any custom fact. This will show up as kafo.scenario.custom.your_fact.
|
109
|
+
# It is possible to use structures such as arrays and hashes besides the
|
110
|
+
# obvious ones such as strings, integers, booleans.
|
111
|
+
#
|
112
|
+
# These facts can also be used in Hiera hierachy definitions.
|
113
|
+
def store_custom_fact(key, value)
|
114
|
+
self.kafo.config.set_custom_fact(key, value)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Return the id of the current scenario
|
118
|
+
def scenario_id
|
119
|
+
self.kafo.config.scenario_id
|
120
|
+
end
|
121
|
+
|
96
122
|
# Return the path to the current scenario
|
97
123
|
def scenario_path
|
98
|
-
self.kafo.
|
124
|
+
self.kafo.config.config_file
|
99
125
|
end
|
100
126
|
|
101
127
|
# Return the actual data in the current scenario
|
102
128
|
def scenario_data
|
103
|
-
|
129
|
+
self.kafo.config.app
|
104
130
|
end
|
105
131
|
end
|
106
132
|
end
|
data/lib/kafo/kafo_configure.rb
CHANGED
@@ -26,8 +26,7 @@ require 'kafo/progress_bar'
|
|
26
26
|
require 'kafo/hooking'
|
27
27
|
require 'kafo/exit_handler'
|
28
28
|
require 'kafo/scenario_manager'
|
29
|
-
require 'kafo/
|
30
|
-
require 'kafo/puppet_configurer'
|
29
|
+
require 'kafo/execution_environment'
|
31
30
|
|
32
31
|
module Kafo
|
33
32
|
class KafoConfigure < Clamp::Command
|
@@ -424,33 +423,29 @@ module Kafo
|
|
424
423
|
def run_installation
|
425
424
|
self.class.hooking.execute(:pre)
|
426
425
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
puppetconf =
|
432
|
-
'color'
|
433
|
-
'evaltrace'
|
434
|
-
'
|
435
|
-
'
|
436
|
-
'
|
437
|
-
'show_diff' => true,
|
438
|
-
'environmentpath' => hiera.temp_dir,
|
426
|
+
execution_env = ExecutionEnvironment.new(config)
|
427
|
+
self.class.exit_handler.register_cleanup_path(execution_env.directory)
|
428
|
+
|
429
|
+
execution_env.store_answers
|
430
|
+
puppetconf = execution_env.configure_puppet(
|
431
|
+
'color' => false,
|
432
|
+
'evaltrace' => !!@progress_bar,
|
433
|
+
'noop' => !!noop?,
|
434
|
+
'profile' => !!profile?,
|
435
|
+
'show_diff' => true,
|
439
436
|
)
|
440
|
-
self.class.exit_handler.register_cleanup_path(puppetconf.config_path)
|
441
437
|
|
442
438
|
exit_code = 0
|
443
439
|
exit_status = nil
|
444
440
|
options = [
|
445
441
|
'--verbose',
|
446
442
|
'--debug',
|
447
|
-
'--trace',
|
448
443
|
'--detailed-exitcodes',
|
449
444
|
]
|
450
445
|
begin
|
451
446
|
command = PuppetCommand.new('include kafo_configure', options, puppetconf).command
|
452
447
|
log_parser = PuppetLogParser.new
|
453
|
-
PTY.spawn(command) do |stdin, stdout, pid|
|
448
|
+
PTY.spawn(*PuppetCommand.format_command(command)) do |stdin, stdout, pid|
|
454
449
|
begin
|
455
450
|
stdin.each do |line|
|
456
451
|
line = normalize_encoding(line)
|
data/lib/kafo/puppet_command.rb
CHANGED
@@ -6,8 +6,12 @@ module Kafo
|
|
6
6
|
@command = command
|
7
7
|
@puppet_config = puppet_config
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
if puppet_config
|
10
|
+
puppet_config['basemodulepath'] = modules_path.join(':')
|
11
|
+
@options = options.push("--config=#{puppet_config.config_path}")
|
12
|
+
else
|
13
|
+
@options = options.push("--modulepath #{modules_path.join(':')}")
|
14
|
+
end
|
11
15
|
@logger = KafoConfigure.logger
|
12
16
|
@puppet_version_check = !configuration.app[:skip_puppet_version_check]
|
13
17
|
@suffix = nil
|
@@ -31,12 +35,32 @@ module Kafo
|
|
31
35
|
end
|
32
36
|
|
33
37
|
def self.search_puppet_path(bin_name)
|
38
|
+
# Find the location of the puppet executable and use that to
|
39
|
+
# determine the path of all executables
|
34
40
|
bin_path = (::ENV['PATH'].split(File::PATH_SEPARATOR) + ['/opt/puppetlabs/bin']).find do |path|
|
35
|
-
File.executable?(File.join(path, bin_name))
|
41
|
+
File.executable?(File.join(path, 'puppet')) && File.executable?(File.join(path, bin_name))
|
36
42
|
end
|
37
43
|
File.join([bin_path, bin_name].compact)
|
38
44
|
end
|
39
45
|
|
46
|
+
def self.format_command(command)
|
47
|
+
if search_puppet_path('puppet').start_with?('/opt/puppetlabs')
|
48
|
+
[clean_env_vars, command, :unsetenv_others => true]
|
49
|
+
else
|
50
|
+
[::ENV, command, :unsetenv_others => false]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.clean_env_vars
|
55
|
+
# Cleaning ENV vars and keeping required vars only because,
|
56
|
+
# When using SCL it adds GEM_HOME and GEM_PATH ENV vars.
|
57
|
+
whitelisted_vars = %w[HOME USER LANG]
|
58
|
+
|
59
|
+
cleaned_env = ::ENV.select { |var| whitelisted_vars.include?(var) || var.start_with?('LC_') }
|
60
|
+
cleaned_env['PATH'] = '/sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin'
|
61
|
+
cleaned_env
|
62
|
+
end
|
63
|
+
|
40
64
|
private
|
41
65
|
|
42
66
|
def manifest
|
@@ -2,16 +2,12 @@ require 'tempfile'
|
|
2
2
|
|
3
3
|
module Kafo
|
4
4
|
class PuppetConfigurer
|
5
|
-
attr_reader :logger
|
5
|
+
attr_reader :logger, :config_path
|
6
6
|
|
7
|
-
def initialize(settings = {})
|
7
|
+
def initialize(config_path, settings = {})
|
8
|
+
@config_path = config_path
|
8
9
|
@settings = {'reports' => ''}.merge(settings)
|
9
10
|
@logger = KafoConfigure.logger
|
10
|
-
@temp_file = Tempfile.new(['kafo_puppet', '.conf'])
|
11
|
-
end
|
12
|
-
|
13
|
-
def config_path
|
14
|
-
@temp_file.path
|
15
11
|
end
|
16
12
|
|
17
13
|
def [](key)
|
@@ -23,15 +19,13 @@ module Kafo
|
|
23
19
|
end
|
24
20
|
|
25
21
|
def write_config
|
26
|
-
@logger.debug("Writing Puppet config file at #{
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
@logger.debug("Writing Puppet config file at #{config_path}")
|
23
|
+
File.open(config_path, 'w') do |file|
|
24
|
+
file.puts '[main]'
|
25
|
+
@settings.keys.sort.each do |key|
|
26
|
+
file.puts "#{key} = #{@settings[key]}"
|
27
|
+
end
|
32
28
|
end
|
33
|
-
ensure
|
34
|
-
@temp_file.close
|
35
29
|
end
|
36
30
|
end
|
37
31
|
end
|
data/lib/kafo/puppet_module.rb
CHANGED
@@ -160,7 +160,7 @@ module Kafo
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def default_params_path
|
163
|
-
"#{dir_name}/manifests/#{get_params_name}.pp"
|
163
|
+
"#{dir_name}/manifests/#{class_to_name(get_params_name)}.pp"
|
164
164
|
end
|
165
165
|
|
166
166
|
def default_manifest_name
|
@@ -179,5 +179,9 @@ module Kafo
|
|
179
179
|
name.gsub('/', '::')
|
180
180
|
end
|
181
181
|
|
182
|
+
def class_to_name(name)
|
183
|
+
name.gsub('::', '/')
|
184
|
+
end
|
185
|
+
|
182
186
|
end
|
183
187
|
end
|
@@ -19,7 +19,7 @@ module Kafo
|
|
19
19
|
content = YAML.load_file(scn_file)
|
20
20
|
if content.is_a?(Hash) && content.has_key?(:answer_file) && content.fetch(:enabled, true)
|
21
21
|
# add scenario name for legacy configs
|
22
|
-
content[:name] =
|
22
|
+
content[:name] = Configuration.get_scenario_id(scn_file) unless content.has_key?(:name)
|
23
23
|
scns[scn_file] = content
|
24
24
|
end
|
25
25
|
rescue Psych::SyntaxError => e
|
@@ -78,12 +78,19 @@ module Kafo
|
|
78
78
|
|
79
79
|
def scenario_from_args(arg_name='--scenario|-S')
|
80
80
|
# try scenario provided in the args via -S or --scenario
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
ARGV.each_with_index do |arg, index|
|
82
|
+
parsed = arg.match(/^(#{arg_name})($|=(?<scenario>\S+))/)
|
83
|
+
if parsed
|
84
|
+
scenario = parsed[:scenario] || ARGV[index + 1]
|
85
|
+
next unless scenario
|
86
|
+
|
87
|
+
scenario_file = File.join(config_dir, "#{scenario}.yaml")
|
88
|
+
return scenario_file if File.exist?(scenario_file)
|
89
|
+
fail_now("Scenario (#{scenario_file}) was not found, can not continue", :unset_scenario)
|
90
|
+
end
|
86
91
|
end
|
92
|
+
|
93
|
+
nil
|
87
94
|
end
|
88
95
|
|
89
96
|
def select_scenario
|
data/lib/kafo/version.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kafo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Hulan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
62
|
+
name: minitest-reporters
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
@@ -73,19 +73,19 @@ dependencies:
|
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
76
|
+
name: simplecov
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '0'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: kafo_wizards
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -149,6 +149,9 @@ dependencies:
|
|
149
149
|
- - ">="
|
150
150
|
- !ruby/object:Gem::Version
|
151
151
|
version: 0.6.2
|
152
|
+
- - "<"
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: 1.3.1
|
152
155
|
type: :runtime
|
153
156
|
prerelease: false
|
154
157
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -156,6 +159,9 @@ dependencies:
|
|
156
159
|
- - ">="
|
157
160
|
- !ruby/object:Gem::Version
|
158
161
|
version: 0.6.2
|
162
|
+
- - "<"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 1.3.1
|
159
165
|
- !ruby/object:Gem::Dependency
|
160
166
|
name: highline
|
161
167
|
requirement: !ruby/object:Gem::Requirement
|
@@ -239,7 +245,9 @@ files:
|
|
239
245
|
- lib/kafo/data_types/undef.rb
|
240
246
|
- lib/kafo/data_types/variant.rb
|
241
247
|
- lib/kafo/exceptions.rb
|
248
|
+
- lib/kafo/execution_environment.rb
|
242
249
|
- lib/kafo/exit_handler.rb
|
250
|
+
- lib/kafo/fact_writer.rb
|
243
251
|
- lib/kafo/help_builder.rb
|
244
252
|
- lib/kafo/help_builders/advanced.rb
|
245
253
|
- lib/kafo/help_builders/base.rb
|
@@ -256,7 +264,6 @@ files:
|
|
256
264
|
- lib/kafo/param_group.rb
|
257
265
|
- lib/kafo/parser_cache_reader.rb
|
258
266
|
- lib/kafo/parser_cache_writer.rb
|
259
|
-
- lib/kafo/password_manager.rb
|
260
267
|
- lib/kafo/progress_bar.rb
|
261
268
|
- lib/kafo/progress_bars/black_white.rb
|
262
269
|
- lib/kafo/progress_bars/colored.rb
|
@@ -283,6 +290,7 @@ files:
|
|
283
290
|
- modules/kafo_configure/spec/classes/init_spec.rb
|
284
291
|
- modules/kafo_configure/spec/fixtures/hiera/hiera.yaml
|
285
292
|
- modules/kafo_configure/spec/fixtures/hiera/test.yaml
|
293
|
+
- modules/kafo_configure/spec/fixtures/manifests/site.pp
|
286
294
|
- modules/kafo_configure/spec/fixtures/modules/dummy/manifests/init.pp
|
287
295
|
- modules/kafo_configure/spec/fixtures/modules/dummy/manifests/params.pp
|
288
296
|
- modules/kafo_configure/spec/functions/dump_lookups_spec.rb
|
@@ -308,8 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
308
316
|
- !ruby/object:Gem::Version
|
309
317
|
version: '0'
|
310
318
|
requirements: []
|
311
|
-
|
312
|
-
rubygems_version: 2.7.6
|
319
|
+
rubygems_version: 3.1.2
|
313
320
|
signing_key:
|
314
321
|
specification_version: 4
|
315
322
|
summary: A gem for making installations based on puppet user friendly
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'securerandom'
|
3
|
-
require 'digest/sha2'
|
4
|
-
require 'openssl'
|
5
|
-
require 'base64'
|
6
|
-
|
7
|
-
module Kafo
|
8
|
-
class PasswordManager
|
9
|
-
# generate a random password of lenght n
|
10
|
-
#
|
11
|
-
# on ruby >= 1.9 we use builtin method urlsafe_base64, on olders we use our own
|
12
|
-
# implementation (inspired by urlsafe_base64)
|
13
|
-
#
|
14
|
-
# the result may contain A-Z, a-z, 0-9, “-” and “_”. “=”
|
15
|
-
def password(n = 32)
|
16
|
-
return SecureRandom.urlsafe_base64(n) if SecureRandom.respond_to?(:urlsafe_base64)
|
17
|
-
|
18
|
-
s = [SecureRandom.random_bytes(n)].pack("m*")
|
19
|
-
s.delete!("\n")
|
20
|
-
s.tr!("+/", "-_")
|
21
|
-
s.delete!("=")
|
22
|
-
s
|
23
|
-
end
|
24
|
-
|
25
|
-
def aes_encrypt(text, passphrase)
|
26
|
-
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
|
27
|
-
cipher.encrypt
|
28
|
-
cipher.key = Digest::SHA2.hexdigest(passphrase)
|
29
|
-
cipher.iv = Digest::SHA2.hexdigest(passphrase + passphrase)
|
30
|
-
|
31
|
-
encrypted = cipher.update(text)
|
32
|
-
encrypted << cipher.final
|
33
|
-
Base64.encode64(encrypted)
|
34
|
-
end
|
35
|
-
|
36
|
-
def aes_decrypt(text, passphrase)
|
37
|
-
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
|
38
|
-
cipher.decrypt
|
39
|
-
cipher.key = Digest::SHA2.hexdigest(passphrase)
|
40
|
-
cipher.iv = Digest::SHA2.hexdigest(passphrase + passphrase)
|
41
|
-
|
42
|
-
decrypted = cipher.update(Base64.decode64(text))
|
43
|
-
decrypted << cipher.final
|
44
|
-
decrypted
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|