kafo 6.3.0 → 6.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d246040f3b21a35b8ec0091c61333fbd5b3ecc8af9fb7d6ed666de850a101bf9
4
- data.tar.gz: 9ab7731a6e46877cebfdffffbd7b06e5c11951821be90ff2743aa726c889c418
3
+ metadata.gz: 2224fcf87240686b6638ceffdde5ea8026baf151e784f90f1903389305996ae8
4
+ data.tar.gz: c6ea88ba2845dfa6d34281c78f7f4a70073c9f6a7bb971f97a0a8cdc7e2897d8
5
5
  SHA512:
6
- metadata.gz: fb5d804b5c587646b9576f4ba6a67c9b0bd3702ddfad877750beb81b61710fd5b104db0fe36b7cf1cfd1f286d1548fb5b48acb9b778652df6c075600176df88d
7
- data.tar.gz: 406667aac6a714122c3ec8d00a90ec630843bd6939167f23142e94bf465be51c8e098380815e869be64af9090b726a2e6a368542e18137a4fdb2493a52ed6246
6
+ metadata.gz: 373d68b4cc0c8ee1e43e991c4eea2bd632f3de482d797fde26156b38975ee4eef8b0a4cd0cc934ed8c3d9b341e7a429df57b2077496710ed8f187890b1186669
7
+ data.tar.gz: f7d9a1356a7f260fa7baa605642c6c00d6276a9064330a03f2864561427ba0eeb99947daae84d951f9647798fac8870c7517fb9b3dd7e3330e4778d5a7975ca0
data/README.md CHANGED
@@ -493,6 +493,39 @@ as key:value.
493
493
  When parsing the value, the first colon divides key and value. All other
494
494
  colons are ignored.
495
495
 
496
+ ## Sensitive arguments
497
+
498
+ Puppet's `Sensitive` data type can be used as long as it's configured in Hiera
499
+ too. Given the following manifest:
500
+
501
+ ```puppet
502
+ class example (
503
+ Sensitive[String[1]] $password,
504
+ ) {
505
+ ```
506
+
507
+ Here the following Hiera configuration is needed:
508
+ ```yaml
509
+ lookup_options:
510
+ example::password:
511
+ convert_to: "Sensitive"
512
+ ```
513
+
514
+ This is based on [Puppet's documentation](https://puppet.com/docs/puppet/6/securing-sensitive-data.html).
515
+
516
+ Note that to provide a default inside the manifest inheritance must be used.
517
+
518
+ ```puppet
519
+ class example (
520
+ Sensitive[String[1]] $password = $example::params::password,
521
+ ) inherits example::params {
522
+ }
523
+
524
+ class example::params {
525
+ $password = Sensitive('supersecret')
526
+ }
527
+ ```
528
+
496
529
  ## Default values
497
530
 
498
531
  Default values for parameters are read from the class definitions in the
@@ -816,6 +849,32 @@ if app_value(:reset_foreman_db) && !app_value(:noop)
816
849
  end
817
850
  ```
818
851
 
852
+ Hooks can additionally be defined by combining all related stages into a single file
853
+ known as a Multi-stage hook. Multi-stage hooks live in a special directory inside
854
+ the hooks directory: ```$installer_dir/hooks/multi```. Taking the previous example:
855
+
856
+ ```ruby
857
+ # hooks/multi/10-reset_option_feature.rb
858
+ boot do
859
+ app_option '--reset-foreman-db', :flag, 'Drop foreman database first? You will lose all data!', :default => false
860
+ end
861
+
862
+ pre do
863
+ if app_value(:reset_foreman_db) && !app_value(:noop)
864
+ `which foreman-rake > /dev/null 2>&1`
865
+ if $?.success?
866
+ logger.info 'Dropping database!'
867
+ output = `foreman-rake db:drop 2>&1`
868
+ logger.debug output.to_s
869
+ unless $?.success?
870
+ logger.warn "Unable to drop DB, ignoring since it's not fatal, output was: '#{output}''"
871
+ end
872
+ else
873
+ logger.warn 'Foreman not installed yet, can not drop database!'
874
+ end
875
+ end
876
+ end
877
+ ```
819
878
 
820
879
  If you want to add more directories to be search you can use the "hook_dirs" option
821
880
  in the installer configuration file.
@@ -130,7 +130,7 @@ module Kafo
130
130
  def modules
131
131
  @modules ||= begin
132
132
  register_data_types
133
- @data.keys.map { |mod| PuppetModule.new(mod, PuppetModule.find_parser, self).parse }.sort
133
+ @data.keys.map { |mod| PuppetModule.new(mod, configuration: self).parse }.sort
134
134
  end
135
135
  end
136
136
 
@@ -159,7 +159,7 @@ module Kafo
159
159
  end
160
160
 
161
161
  def add_module(name)
162
- mod = PuppetModule.new(name, PuppetModule.find_parser, self).parse
162
+ mod = PuppetModule.new(name, configuration: self).parse
163
163
  unless modules.map(&:name).include?(mod.name)
164
164
  mod.enable
165
165
  @modules << mod
@@ -130,4 +130,4 @@ require 'kafo/data_types/struct'
130
130
  require 'kafo/data_types/tuple'
131
131
  require 'kafo/data_types/type_reference'
132
132
  require 'kafo/data_types/undef'
133
- require 'kafo/data_types/variant'
133
+ require 'kafo/data_types/wrapped_data_type'
@@ -10,7 +10,7 @@ module Kafo
10
10
  @logger = KafoConfigure.logger
11
11
  @types = {}
12
12
  manifest.each_line do |line|
13
- if (type = TYPE_DEFINITION.match(line))
13
+ if (type = TYPE_DEFINITION.match(line.force_encoding("UTF-8")))
14
14
  @types[type[1]] = type[2]
15
15
  end
16
16
  end
@@ -7,7 +7,7 @@ module Kafo
7
7
  def_delegators :@inner_type, :condition_value, :dump_default, :multivalued?, :typecast, :valid?
8
8
 
9
9
  def initialize
10
- @inner_type = DataTypes::Variant.new('Integer', 'Float', 'String', 'Boolean', 'Regexp')
10
+ @inner_type = DataTypes::WrappedDataType.new('Integer', 'Float', 'String', 'Boolean', 'Regexp')
11
11
  end
12
12
  end
13
13
 
@@ -1,6 +1,6 @@
1
1
  module Kafo
2
2
  module DataTypes
3
- class Variant < DataType
3
+ class WrappedDataType < DataType
4
4
  def initialize(*inner_types)
5
5
  @inner_types = inner_types.map { |t| DataType.new_from_string(t) }
6
6
  end
@@ -16,7 +16,7 @@ module Kafo
16
16
  end
17
17
 
18
18
  def multivalued?
19
- @inner_types.any? { |t| t.multivalued? }
19
+ @inner_types.any?(&:multivalued?)
20
20
  end
21
21
 
22
22
  def to_s
@@ -33,7 +33,7 @@ module Kafo
33
33
  if type
34
34
  type.valid?(value, errors)
35
35
  else
36
- errors << "#{value} is not one of #{to_s}"
36
+ errors << "#{value} is not one of #{self}"
37
37
  false
38
38
  end
39
39
  end
@@ -45,6 +45,7 @@ module Kafo
45
45
  end
46
46
  end
47
47
 
48
- DataType.register_type('Variant', Variant)
48
+ DataType.register_type('Sensitive', WrappedDataType)
49
+ DataType.register_type('Variant', WrappedDataType)
49
50
  end
50
51
  end
@@ -14,10 +14,9 @@ module Kafo
14
14
  end
15
15
 
16
16
  def self.wrapper
17
- # Ruby 2.0 doesn't have <<~ heredocs
18
- <<-WRAPPER
19
- require 'yaml'
20
- Facter.add(:kafo) { setcode { YAML.load_file(File.join(__dir__, '#{DATA_FILENAME}')) } }
17
+ <<~WRAPPER
18
+ require 'yaml'
19
+ Facter.add(:kafo) { setcode { YAML.load_file(File.join(__dir__, '#{DATA_FILENAME}')) } }
21
20
  WRAPPER
22
21
  end
23
22
  end
@@ -34,8 +34,8 @@ module Kafo
34
34
  #
35
35
  # @example
36
36
  # app_option ['-n', '--noop'], :flag, 'Run puppet in noop mode?', :default => false
37
- def app_option(*args)
38
- self.kafo.class.app_option(*args)
37
+ def app_option(*args, &block)
38
+ self.kafo.class.app_option(*args, &block)
39
39
  end
40
40
 
41
41
  # Returns whether the given app option exists. This is useful when there's a conditional option that is
data/lib/kafo/hooking.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'kafo/hook_context'
2
+ require 'kafo/multi_stage_hook'
2
3
 
3
4
  module Kafo
4
5
  class Hooking
@@ -36,6 +37,14 @@ module Kafo
36
37
  register(hook_type, file, &hook_block)
37
38
  end
38
39
  end
40
+
41
+ # Multi stage hooks are special
42
+ Dir.glob(File.join(base_dir, 'multi', '*.rb')).sort.each do |file|
43
+ logger.debug "Loading multi stage hook #{file}"
44
+ hook = File.read(file)
45
+ MultiStageHook.new(file, self, TYPES).instance_eval(hook, file, 1)
46
+ end
47
+
39
48
  @loaded = true
40
49
  end
41
50
  self
@@ -525,8 +525,8 @@ module Kafo
525
525
  @progress_bar.update(line) if @progress_bar
526
526
  end
527
527
  rescue Errno::EIO # we reach end of input
528
- exit_status = PTY.check(pid, true) if PTY.respond_to?(:check) # ruby >= 1.9.2
529
- if exit_status.nil? # process is still running or we have old ruby so we don't know
528
+ exit_status = PTY.check(pid, true)
529
+ if exit_status.nil? # process is still running
530
530
  begin
531
531
  Process.wait(pid)
532
532
  rescue Errno::ECHILD # process could exit meanwhile so we rescue
@@ -535,7 +535,7 @@ module Kafo
535
535
  end
536
536
  end
537
537
  end
538
- rescue PTY::ChildExited => e # could be raised by Process.wait on older ruby or by PTY.check
538
+ rescue PTY::ChildExited => e # could be raised by PTY.check
539
539
  self.class.exit_handler.exit_code = e.status.exitstatus
540
540
  end
541
541
 
@@ -564,11 +564,7 @@ module Kafo
564
564
  end
565
565
 
566
566
  def normalize_encoding(line)
567
- if line.respond_to?(:encode) && line.respond_to?(:valid_encoding?)
568
- line.valid_encoding? ? line : line.encode('UTF-16be', :invalid => :replace, :replace => '?').encode('UTF-8')
569
- else # Ruby 1.8.7, doesn't worry about invalid encodings
570
- line
571
- end
567
+ line.valid_encoding? ? line : line.encode('UTF-16be', :invalid => :replace, :replace => '?').encode('UTF-8')
572
568
  end
573
569
  end
574
570
  end
data/lib/kafo/logger.rb CHANGED
@@ -13,7 +13,13 @@ module Kafo
13
13
 
14
14
  def log(level, *args, &block)
15
15
  if Logging.buffering?
16
- Logging.to_buffer(@name, level, args, &block)
16
+ if block_given?
17
+ data = yield
18
+ else
19
+ data = args
20
+ end
21
+
22
+ Logging.to_buffer(@name, ::Logging::LogEvent.new(@name, ::Logging::LEVELS[level.to_s], data, false))
17
23
  else
18
24
  Logging.dump_buffer if Logging.dump_needed?
19
25
  @logger.send(level, *args, &block)
data/lib/kafo/logging.rb CHANGED
@@ -118,7 +118,7 @@ module Kafo
118
118
 
119
119
  def dump_buffer
120
120
  @buffer.each do |log|
121
- ::Logging.logger[log[0]].send(log[1], *([log[2]].flatten(2)), &log[3])
121
+ ::Logging.logger[log[0]].send(:log_event, log[1])
122
122
  end
123
123
  @buffer.clear
124
124
  end
@@ -0,0 +1,13 @@
1
+ module Kafo
2
+ class MultiStageHook
3
+ def initialize(name, registry, types)
4
+ default_name = name
5
+
6
+ types.each do |hook_type|
7
+ self.class.send(:define_method, hook_type) do |name=nil, &block|
8
+ registry.send(:register, hook_type, name || default_name, &block)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -25,7 +25,7 @@ module Kafo
25
25
  end
26
26
  end
27
27
 
28
- def initialize(identifier, parser = self.class.find_parser, configuration = KafoConfigure.config)
28
+ def initialize(identifier, parser: nil, configuration: KafoConfigure.config)
29
29
  @identifier = identifier
30
30
  @configuration = configuration
31
31
  @name = get_name
@@ -65,6 +65,7 @@ module Kafo
65
65
  def parse(builder_klass = ParamBuilder)
66
66
  @raw_data = @parser_cache.get(identifier, manifest_path) if @parser_cache
67
67
  if @raw_data.nil?
68
+ @parser = self.class.find_parser if @parser.nil?
68
69
  if @parser.nil? || @parser == :none
69
70
  raise ParserError.new("No Puppet module parser is installed and no cache of the file #{manifest_path} is available. Please check debug logs and install optional dependencies for the parser.")
70
71
  else
@@ -80,7 +81,7 @@ module Kafo
80
81
 
81
82
  self
82
83
  rescue ConfigurationException => e
83
- @logger.fatal "Unable to continue because of: #{e.message}"
84
+ @logger.fatal "Unable to parse #{manifest_path} because of: #{e.message}"
84
85
  KafoConfigure.exit(:manifest_error)
85
86
  end
86
87
 
data/lib/kafo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
  module Kafo
3
3
  PARSER_CACHE_VERSION = 1
4
- VERSION = "6.3.0"
4
+ VERSION = "6.5.0"
5
5
  end
@@ -10,6 +10,13 @@ Puppet::Functions.create_function(:'kafo_configure::dump_lookups') do
10
10
  end
11
11
 
12
12
  def dump_lookups(parameters)
13
- Hash[parameters.map { |param| [param, call_function('lookup', [param], 'default_value' => nil)] }]
13
+ Hash[parameters.map { |param| [param, lookup(param)] }]
14
+ end
15
+
16
+ private
17
+
18
+ def lookup(param)
19
+ value = call_function('lookup', [param], 'default_value' => nil)
20
+ value.respond_to?(:unwrap) ? value.unwrap : value
14
21
  end
15
22
  end
@@ -8,6 +8,12 @@ Puppet::Functions.create_function(:'kafo_configure::dump_variables') do
8
8
 
9
9
  def dump_variables(variables)
10
10
  scope = closure_scope
11
- Hash[variables.map { |var| [var, scope[var]] }]
11
+ Hash[variables.map { |var| [var, unwrap(scope[var])] }]
12
+ end
13
+
14
+ private
15
+
16
+ def unwrap(value)
17
+ value.respond_to?(:unwrap) ? value.unwrap : value
12
18
  end
13
19
  end
@@ -2,3 +2,8 @@
2
2
  classes:
3
3
  - dummy
4
4
  my_module::param: override
5
+ my_module::password: batteryhorsestaple
6
+
7
+ lookup_options:
8
+ my_module::password:
9
+ convert_to: "Sensitive"
@@ -1,5 +1,6 @@
1
1
  class dummy (
2
2
  String $first = $dummy::params::first,
3
3
  Optional[Integer] $second = undef,
4
+ Sensitive[String[1]] $password = $dummy::params::password,
4
5
  ) inherits dummy::params {
5
6
  }
@@ -1,3 +1,4 @@
1
1
  class dummy::params {
2
2
  $first = 'foo'
3
+ $password = Sensitive('supersecret')
3
4
  }
@@ -4,4 +4,5 @@ describe 'kafo_configure::dump_lookups' do
4
4
  let(:hiera_config) { 'spec/fixtures/hiera/hiera.yaml' }
5
5
  it { is_expected.to run.with_params([]).and_return({}) }
6
6
  it { is_expected.to run.with_params(['my_module::param']).and_return({'my_module::param' => 'override'}) }
7
+ it { is_expected.to run.with_params(['my_module::password']).and_return({'my_module::password' => 'batteryhorsestaple'}) }
7
8
  end
@@ -6,5 +6,6 @@ describe 'kafo_configure::dump_variables' do
6
6
  context 'with values' do
7
7
  let(:pre_condition) { 'include dummy' }
8
8
  it { is_expected.to run.with_params(['dummy::first']).and_return({'dummy::first' => 'foo'}) }
9
+ it { is_expected.to run.with_params(['dummy::password']).and_return({'dummy::password' => 'supersecret'}) }
9
10
  end
10
11
  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: 6.3.0
4
+ version: 6.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marek Hulan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-25 00:00:00.000000000 Z
11
+ date: 2022-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -245,7 +245,7 @@ files:
245
245
  - lib/kafo/data_types/tuple.rb
246
246
  - lib/kafo/data_types/type_reference.rb
247
247
  - lib/kafo/data_types/undef.rb
248
- - lib/kafo/data_types/variant.rb
248
+ - lib/kafo/data_types/wrapped_data_type.rb
249
249
  - lib/kafo/exceptions.rb
250
250
  - lib/kafo/execution_environment.rb
251
251
  - lib/kafo/exit_handler.rb
@@ -262,6 +262,7 @@ files:
262
262
  - lib/kafo/logging.rb
263
263
  - lib/kafo/migration_context.rb
264
264
  - lib/kafo/migrations.rb
265
+ - lib/kafo/multi_stage_hook.rb
265
266
  - lib/kafo/param.rb
266
267
  - lib/kafo/param_builder.rb
267
268
  - lib/kafo/param_group.rb
@@ -319,7 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
320
  - !ruby/object:Gem::Version
320
321
  version: '0'
321
322
  requirements: []
322
- rubygems_version: 3.1.4
323
+ rubygems_version: 3.2.22
323
324
  signing_key:
324
325
  specification_version: 4
325
326
  summary: A gem for making installations based on puppet user friendly