kafo 3.0.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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