kafo 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +56 -98
  3. data/Rakefile +12 -1
  4. data/lib/kafo/color_scheme.rb +3 -3
  5. data/lib/kafo/configuration.rb +5 -7
  6. data/lib/kafo/data_types/aliases.rb +0 -10
  7. data/lib/kafo/data_types/not_undef.rb +2 -0
  8. data/lib/kafo/data_types/optional.rb +2 -0
  9. data/lib/kafo/hiera_configurer.rb +50 -22
  10. data/lib/kafo/hook_context.rb +3 -2
  11. data/lib/kafo/kafo_configure.rb +9 -8
  12. data/lib/kafo/logger.rb +2 -2
  13. data/lib/kafo/param.rb +6 -20
  14. data/lib/kafo/param_builder.rb +1 -8
  15. data/lib/kafo/progress_bar.rb +1 -1
  16. data/lib/kafo/puppet_command.rb +4 -21
  17. data/lib/kafo/puppet_module.rb +2 -13
  18. data/lib/kafo/scenario_manager.rb +6 -6
  19. data/lib/kafo/version.rb +1 -1
  20. data/modules/kafo_configure/Rakefile +1 -0
  21. data/modules/kafo_configure/lib/puppet/functions/{dump_lookups.rb → kafo_configure/dump_lookups.rb} +2 -1
  22. data/modules/kafo_configure/lib/puppet/functions/kafo_configure/dump_variables.rb +13 -0
  23. data/modules/kafo_configure/lib/puppet/functions/kafo_configure/to_yaml.rb +15 -0
  24. data/modules/kafo_configure/manifests/dump_values.pp +11 -12
  25. data/modules/kafo_configure/manifests/init.pp +7 -5
  26. data/modules/kafo_configure/manifests/puppet_version_semver.pp +1 -1
  27. data/modules/kafo_configure/metadata.json +15 -0
  28. data/modules/kafo_configure/spec/classes/dump_values_spec.rb +24 -0
  29. data/modules/kafo_configure/spec/classes/init_spec.rb +17 -0
  30. data/modules/kafo_configure/spec/fixtures/hiera/hiera.yaml +7 -0
  31. data/modules/kafo_configure/spec/fixtures/hiera/test.yaml +4 -0
  32. data/modules/kafo_configure/spec/fixtures/modules/dummy/manifests/init.pp +5 -0
  33. data/modules/kafo_configure/spec/fixtures/modules/dummy/manifests/params.pp +3 -0
  34. data/modules/kafo_configure/spec/functions/dump_lookups_spec.rb +7 -0
  35. data/modules/kafo_configure/spec/functions/dump_variables_spec.rb +10 -0
  36. data/modules/kafo_configure/spec/functions/to_yaml_spec.rb +5 -0
  37. data/modules/kafo_configure/spec/spec_helper.rb +5 -0
  38. metadata +48 -35
  39. data/lib/kafo/params/password.rb +0 -60
  40. data/lib/kafo/validator.rb +0 -122
  41. data/modules/kafo_configure/lib/puppet/parser/functions/decrypt.rb +0 -16
  42. data/modules/kafo_configure/lib/puppet/parser/functions/dump_values.rb +0 -13
  43. data/modules/kafo_configure/lib/puppet/parser/functions/foreman_to_yaml.rb +0 -13
  44. data/modules/kafo_configure/lib/puppet/parser/functions/load_kafo_password.rb +0 -13
  45. data/modules/kafo_configure/manifests/puppet_version_versioncmp.pp +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bb73eb4c71ae5aad0d0c3dc4b891a0ef33af1c8a
4
- data.tar.gz: a63a799798654d67bc245630d0f95cc52b379b64
2
+ SHA256:
3
+ metadata.gz: e35b389c721abe577314b02199940ac88fa9777c9a3daa0d0b1bda886082ea0b
4
+ data.tar.gz: f92d08ac63cd96cf98b6b0f6a60b22c97d4cdd66b7e482ab3556b9654659a50b
5
5
  SHA512:
6
- metadata.gz: 819bf86e16679ab8fbc15015bf8562cd415ad9f854ceb031503facf9f6dcd0ea1e978071c69de011e7e9b68bb9a8d20a56bc92ac73ed4e96407e2669c253cef1
7
- data.tar.gz: 9e82f85dabf51876b18f8306de913ac93342c3b0ce4ad257dbde7f65ada6de27fcaf529abe870c843f66c1fdf28900181bbb3d2e338482d9d07c7c46a3718386
6
+ metadata.gz: 26426722b8088cd909266123492b328e686829fe798a4f02cabdd2483fc0e1a1360fcc77b535f86fa7f7e6a176b986779089a409ec37c0d4de93134b0861ee1b
7
+ data.tar.gz: d48254980b31a24d331cf3450d19d19bd0d62a529c8daedc9164dae01327ba4ec058b6171536cb632e811cacedd45c178ceafc388488e434a423f3e36d3bacc2
data/README.md CHANGED
@@ -160,15 +160,13 @@ As you may have noticed there are several ways how to specify arguments. Here's
160
160
 
161
161
  ## Requirements
162
162
 
163
- Kafo is supported with Puppet versions 3 and 4. Puppet 2 is no longer supported
164
- in current versions, use an older version of Kafo or update Puppet.
165
-
166
- Puppet may be installed as a gem (add it to Gemfile) or through a package,
167
- including official AIO packages.
163
+ Kafo is supported with Puppet versions 4.9+, 5 and 6. Puppet may be installed
164
+ as a gem (add it to Gemfile) or through a package, including official AIO
165
+ packages.
168
166
 
169
167
  ## How do I report bugs or contribute?
170
168
 
171
- You can find our redmine issue tracker [here](http://projects.theforeman.org/projects/kafo),
169
+ You can find our redmine issue tracker [here](https://projects.theforeman.org/projects/kafo),
172
170
  you can use your github account for logging in. When reporting new issues please
173
171
  don't forget to specify your:
174
172
  * puppet version
@@ -179,10 +177,10 @@ don't forget to specify your:
179
177
  Since Kafo is a side project of Foreman you can use its IRC channels to
180
178
  contact us on freenode. #theforeman is the channel for generic discussions
181
179
  and #theforeman-dev is reserved only for technical topics. Likewise you can use the Foreman
182
- mailing lists on googlegroups. For more information see [this page](http://theforeman.org/support.html)
180
+ mailing lists on googlegroups. For more information see [this page](https://theforeman.org/support.html)
183
181
 
184
182
  Patches are always welcome. You can use instructions for Foreman, just
185
- substitute Foreman with Kafo. More details are [here](http://projects.theforeman.org/projects/foreman/wiki/Contribute#New-Way-github)
183
+ substitute Foreman with Kafo. More details are [here](https://projects.theforeman.org/projects/foreman/wiki/Contribute#New-Way-github)
186
184
 
187
185
  # Advanced topics
188
186
 
@@ -445,8 +443,8 @@ the particular parameter belongs.
445
443
 
446
444
  ## Argument types
447
445
 
448
- When using Puppet 4 or newer, the data type will be read from the parameter
449
- list and defaults to Puppet's [Any](https://docs.puppet.com/puppet/latest/reference/lang_data_abstract.html#any)
446
+ The data type will be read from the parameter list and defaults to Puppet's
447
+ [Any](https://docs.puppet.com/puppet/latest/reference/lang_data_abstract.html#any)
450
448
  data type, which Kafo handles as a basic string with no validation.
451
449
 
452
450
  If more specific data types, such as `Optional[Array[2]]` or similar are
@@ -460,21 +458,6 @@ class example (
460
458
  ) {
461
459
  ```
462
460
 
463
- When using Puppet 3, data types can be specified in the manifest documentation
464
- rather than the parameter list, like this:
465
-
466
- ```puppet
467
- # $param:: Some documentation for param
468
- type:Array[String]
469
- ```
470
-
471
- For compatibility with older Kafo releases, additional types are supported:
472
- string, boolean, integer, array, password, hash. These are equivalent to their
473
- Puppet 4 namesakes, plus wrapped in `Optional[..]` to permit `undef`.
474
-
475
- If the data type is given in both the manifest documentation and the parameter
476
- list, then the manifest documentation will be preferred.
477
-
478
461
  Note that all arguments that are nil (have no value in answers.yaml or you
479
462
  set them UNDEF (see below)) are translated to ```undef``` in puppet.
480
463
 
@@ -484,48 +467,6 @@ of DataType which implement validation and typecasting. This can be added to a
484
467
 
485
468
  Kafo::DataType.register_type('YourType', Kafo::DataType::YourType)
486
469
 
487
- ## Password arguments
488
-
489
- Kafo supports password arguments. It's adding some level of protection for your
490
- passwords. Usually people generate random strings for passwords. However all
491
- values are stored in config/answers.yaml which may introduce a security risk.
492
-
493
- If this is something to consider for you, you can use the password type (see
494
- Argument types for more info how to define parameter type). It will
495
- generate a secure (random) password with a length of 32 chars and encrypts
496
- it using AES 256 in CBC mode. It uses a passphrase that is stored in
497
- config/kafo.yaml so if anyone gets an access to this file, he can read all
498
- the passwords from the answers.yaml, too. A random password is generated and stored
499
- if there is none in kafo.yaml yet.
500
-
501
- When Kafo runs puppet, puppet will read this password from config/kafo.yaml.
502
- It runs under the same user so it should have read access by default. The Kafo
503
- puppet module also provides a function that you can use to decrypt such
504
- parameters. You can use it like this
505
-
506
- ```erb
507
- password: <%= scope.function_decrypt([scope.lookupvar("::foreman::db_password"))]) -%>
508
- ```
509
-
510
- Also you can take advantage of already encrypted passwords and store since it is
511
- (encrypted). Your application can decrypt it as long as it knows the
512
- passphrase. The passphrase can be obtained from $kafo_configure::password.
513
-
514
- Note that we use a bit extraordinary form of encrypted passwords. All our
515
- encrypted passwords look like "$1$base64encodeddata". As you can see we
516
- use the $1$ as prefix by which we can detect that it is our specially encrypted password.
517
- The form has nothing common with Modular Crypt Format. Also our AES output
518
- is base64 encoded. To get a password from this format you can do something
519
- like this in your application
520
-
521
- ```ruby
522
- require 'base64'
523
- encrypted = "$1$base64encodeddata"
524
- encrypted = encrypted[3..-1] # strip $1$ prefix
525
- encrypted = Base64.decode64(encrypted) # decode base64 string
526
- result = aes_decrypt(encrypted) # for example how to implement aes_decrypt see lib/kafo/password_manager.rb
527
- ```
528
-
529
470
  ## Array arguments
530
471
 
531
472
  Some arguments may be Arrays. If you want to specify array values you can
@@ -582,9 +523,11 @@ class foreman::params {
582
523
  }
583
524
  ```
584
525
 
585
- If no inline default is given in the manifest and on Puppet 4.5+, then Kafo will
586
- attempt to look up a default value using [data stored in the module](https://docs.puppet.com/puppet/latest/lookup_quick_module.html). This can be specified with Hiera data files (or even a data function) in the
587
- module under `data/`.
526
+ If no inline default is given in the manifest, then Kafo will attempt to look
527
+ up a default value using [data stored in the
528
+ module](https://docs.puppet.com/puppet/latest/lookup_quick_module.html). This
529
+ can be specified with Hiera data files (or even a data function) in the module
530
+ under `data/`.
588
531
 
589
532
  ## Resetting an argument
590
533
 
@@ -681,7 +624,6 @@ $db_type is not set 'mysql'. Let's look at following example
681
624
  # == Parameters:
682
625
  #
683
626
  # $use_db:: use database?
684
- # type:boolean
685
627
  #
686
628
  # == Database parameters: condition: $use_db
687
629
  #
@@ -690,7 +632,6 @@ $db_type is not set 'mysql'. Let's look at following example
690
632
  # === MySQL: condition: $database_type == 'mysql'
691
633
  #
692
634
  # $remote:: use remote connection
693
- # type:boolean
694
635
  # $host server to connect to
695
636
  # condition: $remote
696
637
  # $socket server to connect to
@@ -754,18 +695,8 @@ If you use "params_path" for this purpose, "params_name" is ignored.
754
695
 
755
696
  ## Validations
756
697
 
757
- If you specify validations of parameters in your init.pp manifest they
758
- will be replaced with your values even before Puppet is run. In order to do this
759
- you must follow a few rules however:
760
-
761
- * you must use standard validation functions (e.g. validate_array, validate_re, ...)
762
-
763
- These functions are re-implemented in Kafo from common stdlib functions, so please
764
- contribute any missing ones.
765
-
766
698
  If class parameters are declared with Puppet 4 data types then Kafo will
767
- validate user inputs against Puppet's type validation rules, which should
768
- replace the use of separate validation functions.
699
+ validate user inputs against Puppet's type validation rules.
769
700
 
770
701
  ## Enabling or disabling module
771
702
 
@@ -1083,26 +1014,53 @@ being managed by Kafo. Set a custom Hiera config file in Kafo's config with:
1083
1014
  :hiera_config: /usr/share/kafo/hiera.yaml
1084
1015
  ```
1085
1016
 
1086
- The contents of this file are as per the [hiera.yaml docs](https://docs.puppet.com/hiera/latest/configuring.html),
1087
- but hierarchy should contain the item `kafo_answers` and the `yaml` backend
1088
- should be enabled. Kafo will add these if they're missing.
1017
+ The contents of this file are as per the
1018
+ [hiera.yaml docs](https://docs.puppet.com/hiera/latest/configuring.html).
1019
+ Only Hiera version 5 is supported.
1089
1020
 
1090
- When running Puppet, Kafo will copy the Hiera config and YAML data directory to
1091
- a temporary location to include its data. The file `kafo_answers.yaml` will be
1092
- generated containing _all_ default and overriden values for parameters managed
1093
- by Kafo. This may change in the future to allow a more complex hierarchy. As an
1094
- example, a hierarchy could be set up with:
1021
+ When running Puppet, Kafo will copy the Hiera config to a temporary location.
1022
+ Relative data directories will be changed to absolute paths. A
1023
+ `kafo_answers.yaml` file will be generated containing _all_ default and
1024
+ overriden values for parameters managed by Kafo. This may change in the future
1025
+ to allow a more complex hierarchy.
1026
+
1027
+ The hierarchy can contain a special value with the name `Kafo Answers`. The
1028
+ exact values will be rewritten by Kafo, but it can be used to determine when
1029
+ the Kafo answers are loaded. Note the name is case sensitive. When it's
1030
+ missing, it will be added.
1031
+
1032
+ As an example, a hierarchy could be set up with:
1095
1033
 
1096
1034
  ```yaml
1097
- :hierarchy:
1098
- - kafo_answers
1099
- - "%{::osfamily}"
1100
- - common
1035
+ hierarchy:
1036
+ - name: "Kafo Answers"
1037
+ - name: "Other YAML hierarchy levels"
1038
+ paths:
1039
+ - "family/%{facts.os.family}.yaml"
1040
+ - "common.yaml"
1041
+ ```
1042
+
1043
+ It is possible to include another file above answers:
1044
+
1045
+ ```yaml
1046
+ hierarchy:
1047
+ - name: "Custom values"
1048
+ datadir: "custom"
1049
+ path: "override.yaml"
1050
+ - name: "Kafo Answers"
1051
+ - name: "Other YAML hierarchy levels"
1052
+ datadir: "data"
1053
+ paths:
1054
+ - "family/%{facts.os.family}.yaml"
1055
+ - "common.yaml"
1101
1056
  ```
1102
1057
 
1103
1058
  This would give precedence to all Kafo-managed parameter values, but for any
1104
1059
  others, would check for values per OS family, followed by a `common.yaml` file.
1105
1060
 
1061
+ [Migration from Hiera version 3](https://puppet.com/docs/puppet/4.9/hiera_migrate_v3_yaml.html)
1062
+ is documented by Puppet.
1063
+
1106
1064
  ## Exit code
1107
1065
 
1108
1066
  Kafo can terminate either before or after puppet is run. If it is run with
@@ -1130,14 +1088,14 @@ Other exit codes that can be returned:
1130
1088
 
1131
1089
  ## Running Puppet Profiling
1132
1090
 
1133
- As of Puppet 3.2, performance data can be gathered during a puppet run by adding the `--profile` option. See [Tune Puppet for Performance with Profiler](https://puppetlabs.com/blog/tune-puppet-performance-profiler) for more information from the Puppet team. Users who wish to perform a Kafo run and gather this type of profiling data to analyze can pass the same option to their installer. The profiling data will then be present in the normal Kafo logs.
1091
+ Performance data can be gathered during a Puppet run by adding the `--profile` option. See [Tune Puppet for Performance with Profiler](https://puppet.com/blog/tune-puppet-for-performance-profiler) for more information from the Puppet team. Users who wish to perform a Kafo run and gather this type of profiling data to analyze can pass the same option to their installer. The profiling data will then be present in the normal Kafo logs.
1134
1092
 
1135
1093
  ## Issue tracker
1136
1094
 
1137
1095
  Issues are tracked in Redmine, see:
1138
1096
 
1139
- * [Open Kafo issues](http://projects.theforeman.org/projects/kafo/issues/)
1140
- * [File new issue](http://projects.theforeman.org/projects/kafo/issues/new)
1097
+ * [Open Kafo issues](https://projects.theforeman.org/projects/kafo/issues/)
1098
+ * [File new issue](https://projects.theforeman.org/projects/kafo/issues/new)
1141
1099
 
1142
1100
  ## Related projects
1143
1101
 
data/Rakefile CHANGED
@@ -14,6 +14,17 @@ Rake::TestTask.new('test:acceptance') do |t|
14
14
  t.verbose = true
15
15
  end
16
16
 
17
+ namespace 'test' do
18
+ desc 'Run Puppet module tests'
19
+ task :puppet_modules do
20
+ Dir['modules/*'].each do |mod|
21
+ Dir.chdir(mod) do
22
+ `rake release_checks`
23
+ end
24
+ end
25
+ end
26
+ end
27
+
17
28
  CLEAN.include 'test/tmp'
18
29
 
19
- task :test => ['test:unit', 'test:acceptance']
30
+ task :test => ['test:unit', 'test:acceptance', 'test:puppet_modules']
@@ -13,8 +13,8 @@ module Kafo
13
13
  end
14
14
 
15
15
  def setup
16
+ HighLine.color_scheme = build_color_scheme
16
17
  if @colors
17
- HighLine.color_scheme = build_color_scheme
18
18
  HighLine.use_color = true
19
19
  else
20
20
  HighLine.use_color = false
@@ -25,8 +25,8 @@ module Kafo
25
25
 
26
26
  def build_color_scheme
27
27
  HighLine::ColorScheme.new do |cs|
28
- color_hash.keys.each do |key|
29
- cs[key] = color_hash[key]
28
+ color_hash.each do |key, value|
29
+ cs[key] = value
30
30
  end
31
31
  end
32
32
  end
@@ -2,7 +2,6 @@
2
2
  require 'yaml'
3
3
  require 'tmpdir'
4
4
  require 'kafo/puppet_module'
5
- require 'kafo/password_manager'
6
5
  require 'kafo/color_scheme'
7
6
  require 'kafo/data_type_parser'
8
7
  require 'kafo/puppet_configurer'
@@ -42,7 +41,7 @@ module Kafo
42
41
  @answer_file = app[:answer_file]
43
42
  begin
44
43
  @data = load_yaml_file(@answer_file)
45
- rescue Errno::ENOENT => e
44
+ rescue Errno::ENOENT
46
45
  puts "No answer file at #{@answer_file} found, can not continue"
47
46
  KafoConfigure.exit(:no_answer_file)
48
47
  end
@@ -72,12 +71,11 @@ module Kafo
72
71
  @app ||= begin
73
72
  begin
74
73
  configuration = load_yaml_file(@config_file)
75
- rescue => e
74
+ rescue
76
75
  configuration = {}
77
76
  end
78
77
 
79
78
  result = DEFAULT.merge(configuration || {})
80
- result[:password] ||= PasswordManager.new.password
81
79
  result[:module_dirs] = result[:modules_dir] || result[:module_dirs]
82
80
  result.delete(:modules_dir)
83
81
  result
@@ -139,7 +137,7 @@ module Kafo
139
137
  def migrate_configuration(from_config, options={})
140
138
  keys_to_skip = options.fetch(:skip, [])
141
139
  keys = [:log_dir, :log_name, :log_level, :no_prefix,
142
- :colors, :color_of_background, :custom, :password, :verbose_log_level]
140
+ :colors, :color_of_background, :custom, :verbose_log_level]
143
141
  keys += options.fetch(:with, [])
144
142
  keys.each do |key|
145
143
  next if keys_to_skip.include?(key)
@@ -201,7 +199,7 @@ EOS
201
199
 
202
200
  def config_header
203
201
  files = [app[:config_header_file], File.join(gem_root, '/config/config_header.txt')].compact
204
- file = files.select { |f| File.exists?(f) }.first
202
+ file = files.find { |f| File.exist?(f) }
205
203
  @config_header ||= file.nil? ? '' : File.read(file)
206
204
  end
207
205
 
@@ -209,7 +207,7 @@ EOS
209
207
  filename = file || answer_file
210
208
  FileUtils.touch filename
211
209
  File.chmod 0600, filename
212
- File.open(filename, 'w') { |file| file.write(config_header + format(YAML.dump(data))) }
210
+ File.open(filename, 'w') { |f| f.write(config_header + format(YAML.dump(data))) }
213
211
  end
214
212
 
215
213
  def params
@@ -1,14 +1,4 @@
1
- require 'kafo/data_type'
2
-
3
1
  module Kafo
4
2
  DataType.register_type('Data', 'Any')
5
3
  DataType.register_type('Default', 'Enum["default"]')
6
-
7
- # pre-Puppet 4 Kafo data types
8
- DataType.register_type('array', 'Optional[Array]')
9
- DataType.register_type('boolean', 'Optional[Boolean]')
10
- DataType.register_type('hash', 'Optional[Hash]')
11
- DataType.register_type('integer', 'Optional[Integer]')
12
- DataType.register_type('password', 'Optional[String]')
13
- DataType.register_type('string', 'Optional[String]')
14
4
  end
@@ -10,7 +10,9 @@ module Kafo
10
10
  def initialize(inner_type_or_value)
11
11
  begin
12
12
  @inner_type = DataType.new_from_string(inner_type_or_value)
13
+ @inner_value = nil
13
14
  rescue ConfigurationException
15
+ @inner_type = nil
14
16
  @inner_value = inner_type_or_value
15
17
  end
16
18
  end
@@ -10,7 +10,9 @@ module Kafo
10
10
  def initialize(inner_type_or_value)
11
11
  begin
12
12
  @inner_type = DataType.new_from_string(inner_type_or_value)
13
+ @inner_value = nil
13
14
  rescue ConfigurationException
15
+ @inner_type = nil
14
16
  @inner_value = inner_type_or_value
15
17
  end
16
18
  end
@@ -3,6 +3,9 @@ require 'tmpdir'
3
3
 
4
4
  module Kafo
5
5
  class HieraConfigurer
6
+ HIERARCHY_NAME = 'Kafo Answers'
7
+ HIERARCHY_FILENAME = 'kafo_answers.yaml'
8
+
6
9
  attr_reader :temp_dir, :config_path, :data_dir, :logger
7
10
 
8
11
  def initialize(user_config_path, modules, modules_order)
@@ -13,17 +16,13 @@ module Kafo
13
16
  end
14
17
 
15
18
  def write_configs
16
- @temp_dir = Dir.mktmpdir('kafo_hiera')
17
- @config_path = File.join(temp_dir, 'hiera.conf')
18
- @data_dir = File.join(temp_dir, 'data')
19
+ build_temp_dir
19
20
 
20
21
  if @user_config_path
21
22
  logger.debug("Merging existing Hiera config file from #{@user_config_path}")
22
23
  user_config = YAML.load(File.read(@user_config_path))
23
- user_data_dir = user_config[:yaml][:datadir] if user_config[:yaml]
24
24
  else
25
25
  user_config = {}
26
- user_data_dir = false
27
26
  end
28
27
  logger.debug("Writing Hiera config file to #{config_path}")
29
28
  File.open(config_path, 'w') do |f|
@@ -31,15 +30,10 @@ module Kafo
31
30
  f.write(format_yaml_symbols(generate_config(user_config).to_yaml))
32
31
  end
33
32
 
34
- if user_data_dir
35
- logger.debug("Copying Hiera data files from #{user_data_dir} to #{data_dir}")
36
- FileUtils.cp_r(user_data_dir, data_dir)
37
- else
38
- logger.debug("Creating Hiera data files in #{data_dir}")
39
- FileUtils.mkdir(data_dir)
40
- end
33
+ logger.debug("Creating Hiera data files in #{data_dir}")
34
+ FileUtils.mkdir(data_dir)
41
35
 
42
- File.open(File.join(data_dir, 'kafo_answers.yaml'), 'w') do |f|
36
+ File.open(File.join(data_dir, HIERARCHY_FILENAME), 'w') do |f|
43
37
  f.write(format_yaml_symbols(generate_data(@modules).to_yaml))
44
38
  end
45
39
  end
@@ -47,17 +41,33 @@ module Kafo
47
41
  def generate_config(config = {})
48
42
  config ||= {}
49
43
 
50
- # ensure YAML is enabled
51
- config[:backends] ||= []
52
- config[:backends] << 'yaml' unless config[:backends].include?('yaml')
44
+ config['version'] = 5
53
45
 
54
- # ensure kafo_answers is present and most specific
55
- config[:hierarchy] ||= []
56
- config[:hierarchy].unshift('kafo_answers') unless config[:hierarchy].include?('kafo_answers')
46
+ # ensure there are defaults
47
+ config['defaults'] ||= {}
48
+ config['defaults']['datadir'] = determine_data_dir_path(config['defaults']['datadir'])
49
+ config['defaults']['data_hash'] ||= 'yaml_data'
57
50
 
58
- # use our copy of the data dir
59
- config[:yaml] ||= {}
60
- config[:yaml][:datadir] = data_dir
51
+ # ensure our answers file is present and has the right settings
52
+ config['hierarchy'] ||= []
53
+
54
+ config['hierarchy'].each do |level|
55
+ if level['datadir']
56
+ level['datadir'] = determine_data_dir_path(level['datadir'])
57
+ end
58
+ end
59
+
60
+ kafo_answers = config['hierarchy'].find { |level| level['name'] == HIERARCHY_NAME }
61
+ if kafo_answers
62
+ kafo_answers.clear
63
+ else
64
+ kafo_answers = {}
65
+ config['hierarchy'].unshift(kafo_answers)
66
+ end
67
+ kafo_answers['name'] = HIERARCHY_NAME
68
+ kafo_answers['path'] = HIERARCHY_FILENAME
69
+ kafo_answers['datadir'] = data_dir
70
+ kafo_answers['data_hash'] = 'yaml_data'
61
71
 
62
72
  config
63
73
  end
@@ -76,8 +86,26 @@ module Kafo
76
86
  (order & modules) + (modules - order)
77
87
  end
78
88
 
89
+ def build_temp_dir
90
+ @temp_dir ||= Dir.mktmpdir('kafo_hiera')
91
+ @config_path = File.join(temp_dir, 'hiera.conf')
92
+ @data_dir = File.join(temp_dir, 'data')
93
+ end
94
+
95
+ private
96
+
79
97
  def format_yaml_symbols(data)
80
98
  data.gsub('!ruby/sym ', ':')
81
99
  end
100
+
101
+ def determine_data_dir_path(path)
102
+ # Relies on data_dir being absolute or having a user config
103
+ path ||= data_dir
104
+ Pathname.new(path).relative? ? File.join(original_hiera_directory, path) : path
105
+ end
106
+
107
+ def original_hiera_directory
108
+ @user_config_path ? File.dirname(@user_config_path) : nil
109
+ end
82
110
  end
83
111
  end