hieracles 0.1.5 → 0.1.6

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
  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