hieracles 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c2b378bf82fee62a7577b514281f9ed47af9886
4
- data.tar.gz: 6af4a764f1138d3e274b5f72752d2602f32d3966
3
+ metadata.gz: d9b3915635847cd54b684b61feca924b9d11df20
4
+ data.tar.gz: 52c52b2b41f67079a635e8b092727c8478841ba7
5
5
  SHA512:
6
- metadata.gz: 64d4bd38c3e9859edd3c2583180f640fc318eae6f0dfbcf336f38d22b0b4ede390a1589f6c2d9b7b81c73f66ca5c85872015ec3f1dcd498b13937c2d023ef55e
7
- data.tar.gz: 3f1e85e5a9dd5e726e1542be700c7a7e2838e017ee32bfff962d02b43985900956b0e7db50c95a7c0465dc5b9fba2691829de34c1a1c831e666f0d7a4f103380
6
+ metadata.gz: 5f84fcf5cf3c49774c8fb7f6b6a025674c6e2b11173b65e66e75fa2bf0994274f9a8c096d5a7b5d5a7f8741d90193dc0394ec9852392aae7362d0a2a7a9effd4
7
+ data.tar.gz: 0ccd90fa9677651c2a75eb05eb427155321d18961594959d11eec87523353dfce36fafc697651dc3c0af18409e64c2ce3993f81676ab5d6c97ce3dd44770c6fe
data/CHANGELOG.md CHANGED
@@ -1,9 +1,16 @@
1
1
  Hieracles Changelog
2
2
  =======================
3
3
 
4
+ ### 0.1.6 - 2015-11-18
5
+ - add dependency on `deep-merge` gem like hiera does
6
+ - take in account the `merge_behavior` in hiera file
7
+ - make possible to use `%{::variables}` from puppet scope
8
+ but this is a temporary implementation,
9
+ only works for top level variables
10
+
4
11
  ### 0.1.5 - 2015-11-15
5
12
  - add `interactive` new option `-i` for having
6
- CLI user promtped to fill up missing scope vars
13
+ CLI user prompted to fill up missing scope vars
7
14
  - implement interpolation adapted from the code of hiera
8
15
  - fixed the single option parsing for `-i`
9
16
 
@@ -27,7 +34,7 @@ Hieracles Changelog
27
34
  - display full local path in params output
28
35
  - add an option to display version
29
36
  - fix yaml output for true and false cases
30
- - added a simple filter fetaure for yaml format,
37
+ - added a simple filter feature for yaml format,
31
38
  but it only matches like a 'start_with'
32
39
 
33
40
  ### 0.0.6 - 2015-09-21
data/README.md CHANGED
@@ -8,12 +8,16 @@ Hieracles
8
8
  [![Dependency Status](https://img.shields.io/gemnasium/Gandi/hieracles.svg)](https://gemnasium.com/Gandi/hieracles)
9
9
  [![Code Climate](https://img.shields.io/codeclimate/github/Gandi/hieracles.svg)](https://codeclimate.com/github/Gandi/hieracles)
10
10
 
11
- Hieracles is a command-line tool for analysis and deep examination of [Hiera][hiera] paramaters in a [Puppet][puppet] setup. It's used internally at [Gandi][gandi] and its first incarnation is strongly tied to Gandi puppet architecture. But Hieracles tends to become, in time, a generic Hiera overlay visualisation tool.
11
+ Hieracles is a command-line tool for analysis and deep examination of [Hiera][hiera] parameters in a [Puppet][puppet] setup. It can be used to quickly visualize, from a local puppet (typically on a developers environment), all the Hiera params related to a specific node.
12
+
13
+ It's used internally at [Gandi][gandi] and its first incarnation is strongly tied to Gandi puppet architecture. But Hieracles tends to become, in time, a generic Hiera overlay visualization tool.
14
+
15
+ Have a look at the [Changelog](CHANGELOG.md) for details about the evolution.
12
16
 
13
17
  Prerequisite
14
18
  ---------------
15
19
 
16
- There are many ways to setup puppet and use hiera. This tool is designed to match a certain kind of setup, including:
20
+ There are many ways to setup puppet and use Hiera. This tool is designed to match a certain kind of setup, including:
17
21
 
18
22
  - an [external node classifier (ENC)][enc]
19
23
  - a yaml hiera datastore
@@ -139,17 +143,38 @@ Otherwise
139
143
 
140
144
  Debian packaging
141
145
  --------------------
142
- On a Jessie
143
146
 
144
- apt-get install gem2deb ruby-coveralls ruby-all-dev ruby-rspec ruby-rspec-expectations
147
+ A debian/ dir is included you can just use `sbuild` in here and it will build the .deb.
145
148
 
146
- Then build
149
+ For new releases:
147
150
 
148
- gem2deb -p hieracles hieracles
151
+ - update the debian/changelog file
152
+
153
+ FreeBSD packaging
154
+ --------------------
149
155
 
150
- and install
156
+ For new releases:
157
+
158
+ - update the Makefile with new version number
159
+ - in a FreeBSD jail or machine:
160
+ ```
161
+ cd hieracles
162
+ git pull
163
+ cd ports/
164
+ make makesum
165
+ # test the stuff, get that there is no warning or what
166
+ portlint
167
+ make stage
168
+ make check-orphans
169
+ make package
170
+ make install
171
+ make deinstall
172
+ make clean
173
+ cd ..
174
+ shar `find rubygem-hieracles` > rubygem-hieracles.shar
175
+ ```
176
+ - on https://bugs.freebsd.org submit the new version
151
177
 
152
- dpkg -i hieracles_0.0.6-1_all.deb
153
178
 
154
179
  Todo
155
180
  --------------
@@ -166,7 +191,7 @@ Todo
166
191
 
167
192
  Authors
168
193
  -----------
169
- Hieracles original code is writen by [@mose](https://github.com/mose).
194
+ Hieracles original code is written by [@mose](https://github.com/mose).
170
195
 
171
196
  License
172
197
  -----------
data/hc.1 CHANGED
@@ -13,8 +13,11 @@ hc \- Command tool for Hieracles
13
13
  .SH DESCRIPTION
14
14
  .PP
15
15
  Hieracles is a command-line tool for analysis and deep examination
16
- of [Hiera][hiera] parameters in a [Puppet][puppet] setup. It's used
17
- internally at Gandi and its first incarnation is strongly
16
+ of Hiera parameters in a Puppet setup. It can be used to quickly
17
+ visualize, from a local puppet (typically on a developers
18
+ environment), all the Hiera params related to a specific node.
19
+ .PP
20
+ It's used internally at Gandi and its first incarnation is strongly
18
21
  tied to Gandi puppet architecture. But Hieracles tends to become, in
19
22
  time, a generic Hiera overlay visualization tool.
20
23
  .PP
data/hieracles.gemspec CHANGED
@@ -77,6 +77,8 @@ Gem::Specification.new do |spec|
77
77
  spec.test_files = spec.files.grep(%r{^spec/})
78
78
  spec.require_paths = ["lib"]
79
79
 
80
+ spec.add_dependency 'deep_merge'
81
+
80
82
  spec.add_development_dependency "bundler", "~> 1.7"
81
83
  spec.add_development_dependency "rake", "~> 10.0"
82
84
  spec.add_development_dependency 'rspec', "~> 3.0"
@@ -15,8 +15,7 @@ module Hieracles
15
15
  def load(options)
16
16
  @optionfile = options[:config] || defaultconfig
17
17
  @extraparams = extract_params(options[:params])
18
- initconfig(@optionfile) unless File.exist? @optionfile
19
- values = YAML.load_file(@optionfile)
18
+ values = get_config(@optionfile)
20
19
  @server = values['server']
21
20
  @classpath = values['classpath']
22
21
  @modulepath = values['modulepath'] || 'modules'
@@ -30,6 +29,11 @@ module Hieracles
30
29
  @interactive = options[:interactive] || values['interactive']
31
30
  end
32
31
 
32
+ def get_config(file)
33
+ initconfig(file) unless File.exist? file
34
+ values = YAML.load_file(file)
35
+ end
36
+
33
37
  def initconfig(file)
34
38
  FileUtils.mkdir_p(File.dirname(file))
35
39
  File.open(file, 'w') do |f|
@@ -52,7 +52,7 @@ module Hieracles
52
52
  def build_params_line(key, value, filter)
53
53
  output = ''
54
54
  if !filter || Regexp.new(filter).match(key)
55
- first = value.shift
55
+ first = value.pop
56
56
  filecolor_index = @colors[first[:file]]
57
57
  filecolor = COLORS[filecolor_index]
58
58
  output << format("#{filecolor} #{COLORS[5]} %s\n",
@@ -61,7 +61,7 @@ module Hieracles
61
61
  first[:value].to_s.gsub('%', '%%')
62
62
  )
63
63
  while value.count > 0
64
- overriden = value.shift
64
+ overriden = value.pop
65
65
  filecolor_index = @colors[overriden[:file]]
66
66
  output << format(" #{COLORS[8]}\n",
67
67
  "[#{filecolor_index}] #{key} #{overriden[:value]}"
@@ -28,11 +28,11 @@ module Hieracles
28
28
  def build_params_line(key, value, filter)
29
29
  output = ''
30
30
  if !filter || Regexp.new(filter).match(key)
31
- first = value.shift
31
+ first = value.pop
32
32
  output << make_csv(in_what_file(first[:file]) +
33
33
  [key, first[:value].to_s, '0'])
34
34
  while value.count > 0
35
- overriden = value.shift
35
+ overriden = value.pop
36
36
  output << make_csv(in_what_file(overriden[:file]) +
37
37
  [key, overriden[:value].to_s, '1'])
38
38
  end
@@ -39,11 +39,11 @@ module Hieracles
39
39
  def build_params_line(key, value, filter)
40
40
  output = ''
41
41
  if !filter || Regexp.new(filter).match(key)
42
- first = value.shift
42
+ first = value.pop
43
43
  filecolor_index = @index[first[:file]]
44
44
  output << "[#{filecolor_index}] #{key} #{first[:value]}\n"
45
45
  while value.count > 0
46
- overriden = value.shift
46
+ overriden = value.pop
47
47
  filecolor_index = @index[overriden[:file]]
48
48
  output << " [#{filecolor_index}] #{key} #{overriden[:value]}\n"
49
49
  end
@@ -91,7 +91,12 @@ module Hieracles
91
91
  def added(output, key, leaf, params)
92
92
  output += leaf.to_s
93
93
  if params["#{key.join('.')}"]
94
- output += " # " + params[key.join('.')][0][:file]
94
+ params["#{key.join('.')}"].each do |k|
95
+ if k[:value].to_s == leaf.to_s
96
+ output += " # " + k[:file]
97
+ break
98
+ end
99
+ end
95
100
  end
96
101
  output
97
102
  end
@@ -26,5 +26,14 @@ module Hieracles
26
26
  hierarchy.join(',').scan(/%\{(?:::)?([^\}]*)\}/).flatten.uniq
27
27
  end
28
28
 
29
+ def merge_behavior
30
+ case @loaded[:merge_behavior]
31
+ when :deep,'deep',:deeper,'deeper'
32
+ @loaded[:merge_behavior].to_sym
33
+ else
34
+ :native
35
+ end
36
+ end
37
+
29
38
  end
30
39
  end
@@ -2,22 +2,43 @@ module Hieracles
2
2
  module Interpolate
3
3
 
4
4
  def parse(data, values, interactive = false)
5
- data.gsub(/%\{(?:(scope|hiera|literal|alias) *)?([^\}]*)\}/) do |match|
5
+ data.gsub(/%\{(?:(scope|hiera|literal|alias)\(['"])?(?:::)?([^\}"']*)(?:["']\))?\}/) do |match|
6
6
  if interactive && !values[$2.to_sym]
7
- puts
8
- puts "#{match} is not defined."
9
- puts "Is it missing in your ENC source?"
10
- puts "Maybe you should define a default value for that scope variable in your config file?"
11
- puts "Do you want to provide a temmporary value? [input value]"
12
- print "#{$2} = "
13
- val = $stdin.gets.chomp
14
- values[$2.to_sym] = val
15
- val
7
+ values[$2.to_sym] = ask_about($2)
8
+ values[$2.to_sym]
16
9
  else
17
10
  values[$2.to_sym]
18
11
  end
19
12
  end
20
13
  end
21
14
 
15
+ def ask_about(var)
16
+ @@output.puts
17
+ @@output.puts "'#{var}' is not defined."
18
+ @@output.puts "Is it missing in your ENC source?"
19
+ @@output.puts "Maybe you should define a default value for that scope variable in your config file?"
20
+ @@output.puts "Do you want to provide a temmporary value? [input value]"
21
+ @@output.print "#{var} = "
22
+ @@input.gets.chomp
23
+ end
24
+
25
+ # makes possible to set input and output
26
+ def setio(input, output)
27
+ @@input = input
28
+ @@output = output
29
+ end
30
+
31
+ private
32
+
33
+ # defaults to STDIN
34
+ def input
35
+ @@input ||= STDIN
36
+ end
37
+
38
+ # defaults to STDOUT
39
+ def output
40
+ @@output ||= STDOUT
41
+ end
42
+
22
43
  end
23
44
  end
@@ -1,6 +1,7 @@
1
1
  require "net/http"
2
2
  require "uri"
3
3
  require "yaml"
4
+ require 'deep_merge'
4
5
 
5
6
  module Hieracles
6
7
  class Node
@@ -47,7 +48,7 @@ module Hieracles
47
48
 
48
49
  def params(without_common = true)
49
50
  params = {}
50
- files(without_common).each do |f|
51
+ files(without_common).reverse.each do |f|
51
52
  data = YAML.load_file(File.join(Config.basepath, f))
52
53
  if data
53
54
  s = to_shallow_hash(data)
@@ -63,12 +64,9 @@ module Hieracles
63
64
 
64
65
  def params_tree(without_common = true)
65
66
  params = {}
66
- paths(without_common).each do |f|
67
- data = YAML.load_file(f)
68
- if data
69
- # data needs interpolation
70
- deep_merge!(params, data)
71
- end
67
+ paths(without_common).reverse.each do |f|
68
+ data = YAML.load_file(f) || {}
69
+ merge_trees params, data
72
70
  end
73
71
  deep_sort(params)
74
72
  end
@@ -116,5 +114,16 @@ module Hieracles
116
114
  modules
117
115
  end
118
116
 
117
+ def merge_trees(left, right)
118
+ case @hiera.merge_behavior
119
+ when :deeper
120
+ left.deep_merge!(right)
121
+ when :deep
122
+ left.deep_merge(right)
123
+ else # Native and undefined
124
+ local_merge!(left, right)
125
+ end
126
+ end
127
+
119
128
  end
120
129
  end
@@ -19,12 +19,12 @@ module Hieracles
19
19
  keys = key.to_s.split('.').reverse
20
20
  leaf_key = keys.shift
21
21
  key_hash = keys.reduce(leaf_key.to_sym => value) { |h, k| { k.to_sym => h } }
22
- deep_merge!(a, key_hash)
22
+ local_merge!(a, key_hash)
23
23
  a
24
24
  end
25
25
  end
26
26
 
27
- def deep_merge!(hash1, hash2)
27
+ def local_merge!(hash1, hash2)
28
28
  merger = proc { |key, v1, v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &merger) : v2 }
29
29
  hash1.merge!(hash2, &merger)
30
30
  end
@@ -1 +1,9 @@
1
1
  somefarmparam: false
2
+ another:
3
+ more_sublevel: something
4
+ sublevel:
5
+ array:
6
+ - one
7
+ - two
8
+ - three
9
+
@@ -3,3 +3,6 @@ common_param:
3
3
  another:
4
4
  sublevel:
5
5
  thing: always
6
+ array:
7
+ - four
8
+ - five
@@ -54,8 +54,8 @@ describe Hieracles::Formats::Console do
54
54
 
55
55
  describe ".build_params_line" do
56
56
  let(:expected) {
57
- "\e[31m[0]\e[0m \e[36mparams.this.var\e[0m value1\n"+
58
- " \e[97m[1] params.this.var value2\e[0m\n"
57
+ "\e[32m[1]\e[0m \e[36mparams.this.var\e[0m value2\n"+
58
+ " \e[97m[0] params.this.var value1\e[0m\n"
59
59
  }
60
60
  let(:params) {
61
61
  [
@@ -51,8 +51,8 @@ describe Hieracles::Formats::Csv do
51
51
 
52
52
  describe ".build_params_line" do
53
53
  let(:expected) {
54
- "1;0;params.this.var;value1;0\n"+
55
- "0;1;params.this.var;value2;1\n"
54
+ "0;1;params.this.var;value2;0\n"+
55
+ "1;0;params.this.var;value1;1\n"
56
56
  }
57
57
  let(:params) {
58
58
  [
@@ -54,8 +54,8 @@ describe Hieracles::Formats::Plain do
54
54
 
55
55
  describe ".build_params_line" do
56
56
  let(:expected) {
57
- "[0] params.this.var value1\n"+
58
- " [1] params.this.var value2\n"
57
+ "[1] params.this.var value2\n"+
58
+ " [0] params.this.var value1\n"
59
59
  }
60
60
  let(:params) {
61
61
  [
@@ -127,7 +127,7 @@ describe Hieracles::Formats::Yaml do
127
127
  {
128
128
  'key' => [{
129
129
  file: 'what/file',
130
- value: 'value'
130
+ value: 'true'
131
131
  }]
132
132
  }
133
133
  }
@@ -144,7 +144,7 @@ describe Hieracles::Formats::Yaml do
144
144
  {
145
145
  'key' => [{
146
146
  file: 'what/file',
147
- value: 'value'
147
+ value: 'false'
148
148
  }]
149
149
  }
150
150
  }
@@ -161,7 +161,7 @@ describe Hieracles::Formats::Yaml do
161
161
  {
162
162
  'key' => [{
163
163
  file: 'what/file',
164
- value: 'value'
164
+ value: '3'
165
165
  }]
166
166
  }
167
167
  }
@@ -178,7 +178,7 @@ describe Hieracles::Formats::Yaml do
178
178
  {
179
179
  'key' => [{
180
180
  file: 'what/file',
181
- value: 'value'
181
+ value: '0.3'
182
182
  }]
183
183
  }
184
184
  }
@@ -308,6 +308,43 @@ describe Hieracles::Formats::Yaml do
308
308
  }
309
309
  it { expect(yaml_format.mergetree('', [], input, params)).to eq expected }
310
310
  end
311
+ context "with a 3-levels double string key-value and override" do
312
+ let(:params) {
313
+ {
314
+ 'key.sublevel.subsublevel' => [{
315
+ file: 'what/file',
316
+ value: 'value'
317
+ }],
318
+ 'key2.sublevel' => [
319
+ {
320
+ file: 'what/file2',
321
+ value: 'value'
322
+ },
323
+ {
324
+ file: 'what/file1',
325
+ value: 'value2'
326
+ }
327
+ ]
328
+ }
329
+ }
330
+ let(:input) {
331
+ {
332
+ 'key' => {
333
+ 'sublevel' => {
334
+ 'subsublevel' => 'value'
335
+ }
336
+ },
337
+ 'key2' => {
338
+ 'sublevel' => 'value2'
339
+ }
340
+ }
341
+ }
342
+ let(:expected) {
343
+ "\nkey: \n sublevel: \n subsublevel: value # what/file" +
344
+ "\nkey2: \n sublevel: value2 # what/file1"
345
+ }
346
+ it { expect(yaml_format.mergetree('', [], input, params)).to eq expected }
347
+ end
311
348
  end
312
349
 
313
350
  end
@@ -1,58 +1,208 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Hieracles::Node do
4
- let(:options) {
5
- {
6
- config: 'spec/files/config.yml',
7
- hierafile: 'hiera.yaml',
8
- encpath: 'enc',
9
- basepath: 'spec/files'
4
+ context "with native merge" do
5
+ let(:options) {
6
+ {
7
+ config: 'spec/files/config.yml',
8
+ hierafile: 'hiera.yaml',
9
+ encpath: 'enc',
10
+ basepath: 'spec/files'
11
+ }
10
12
  }
11
- }
12
13
 
13
- context "when extra parameters are specified" do
14
- describe '.new' do
15
- let(:extraoptions) {
16
- options.merge({ params: 'key1=value1;key2=value2' })
17
- }
18
- let(:node) { Hieracles::Node.new 'server.example.com', extraoptions }
19
- let(:expected) {
20
- {
21
- classes: ['dev'],
22
- fqdn: 'server.example.com',
23
- country: 'fr',
24
- datacenter: 'equinix',
25
- farm: 'dev',
26
- key1: 'value1',
27
- key2: 'value2'
14
+ context "when extra parameters are specified" do
15
+ describe '.new' do
16
+ let(:extraoptions) {
17
+ options.merge({ params: 'key1=value1;key2=value2' })
28
18
  }
29
- }
30
- it { expect(node).to be_a Hieracles::Node }
31
- it { expect(node.hiera_params).to eq expected }
19
+ let(:node) { Hieracles::Node.new 'server.example.com', extraoptions }
20
+ let(:expected) {
21
+ {
22
+ classes: ['dev'],
23
+ fqdn: 'server.example.com',
24
+ country: 'fr',
25
+ datacenter: 'equinix',
26
+ farm: 'dev',
27
+ key1: 'value1',
28
+ key2: 'value2'
29
+ }
30
+ }
31
+ it { expect(node).to be_a Hieracles::Node }
32
+ it { expect(node.hiera_params).to eq expected }
33
+ end
32
34
  end
33
- end
34
35
 
35
- context "when parameters are not valid" do
36
- let(:node) { Hieracles::Node.new 'server_not_there.example.com', options }
37
- it { expect{ node }.to raise_error(RuntimeError) }
38
- end
36
+ context "when parameters are not valid" do
37
+ let(:node) { Hieracles::Node.new 'server_not_there.example.com', options }
38
+ it { expect{ node }.to raise_error(RuntimeError) }
39
+ end
39
40
 
40
- context "when parameters are valid" do
41
- let(:node) { Hieracles::Node.new 'server.example.com', options }
41
+ context "when parameters are valid" do
42
+ let(:node) { Hieracles::Node.new 'server.example.com', options }
42
43
 
43
- describe '.new' do
44
- let(:expected) {
45
- {
44
+ describe '.new' do
45
+ let(:expected) {
46
+ {
47
+ classes: ['dev'],
48
+ fqdn: 'server.example.com',
49
+ country: 'fr',
50
+ datacenter: 'equinix',
51
+ farm: 'dev'
52
+ }
53
+ }
54
+ it { expect(node).to be_a Hieracles::Node }
55
+ it { expect(node.hiera_params).to eq expected }
56
+ end
57
+
58
+ describe '.files' do
59
+ let(:expected) {
60
+ [
61
+ 'params/nodes/server.example.com.yaml',
62
+ 'params/farm/dev.yaml'
63
+ ]
64
+ }
65
+ it { expect(node.files).to eq expected }
66
+ end
67
+
68
+ describe '.paths' do
69
+ let(:expected) {
70
+ [
71
+ File.join(node.hiera.datapath, 'nodes/server.example.com.yaml'),
72
+ File.join(node.hiera.datapath, 'farm/dev.yaml')
73
+ ]
74
+ }
75
+ it { expect(node.paths).to eq expected }
76
+ end
77
+
78
+ describe '.params' do
79
+ let(:expected) {
80
+ [
81
+ [ "another.more_sublevel",
82
+ [{
83
+ value: "something",
84
+ file: 'params/farm/dev.yaml'
85
+ }]
86
+ ],
87
+ [ "another.sublevel.array",
88
+ [
89
+ {
90
+ value: ["one", "two", "three"],
91
+ file: 'params/farm/dev.yaml'
92
+ },
93
+ {
94
+ value: ["four", "five"],
95
+ file: 'params/nodes/server.example.com.yaml'
96
+ }
97
+ ]
98
+ ],
99
+ [ "another.sublevel.thing",
100
+ [{
101
+ value: "always",
102
+ file: 'params/nodes/server.example.com.yaml'
103
+ }]
104
+ ],
105
+ [ "common_param.subparam",
106
+ [{
107
+ value: "overriden",
108
+ file: 'params/nodes/server.example.com.yaml'
109
+ }]
110
+ ],
111
+ [ "somefarmparam",
112
+ [{
113
+ value: false,
114
+ file: 'params/farm/dev.yaml'
115
+ }]
116
+ ]
117
+ ]
118
+ }
119
+ it { expect(node.params).to eq expected }
120
+ end
121
+
122
+ describe '.params_tree' do
123
+ let(:expected) {
124
+ {
125
+ "another" => {
126
+ "more_sublevel" => "something",
127
+ "sublevel" => {
128
+ "array" => ["five", "four"],
129
+ "thing" => "always"
130
+ }
131
+ },
132
+ "common_param" => {
133
+ "subparam" => "overriden"
134
+ },
135
+ "somefarmparam" => false
136
+ }
137
+ }
138
+ it { expect(node.params_tree).to eq expected }
139
+ end
140
+
141
+ describe '.modules' do
142
+ context "no unfound modules" do
143
+ let(:expected) {
144
+ {
145
+ "fake_module" => "modules/fake_module",
146
+ "fake_module2" => "modules/fake_module2",
147
+ "fake_module3" => "modules/fake_module3"
148
+ }
149
+ }
150
+ it { expect(node.modules).to eq expected }
151
+ end
152
+ context "one unfound modules" do
153
+ let(:node) { Hieracles::Node.new 'server2.example.com', options }
154
+ let(:expected) {
155
+ {
156
+ "fake_module" => "modules/fake_module",
157
+ "fake_module2" => "modules/fake_module2",
158
+ "fake_module4" => nil
159
+ }
160
+ }
161
+ it { expect(node.modules).to eq expected }
162
+ end
163
+ context "no farm file found" do
164
+ let(:node) { Hieracles::Node.new 'server3.example.com', options }
165
+ it { expect { node.modules }.to raise_error(RuntimeError) }
166
+ end
167
+ context "multiple classes included" do
168
+ let(:node) { Hieracles::Node.new 'server4.example.com', options }
169
+ let(:expected) {
170
+ {
171
+ "fake_module" => "modules/fake_module",
172
+ "fake_module2" => "modules/fake_module2",
173
+ "fake_module4" => nil,
174
+ "faux_module1" => "modules/faux_module1",
175
+ "faux_module2" => "modules/faux_module2"
176
+ }
177
+ }
178
+ it { expect(node.modules).to eq expected }
179
+ end
180
+ end
181
+
182
+ describe '.info' do
183
+ let(:expected) { {
46
184
  classes: ['dev'],
47
185
  fqdn: 'server.example.com',
48
- country: 'fr',
49
186
  datacenter: 'equinix',
187
+ country: 'fr',
50
188
  farm: 'dev'
51
- }
52
- }
53
- it { expect(node).to be_a Hieracles::Node }
54
- it { expect(node.hiera_params).to eq expected }
189
+ } }
190
+ it { expect(node.info).to eq expected }
191
+ end
192
+
55
193
  end
194
+ end
195
+
196
+ context "when parameters include double-column variables" do
197
+ let(:options) {
198
+ {
199
+ config: 'spec/files/config.yml',
200
+ hierafile: 'hiera_columns.yaml',
201
+ encpath: 'enc',
202
+ basepath: 'spec/files'
203
+ }
204
+ }
205
+ let(:node) { Hieracles::Node.new 'server.example.com', options }
56
206
 
57
207
  describe '.files' do
58
208
  let(:expected) {
@@ -63,20 +213,41 @@ describe Hieracles::Node do
63
213
  }
64
214
  it { expect(node.files).to eq expected }
65
215
  end
216
+ end
66
217
 
67
- describe '.paths' do
68
- let(:expected) {
69
- [
70
- File.join(node.hiera.datapath, 'nodes/server.example.com.yaml'),
71
- File.join(node.hiera.datapath, 'farm/dev.yaml')
72
- ]
218
+
219
+ context "with deep merge" do
220
+ let(:options) {
221
+ {
222
+ config: 'spec/files/config.yml',
223
+ hierafile: 'hiera_deep.yaml',
224
+ encpath: 'enc',
225
+ basepath: 'spec/files'
73
226
  }
74
- it { expect(node.paths).to eq expected }
75
- end
227
+ }
228
+ let(:node) { Hieracles::Node.new 'server.example.com', options }
76
229
 
77
230
  describe '.params' do
78
231
  let(:expected) {
79
232
  [
233
+ [ "another.more_sublevel",
234
+ [{
235
+ value: "something",
236
+ file: 'params/farm/dev.yaml'
237
+ }]
238
+ ],
239
+ [ "another.sublevel.array",
240
+ [
241
+ {
242
+ value: ["one", "two", "three"],
243
+ file: 'params/farm/dev.yaml'
244
+ },
245
+ {
246
+ value: ["four", "five"],
247
+ file: 'params/nodes/server.example.com.yaml'
248
+ }
249
+ ]
250
+ ],
80
251
  [ "another.sublevel.thing",
81
252
  [{
82
253
  value: "always",
@@ -103,9 +274,11 @@ describe Hieracles::Node do
103
274
  describe '.params_tree' do
104
275
  let(:expected) {
105
276
  {
106
- "another" => {
277
+ "another" => {
278
+ "more_sublevel" => "something",
107
279
  "sublevel" => {
108
- "thing" => "always"
280
+ "array" => ["five", "four", "one", "three", "two"],
281
+ "thing" => "always",
109
282
  }
110
283
  },
111
284
  "common_param" => {
@@ -117,57 +290,81 @@ describe Hieracles::Node do
117
290
  it { expect(node.params_tree).to eq expected }
118
291
  end
119
292
 
293
+ end
120
294
 
121
- describe '.modules' do
122
- context "no unfound modules" do
123
- let(:expected) {
124
- {
125
- "fake_module" => "modules/fake_module",
126
- "fake_module2" => "modules/fake_module2",
127
- "fake_module3" => "modules/fake_module3"
128
- }
129
- }
130
- it { expect(node.modules).to eq expected }
131
- end
132
- context "one unfound modules" do
133
- let(:node) { Hieracles::Node.new 'server2.example.com', options }
134
- let(:expected) {
135
- {
136
- "fake_module" => "modules/fake_module",
137
- "fake_module2" => "modules/fake_module2",
138
- "fake_module4" => nil
139
- }
140
- }
141
- it { expect(node.modules).to eq expected }
142
- end
143
- context "no farm file found" do
144
- let(:node) { Hieracles::Node.new 'server3.example.com', options }
145
- it { expect { node.modules }.to raise_error(RuntimeError) }
146
- end
147
- context "multiple classes included" do
148
- let(:node) { Hieracles::Node.new 'server4.example.com', options }
149
- let(:expected) {
150
- {
151
- "fake_module" => "modules/fake_module",
152
- "fake_module2" => "modules/fake_module2",
153
- "fake_module4" => nil,
154
- "faux_module1" => "modules/faux_module1",
155
- "faux_module2" => "modules/faux_module2"
156
- }
157
- }
158
- it { expect(node.modules).to eq expected }
159
- end
295
+
296
+ context "with deeper merge" do
297
+ let(:options) {
298
+ {
299
+ config: 'spec/files/config.yml',
300
+ hierafile: 'hiera_deeper.yaml',
301
+ encpath: 'enc',
302
+ basepath: 'spec/files'
303
+ }
304
+ }
305
+ let(:node) { Hieracles::Node.new 'server.example.com', options }
306
+
307
+ describe '.params' do
308
+ let(:expected) {
309
+ [
310
+ [ "another.more_sublevel",
311
+ [{
312
+ value: "something",
313
+ file: 'params/farm/dev.yaml'
314
+ }]
315
+ ],
316
+ [ "another.sublevel.array",
317
+ [
318
+ {
319
+ value: ["one", "two", "three"],
320
+ file: 'params/farm/dev.yaml'
321
+ },
322
+ {
323
+ value: ["four", "five"],
324
+ file: 'params/nodes/server.example.com.yaml'
325
+ }
326
+ ]
327
+ ],
328
+ [ "another.sublevel.thing",
329
+ [{
330
+ value: "always",
331
+ file: 'params/nodes/server.example.com.yaml'
332
+ }]
333
+ ],
334
+ [ "common_param.subparam",
335
+ [{
336
+ value: "overriden",
337
+ file: 'params/nodes/server.example.com.yaml'
338
+ }]
339
+ ],
340
+ [ "somefarmparam",
341
+ [{
342
+ value: false,
343
+ file: 'params/farm/dev.yaml'
344
+ }]
345
+ ]
346
+ ]
347
+ }
348
+ it { expect(node.params).to eq expected }
160
349
  end
161
350
 
162
- describe '.info' do
163
- let(:expected) { {
164
- classes: ['dev'],
165
- fqdn: 'server.example.com',
166
- datacenter: 'equinix',
167
- country: 'fr',
168
- farm: 'dev'
169
- } }
170
- it { expect(node.info).to eq expected }
351
+ describe '.params_tree' do
352
+ let(:expected) {
353
+ {
354
+ "another" => {
355
+ "more_sublevel" => "something",
356
+ "sublevel" => {
357
+ "array" => ["five", "four", "one", "three", "two"],
358
+ "thing" => "always",
359
+ }
360
+ },
361
+ "common_param" => {
362
+ "subparam" => "overriden"
363
+ },
364
+ "somefarmparam" => false
365
+ }
366
+ }
367
+ it { expect(node.params_tree).to eq expected }
171
368
  end
172
369
 
173
370
  end
@@ -32,7 +32,7 @@ describe Hieracles::Optparse do
32
32
  end
33
33
  end
34
34
 
35
- context 'with funny arguments' do
35
+ context 'with funnily ordered arguments' do
36
36
  let(:array) { ['arg1', '-u', 'path/to/config-file', 'arg2', '-f', 'thatformat'] }
37
37
  let(:expected_payload) { ['arg1', 'arg2'] }
38
38
  let(:expected_options) do
@@ -48,7 +48,7 @@ describe Hieracles::Optparse do
48
48
  end
49
49
 
50
50
  context 'with arguments in alternative syntax' do
51
- let(:array) { ['arg1', 'arg2', '-config', 'path/to/config-file', '-format', 'thatformat'] }
51
+ let(:array) { ['arg1', 'arg2', '-config', 'path/to/config-file', '--format', 'thatformat'] }
52
52
  let(:expected_payload) { ['arg1', 'arg2'] }
53
53
  let(:expected_options) do
54
54
  { config: 'path/to/config-file', format: 'thatformat' }
@@ -61,5 +61,23 @@ describe Hieracles::Optparse do
61
61
  expect(subject.options).to eq expected_options
62
62
  end
63
63
  end
64
+
65
+
66
+ context 'with arguments containing boolean element' do
67
+ let(:array) { ['arg1', 'arg2', '-i', '-format', 'thatformat'] }
68
+ let(:expected_payload) { ['arg1', 'arg2'] }
69
+ let(:expected_options) do
70
+ { format: 'thatformat', interactive: true }
71
+ end
72
+ subject { Hieracles::Optparse.new array }
73
+ it "populates payload" do
74
+ expect(subject.payload).to eq expected_payload
75
+ end
76
+ it 'populates options' do
77
+ expect(subject.options).to eq expected_options
78
+ end
79
+ end
80
+
81
+
64
82
  end
65
83
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hieracles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - mose
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-15 00:00:00.000000000 Z
11
+ date: 2015-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: deep_merge
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement