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.
@@ -6,14 +6,7 @@ module Kafo
6
6
  attr_reader :kafo
7
7
 
8
8
  def self.execute(kafo, &hook)
9
- # TODO can be removed in 0.6, is DEPRECATED since 0.5
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 to late (e.g. when displaying help)
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.class.scenario_manager.select_scenario
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
- YAML.load(File.read(scenario_path))
129
+ self.kafo.config.app
104
130
  end
105
131
  end
106
132
  end
@@ -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/hiera_configurer'
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
- hiera = HieraConfigurer.new(config.app[:hiera_config], config.modules, config.app[:order])
428
- hiera.write_configs
429
- self.class.exit_handler.register_cleanup_path(hiera.temp_dir)
430
-
431
- puppetconf = PuppetConfigurer.new(
432
- 'color' => false,
433
- 'evaltrace' => !!@progress_bar,
434
- 'hiera_config' => hiera.config_path,
435
- 'noop' => !!noop?,
436
- 'profile' => !!profile?,
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)
@@ -6,8 +6,12 @@ module Kafo
6
6
  @command = command
7
7
  @puppet_config = puppet_config
8
8
 
9
- @options = options.push("--modulepath #{modules_path.join(':')}")
10
- @options.push("--config=#{puppet_config.config_path}") if puppet_config
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 #{@temp_file.path}")
27
- @temp_file.open
28
- @temp_file.truncate(0)
29
- @temp_file.puts '[main]'
30
- @settings.keys.sort.each do |key|
31
- @temp_file.puts "#{key} = #{@settings[key]}"
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
@@ -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] = File.basename(scn_file, '.yaml') unless content.has_key?(: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
- parsed = ARGV.join(" ").match(/(#{arg_name})(\s+|[=]?)(\S+)/)
82
- if parsed
83
- scenario_file = File.join(config_dir, "#{parsed[3]}.yaml")
84
- return scenario_file if File.exist?(scenario_file)
85
- fail_now("Scenario (#{scenario_file}) was not found, can not continue", :unset_scenario)
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
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
  module Kafo
3
3
  PARSER_CACHE_VERSION = 1
4
- VERSION = "3.0.0"
4
+ VERSION = "5.0.1"
5
5
  end
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: 3.0.0
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: 2019-03-12 00:00:00.000000000 Z
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: simplecov
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: ci_reporter_minitest
76
+ name: simplecov
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '1.0'
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: '1.0'
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
- rubyforge_project:
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