vagrant-config_builder 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,6 +1,23 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 0.3.0
5
+ -----
6
+
7
+ This is a backwards compatible bugfix and feature release
8
+
9
+ ### User notes
10
+
11
+ #### Enhancements
12
+
13
+ * (GH-6) New filter: `boxes`
14
+ * box_url is now a supported vm attribute
15
+
16
+ #### Bugfixes
17
+
18
+ * Better error handling when no configuration is set
19
+ * Add missing variable when raising ClassRegistry::DuplicateEntry error
20
+
4
21
  0.2.0
5
22
  -----
6
23
 
@@ -29,6 +29,7 @@ module ConfigBuilder
29
29
  def register(identifier, klass)
30
30
  if @klasses[identifier]
31
31
  raise DuplicateEntry, :registry => @name,
32
+ :identifier => identifier.inspect,
32
33
  :identifiers => @klasses.keys
33
34
  else
34
35
  @klasses[identifier] = klass
@@ -1,5 +1,6 @@
1
1
  module ConfigBuilder
2
2
  module Filter
3
3
  require 'config_builder/filter/roles'
4
+ require 'config_builder/filter/boxes'
4
5
  end
5
6
  end
@@ -0,0 +1,22 @@
1
+ class ConfigBuilder::Filter::Boxes
2
+
3
+ attr_reader :boxes
4
+
5
+ def set_config(root_config)
6
+ @root_config = root_config
7
+ @boxes = (@root_config.delete('boxes') || {})
8
+ end
9
+
10
+ def run
11
+ return @root_config if @root_config['vms'].nil?
12
+
13
+ @root_config['vms'].each { |vm_hash| filter_vm(vm_hash) }
14
+ @root_config
15
+ end
16
+
17
+ def filter_vm(vm_hash)
18
+ if (box_name = vm_hash['box'])
19
+ vm_hash['box_url'] ||= @boxes[box_name]
20
+ end
21
+ end
22
+ end
@@ -12,7 +12,7 @@
12
12
  # the order of declaration of roles does not matter.
13
13
  #
14
14
  # @example
15
- # >> hash_config
15
+ # >> run()
16
16
  # => {
17
17
  # 'roles' => {
18
18
  # 'webserver' => {
@@ -37,19 +37,29 @@
37
37
  #
38
38
  class ConfigBuilder::Filter::Roles
39
39
 
40
- def run(hash_config)
41
- @roles = hash_config.delete('roles')
40
+ # @!attribute [r] roles
41
+ # @return [Hash<String, Object>]
42
+ attr_reader :roles
42
43
 
43
- hash_config['vms'].map! { |vm_hash| filter_vm(vm_hash) }
44
-
45
- hash_config
44
+ def set_config(root_config)
45
+ @root_config = root_config
46
+ @roles = @root_config.delete('roles')
47
+ @vms = @root_config.delete('vms')
46
48
  end
47
49
 
48
- private
50
+ def run
51
+ return @root_config if @vms.nil?
49
52
 
53
+ @root_config['vms'] = @vms.map { |vm_hash| filter_vm(vm_hash) }
54
+ @root_config
55
+ end
56
+
57
+ # @param vm_hash [Hash]
58
+ #
59
+ # @return [Hash] The filtered VM
50
60
  def filter_vm(old_vm)
51
61
  role_list = old_vm.delete('roles')
52
- node_stack = roles_for_vm(role_list)
62
+ node_stack = roles_by_name(role_list)
53
63
 
54
64
  node_stack << old_vm
55
65
 
@@ -60,25 +70,45 @@ class ConfigBuilder::Filter::Roles
60
70
  new_vm
61
71
  end
62
72
 
73
+ # Fetch the role associated with the given name
74
+ #
75
+ # @param role_name [String]
76
+ #
77
+ # @return [Hash<String, Object>]
78
+ def role(name)
79
+ if (retval = @roles[name])
80
+ retval
81
+ else
82
+ raise ArgumentError, "Requested role #{name.inspect} is not defined, available roles: #{@roles.keys}."
83
+ end
84
+ end
85
+
86
+ # @overload roles_by_name(name)
87
+ # @param name [String] A single role name
88
+ # @return [Array<Hash>] An array containing the requested role
89
+ #
90
+ # @overload roles_by_name(names)
91
+ # @param names [Array<String>] A list of role names
92
+ # @return [Array<Hash>] An array containing all of the requested roles in the
93
+ # order requested.
94
+ #
95
+ # @overload roles_by_name(nothing)
96
+ # @param nothing [NilClass] nil
97
+ # @return [Array<>] An empty array
98
+ #
63
99
  # @return [Array]
64
- def roles_for_vm(role_field)
100
+ def roles_by_name(field)
65
101
 
66
- case role_field
67
- when Array then names = role_field
68
- when String then names = [role_field]
102
+ case field
103
+ when Array then names = field
104
+ when String then names = [field]
69
105
  when NilClass then names = []
70
106
  end
71
107
 
72
- names.map { |name| role_definition(name) }
108
+ names.map { |name| role(name) }
73
109
  end
74
110
 
75
- def role_definition(name)
76
- if (defn = @roles[name])
77
- defn
78
- else
79
- raise "Couldn't find role named #{name.inspect} in roles #{@roles.keys.inspect}"
80
- end
81
- end
111
+ private
82
112
 
83
113
  # Merge two node hash structures, with values in `right` overwriting values
84
114
  # in `left`.
@@ -13,18 +13,24 @@ module ConfigBuilder
13
13
  def filter(input)
14
14
  set_filters(input.delete(:filters))
15
15
 
16
- @filter_stack.inject(input) do |current_input, filter|
17
- filter.run(current_input)
16
+ output = @filter_stack.inject(input) do |current_input, filter|
17
+ filter.set_config(current_input)
18
+ filter.run
18
19
  end
20
+
21
+ output
19
22
  end
20
23
 
21
24
  private
22
25
 
26
+ # @note The implementation of this method is not final, use at your own peril.
27
+ # @api private
23
28
  def set_filters(list)
24
29
  if list.nil?
25
30
  @filter_stack << ConfigBuilder::Filter::Roles.new
31
+ @filter_stack << ConfigBuilder::Filter::Boxes.new
26
32
  else
27
- raise NotImplementedError, "Custom lists of filters not implemented."
33
+ @filter_stack = list
28
34
  end
29
35
  end
30
36
  end
@@ -13,7 +13,12 @@ class ConfigBuilder::Loader::YAML
13
13
  rv = {}
14
14
  Dir.glob(glob_path).each do |file|
15
15
  contents = ::YAML.load_file(file)
16
- rv.merge!(contents)
16
+
17
+ if contents.is_a? Hash
18
+ rv.merge! contents
19
+ else
20
+ # TODO warn on non-hash YAML
21
+ end
17
22
  end
18
23
 
19
24
  rv
@@ -66,6 +66,10 @@ class ConfigBuilder::Model::VM < ConfigBuilder::Model::Base
66
66
  # @return [String] The name of the Vagrant box to instantiate for this VM
67
67
  def_model_attribute :box
68
68
 
69
+ # @!attribute [rw] box_url
70
+ # @return [String] The source URL for the Vagrant box associated with this VM
71
+ def_model_attribute :box
72
+
69
73
  # @!attribute [rw] name
70
74
  # @return [String] The name of the instantiated box in this environment
71
75
  def_model_attribute :name
@@ -89,6 +93,7 @@ class ConfigBuilder::Model::VM < ConfigBuilder::Model::Base
89
93
  vm_config = config.vm
90
94
 
91
95
  vm_config.box = attr(:box) if defined? attr(:box)
96
+ vm_config.box_url = attr(:box_url) if defined? attr(:box_url)
92
97
  vm_config.hostname = attr(:hostname) if defined? attr(:hostname)
93
98
 
94
99
  eval_models(vm_config)
@@ -1,3 +1,3 @@
1
1
  module ConfigBuilder
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe ConfigBuilder::Filter::Boxes do
4
+
5
+ def dup(o)
6
+ Marshal.load(Marshal.dump(o))
7
+ end
8
+
9
+ let(:boxes) do
10
+ {
11
+ 'first_box' => 'http://box_host/first_box.box',
12
+ 'second_box' => 'http://box_host/second_box.box',
13
+ 'third_box' => 'http://box_host/third_box.box',
14
+ }
15
+ end
16
+
17
+ let(:vms) do
18
+ [
19
+ {'name' => 'one', 'box' => 'first_box'},
20
+ {'name' => 'two', 'box' => 'second_box'},
21
+ {'name' => 'four', 'box' => 'fourth_box'},
22
+ {
23
+ 'name' => 'five',
24
+ 'box' => 'fifth_box',
25
+ 'box_url' => 'https://another_box_host/fifth_box.box',
26
+ },
27
+ ]
28
+ end
29
+
30
+ describe 'without a boxes key' do
31
+ let(:config) do
32
+ {
33
+ 'vms' => vms,
34
+ }
35
+ end
36
+
37
+ before { subject.set_config(config) }
38
+
39
+ it "doesn't modify any boxes" do
40
+ input = dup(config)
41
+ output = subject.run
42
+ expect(output).to eq config
43
+ end
44
+ end
45
+
46
+ describe 'when the boxes key is given' do
47
+ let(:config) do
48
+ {
49
+ 'boxes' => boxes,
50
+ 'vms' => vms,
51
+ }
52
+ end
53
+
54
+ before { subject.set_config(config) }
55
+
56
+ it "removes the 'boxes' key" do
57
+ output = subject.run
58
+ expect(output).to_not have_key 'boxes'
59
+ end
60
+
61
+ it "adds the 'box_url' to VMs whose 'box' value is in the 'boxes' list" do
62
+ output = subject.run
63
+ vms = output['vms']
64
+
65
+ expect(vms[0]['box_url']).to eq 'http://box_host/first_box.box'
66
+ expect(vms[1]['box_url']).to eq 'http://box_host/second_box.box'
67
+ end
68
+
69
+ describe "if the VM 'box' value doesn't have a match in the box list" do
70
+ it "doesn't modify the 'box_url'" do
71
+ output = subject.run
72
+ vms = output['vms']
73
+
74
+ expect(vms[2]['box_url']).to be_nil
75
+ end
76
+ end
77
+
78
+ describe "if the VM 'box_url' is already set" do
79
+ it "doesn't modify the 'box_url'" do
80
+ output = subject.run
81
+ vms = output['vms']
82
+
83
+ expect(vms[3]['box_url']).to eq 'https://another_box_host/fifth_box.box'
84
+ end
85
+ end
86
+ end
87
+ end
@@ -53,9 +53,13 @@ describe ConfigBuilder::Filter::Roles do
53
53
  {'vms' => vms}
54
54
  end
55
55
 
56
+ before do
57
+ subject.set_config(dup(config))
58
+ end
59
+
56
60
  it "doesn't alter the structure" do
57
61
  input = dup(config)
58
- output = subject.run(input)
62
+ output = subject.run
59
63
 
60
64
  expect(output).to eq config
61
65
  end
@@ -69,8 +73,12 @@ describe ConfigBuilder::Filter::Roles do
69
73
  }
70
74
  end
71
75
 
76
+ before do
77
+ subject.set_config(dup(config))
78
+ end
79
+
72
80
  it 'strips out the roles key' do
73
- output = subject.run(config)
81
+ output = subject.run
74
82
  expect(output).to_not have_key 'roles'
75
83
  end
76
84
  end
@@ -85,9 +93,12 @@ describe ConfigBuilder::Filter::Roles do
85
93
  }
86
94
  end
87
95
 
96
+ before do
97
+ subject.set_config(dup(config))
98
+ end
99
+
88
100
  it "doesn't alter the vm" do
89
- input = dup(config)
90
- output = subject.run(input)
101
+ output = subject.run
91
102
  expect(output['vms']).to eq vms
92
103
  end
93
104
  end
@@ -103,8 +114,12 @@ describe ConfigBuilder::Filter::Roles do
103
114
  }
104
115
  end
105
116
 
117
+ before do
118
+ subject.set_config(dup(config))
119
+ end
120
+
106
121
  let(:filtered_vm) do
107
- output = subject.run(config)
122
+ output = subject.run
108
123
  output['vms'][0]
109
124
  end
110
125
 
@@ -137,8 +152,12 @@ describe ConfigBuilder::Filter::Roles do
137
152
  }
138
153
  end
139
154
 
155
+ before do
156
+ subject.set_config(dup(config))
157
+ end
158
+
140
159
  let(:filtered_vm) do
141
- output = subject.run(config)
160
+ output = subject.run
142
161
  output['vms'][0]
143
162
  end
144
163
 
@@ -180,8 +199,12 @@ describe ConfigBuilder::Filter::Roles do
180
199
  }
181
200
  end
182
201
 
202
+ before do
203
+ subject.set_config(dup(config))
204
+ end
205
+
183
206
  let(:filtered_vms) do
184
- output = subject.run(config)
207
+ output = subject.run
185
208
  output['vms']
186
209
  end
187
210
 
@@ -237,8 +260,12 @@ describe ConfigBuilder::Filter::Roles do
237
260
  'roles' => {'yep' => {'box' => 'moxxi'}}
238
261
  }
239
262
 
263
+ before do
264
+ subject.set_config(dup(config))
265
+ end
266
+
240
267
  it 'raises an error' do
241
- expect { subject.run(config) }.to raise_error, /Couldn't find role named .*nope.*/
268
+ expect { subject.run }.to raise_error, /Couldn't find role named .*nope.*/
242
269
  end
243
270
  end
244
271
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-config_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-17 00:00:00.000000000 Z
12
+ date: 2013-08-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -44,6 +44,7 @@ files:
44
44
  - lib/config_builder/class_registry.rb
45
45
  - lib/config_builder/extension_handler.rb
46
46
  - lib/config_builder/filter.rb
47
+ - lib/config_builder/filter/boxes.rb
47
48
  - lib/config_builder/filter/roles.rb
48
49
  - lib/config_builder/filter_stack.rb
49
50
  - lib/config_builder/loader.rb
@@ -65,6 +66,7 @@ files:
65
66
  - lib/config_builder/runner.rb
66
67
  - lib/config_builder/version.rb
67
68
  - lib/vagrant-config_builder.rb
69
+ - spec/config_builder/filter/boxes_spec.rb
68
70
  - spec/config_builder/filter/roles_spec.rb
69
71
  - spec/spec_helper.rb
70
72
  - templates/locales/en.yml