cheffish 1.5.0 → 1.6.0
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 +4 -4
- data/Gemfile +10 -0
- data/LICENSE +201 -201
- data/README.md +120 -120
- data/Rakefile +23 -23
- data/cheffish.gemspec +26 -0
- data/lib/chef/provider/chef_acl.rb +446 -439
- data/lib/chef/provider/chef_client.rb +53 -53
- data/lib/chef/provider/chef_container.rb +55 -55
- data/lib/chef/provider/chef_data_bag.rb +55 -55
- data/lib/chef/provider/chef_data_bag_item.rb +278 -278
- data/lib/chef/provider/chef_environment.rb +83 -83
- data/lib/chef/provider/chef_group.rb +83 -83
- data/lib/chef/provider/chef_mirror.rb +169 -169
- data/lib/chef/provider/chef_node.rb +87 -87
- data/lib/chef/provider/chef_organization.rb +155 -155
- data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -46
- data/lib/chef/provider/chef_role.rb +84 -84
- data/lib/chef/provider/chef_user.rb +59 -59
- data/lib/chef/provider/private_key.rb +225 -225
- data/lib/chef/provider/public_key.rb +88 -88
- data/lib/chef/resource/chef_acl.rb +69 -69
- data/lib/chef/resource/chef_client.rb +48 -48
- data/lib/chef/resource/chef_container.rb +22 -22
- data/lib/chef/resource/chef_data_bag.rb +22 -22
- data/lib/chef/resource/chef_data_bag_item.rb +121 -121
- data/lib/chef/resource/chef_environment.rb +77 -77
- data/lib/chef/resource/chef_group.rb +53 -53
- data/lib/chef/resource/chef_mirror.rb +52 -52
- data/lib/chef/resource/chef_node.rb +22 -22
- data/lib/chef/resource/chef_organization.rb +69 -69
- data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -35
- data/lib/chef/resource/chef_role.rb +110 -110
- data/lib/chef/resource/chef_user.rb +56 -56
- data/lib/chef/resource/private_key.rb +48 -48
- data/lib/chef/resource/public_key.rb +25 -25
- data/lib/cheffish.rb +235 -235
- data/lib/cheffish/actor_provider_base.rb +131 -131
- data/lib/cheffish/basic_chef_client.rb +184 -184
- data/lib/cheffish/chef_provider_base.rb +246 -246
- data/lib/cheffish/chef_run.rb +162 -162
- data/lib/cheffish/chef_run_data.rb +19 -19
- data/lib/cheffish/chef_run_listener.rb +30 -30
- data/lib/cheffish/key_formatter.rb +113 -113
- data/lib/cheffish/merged_config.rb +98 -94
- data/lib/cheffish/recipe_dsl.rb +157 -157
- data/lib/cheffish/rspec.rb +8 -8
- data/lib/cheffish/rspec/chef_run_support.rb +83 -83
- data/lib/cheffish/rspec/matchers.rb +4 -4
- data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
- data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
- data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
- data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
- data/lib/cheffish/rspec/recipe_run_wrapper.rb +78 -78
- data/lib/cheffish/rspec/repository_support.rb +108 -108
- data/lib/cheffish/server_api.rb +52 -52
- data/lib/cheffish/version.rb +3 -3
- data/lib/cheffish/with_pattern.rb +21 -21
- data/spec/functional/fingerprint_spec.rb +64 -64
- data/spec/functional/merged_config_spec.rb +19 -19
- data/spec/functional/server_api_spec.rb +13 -13
- data/spec/integration/chef_acl_spec.rb +892 -879
- data/spec/integration/chef_client_spec.rb +105 -105
- data/spec/integration/chef_container_spec.rb +33 -33
- data/spec/integration/chef_group_spec.rb +309 -309
- data/spec/integration/chef_mirror_spec.rb +491 -491
- data/spec/integration/chef_node_spec.rb +786 -786
- data/spec/integration/chef_organization_spec.rb +226 -226
- data/spec/integration/chef_role_spec.rb +78 -78
- data/spec/integration/chef_user_spec.rb +85 -85
- data/spec/integration/private_key_spec.rb +399 -399
- data/spec/integration/recipe_dsl_spec.rb +28 -28
- data/spec/integration/rspec/converge_spec.rb +183 -183
- data/spec/support/key_support.rb +29 -29
- data/spec/support/spec_support.rb +15 -15
- data/spec/unit/get_private_key_spec.rb +131 -131
- data/spec/unit/recipe_run_wrapper_spec.rb +37 -37
- metadata +7 -5
@@ -1,786 +1,786 @@
|
|
1
|
-
require 'support/spec_support'
|
2
|
-
require 'cheffish/rspec/chef_run_support'
|
3
|
-
require 'chef/resource/chef_node'
|
4
|
-
require 'chef/provider/chef_node'
|
5
|
-
|
6
|
-
describe Chef::Resource::ChefNode do
|
7
|
-
extend Cheffish::RSpec::ChefRunSupport
|
8
|
-
|
9
|
-
when_the_chef_12_server 'is in multi-org mode' do
|
10
|
-
organization 'foo'
|
11
|
-
|
12
|
-
before :each do
|
13
|
-
Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'and is empty' do
|
17
|
-
context 'and we run a recipe that creates node "blah"' do
|
18
|
-
it 'the node gets created' do
|
19
|
-
expect_recipe {
|
20
|
-
chef_node 'blah'
|
21
|
-
}.to have_updated 'chef_node[blah]', :create
|
22
|
-
expect(get('nodes/blah')['name']).to eq('blah')
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# TODO why-run mode
|
27
|
-
|
28
|
-
context 'and another chef server is running on port 8899' do
|
29
|
-
before :each do
|
30
|
-
@server = ChefZero::Server.new(:port => 8899)
|
31
|
-
@server.start_background
|
32
|
-
end
|
33
|
-
|
34
|
-
after :each do
|
35
|
-
@server.stop
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'and a recipe is run that creates node "blah" on the second chef server using with_chef_server' do
|
39
|
-
|
40
|
-
it 'the node is created on the second chef server but not the first' do
|
41
|
-
expect_recipe {
|
42
|
-
with_chef_server 'http://127.0.0.1:8899'
|
43
|
-
chef_node 'blah'
|
44
|
-
}.to have_updated 'chef_node[blah]', :create
|
45
|
-
expect { get('nodes/blah') }.to raise_error(Net::HTTPServerException)
|
46
|
-
expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context 'and a recipe is run that creates node "blah" on the second chef server using chef_server' do
|
51
|
-
|
52
|
-
it 'the node is created on the second chef server but not the first' do
|
53
|
-
expect_recipe {
|
54
|
-
chef_node 'blah' do
|
55
|
-
chef_server({ :chef_server_url => 'http://127.0.0.1:8899' })
|
56
|
-
end
|
57
|
-
}.to have_updated 'chef_node[blah]', :create
|
58
|
-
expect { get('nodes/blah') }.to raise_error(Net::HTTPServerException)
|
59
|
-
expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'and has a node named "blah"' do
|
66
|
-
node 'blah', {}
|
67
|
-
|
68
|
-
it 'chef_node "blah" does not get created or updated' do
|
69
|
-
expect_recipe {
|
70
|
-
chef_node 'blah'
|
71
|
-
}.not_to have_updated 'chef_node[blah]', :create
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context 'and has a node named "blah" with tags' do
|
76
|
-
node 'blah', {
|
77
|
-
'normal' => { 'tags' => [ 'a', 'b' ] }
|
78
|
-
}
|
79
|
-
|
80
|
-
context 'with chef_node "blah" that sets attributes' do
|
81
|
-
with_converge do
|
82
|
-
chef_node 'blah' do
|
83
|
-
attributes({})
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'the tags in attributes are used' do
|
88
|
-
expect(get('nodes/blah')['normal']['tags']).to eq([ 'a', 'b' ])
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'with chef_node "blah" that sets attributes with tags in them' do
|
93
|
-
with_converge do
|
94
|
-
chef_node 'blah' do
|
95
|
-
attributes 'tags' => [ 'c', 'd' ]
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'the tags in attributes are used' do
|
100
|
-
expect(get('nodes/blah')['normal']['tags']).to eq([ 'c', 'd' ])
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
describe '#complete' do
|
106
|
-
context 'when the Chef server has a node named "blah" with everything in it' do
|
107
|
-
node 'blah', {
|
108
|
-
'chef_environment' => 'blah',
|
109
|
-
'run_list' => [ 'recipe[bjork]' ],
|
110
|
-
'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
|
111
|
-
'default' => { 'foo2' => 'bar2' },
|
112
|
-
'automatic' => { 'foo3' => 'bar3' },
|
113
|
-
'override' => { 'foo4' => 'bar4' }
|
114
|
-
}
|
115
|
-
|
116
|
-
it 'chef_node with no attributes modifies nothing' do
|
117
|
-
expect_recipe {
|
118
|
-
chef_node 'blah'
|
119
|
-
}.to be_up_to_date
|
120
|
-
expect(get('nodes/blah')).to include(
|
121
|
-
'name' => 'blah',
|
122
|
-
'chef_environment' => 'blah',
|
123
|
-
'run_list' => [ 'recipe[bjork]' ],
|
124
|
-
'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
|
125
|
-
'default' => { 'foo2' => 'bar2' },
|
126
|
-
'automatic' => { 'foo3' => 'bar3' },
|
127
|
-
'override' => { 'foo4' => 'bar4' }
|
128
|
-
)
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'chef_node with complete true removes everything except default, automatic and override' do
|
132
|
-
expect_recipe {
|
133
|
-
chef_node 'blah' do
|
134
|
-
complete true
|
135
|
-
end
|
136
|
-
}.to be_updated
|
137
|
-
expect(get('nodes/blah')).to include(
|
138
|
-
'name' => 'blah',
|
139
|
-
'chef_environment' => '_default',
|
140
|
-
'run_list' => [ ],
|
141
|
-
'normal' => { 'tags' => [ 'a', 'b' ] },
|
142
|
-
'default' => { 'foo2' => 'bar2' },
|
143
|
-
'automatic' => { 'foo3' => 'bar3' },
|
144
|
-
'override' => { 'foo4' => 'bar4' }
|
145
|
-
)
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'chef_node with complete true sets the given attributes' do
|
149
|
-
expect_recipe {
|
150
|
-
chef_node 'blah' do
|
151
|
-
chef_environment 'x'
|
152
|
-
run_list [ 'recipe[y]' ]
|
153
|
-
attributes 'a' => 'b'
|
154
|
-
tags 'c', 'd'
|
155
|
-
complete true
|
156
|
-
end
|
157
|
-
}.to be_updated
|
158
|
-
expect(get('nodes/blah')).to include(
|
159
|
-
'name' => 'blah',
|
160
|
-
'chef_environment' => 'x',
|
161
|
-
'run_list' => [ 'recipe[y]' ],
|
162
|
-
'normal' => { 'a' => 'b', 'tags' => [ 'c', 'd' ] },
|
163
|
-
'default' => { 'foo2' => 'bar2' },
|
164
|
-
'automatic' => { 'foo3' => 'bar3' },
|
165
|
-
'override' => { 'foo4' => 'bar4' }
|
166
|
-
)
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'chef_node with complete true and partial attributes sets the given attributes' do
|
170
|
-
expect_recipe {
|
171
|
-
chef_node 'blah' do
|
172
|
-
chef_environment 'x'
|
173
|
-
recipe 'y'
|
174
|
-
attribute 'a', 'b'
|
175
|
-
tags 'c', 'd'
|
176
|
-
complete true
|
177
|
-
end
|
178
|
-
}.to be_updated
|
179
|
-
expect(get('nodes/blah')).to include(
|
180
|
-
'name' => 'blah',
|
181
|
-
'chef_environment' => 'x',
|
182
|
-
'run_list' => [ 'recipe[y]' ],
|
183
|
-
'normal' => { 'a' => 'b', 'tags' => [ 'c', 'd' ] },
|
184
|
-
'default' => { 'foo2' => 'bar2' },
|
185
|
-
'automatic' => { 'foo3' => 'bar3' },
|
186
|
-
'override' => { 'foo4' => 'bar4' }
|
187
|
-
)
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe '#attributes' do
|
193
|
-
context 'with a node with normal attributes a => b and c => { d => e }' do
|
194
|
-
node 'blah', {
|
195
|
-
'normal' => {
|
196
|
-
'a' => 'b',
|
197
|
-
'c' => { 'd' => 'e' },
|
198
|
-
'tags' => [ 'a', 'b' ]
|
199
|
-
},
|
200
|
-
'automatic' => {
|
201
|
-
'x' => 'y'
|
202
|
-
},
|
203
|
-
'chef_environment' => 'desert'
|
204
|
-
}
|
205
|
-
|
206
|
-
it 'chef_node with attributes {} removes all normal attributes but leaves tags, automatic and environment alone' do
|
207
|
-
expect_recipe {
|
208
|
-
chef_node 'blah' do
|
209
|
-
attributes({})
|
210
|
-
end
|
211
|
-
}.to have_updated('chef_node[blah]', :create)
|
212
|
-
expect(get('nodes/blah')).to include(
|
213
|
-
'normal' => { 'tags' => [ 'a', 'b' ] },
|
214
|
-
'automatic' => { 'x' => 'y' },
|
215
|
-
'chef_environment' => 'desert'
|
216
|
-
)
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'chef_node with attributes { c => d } replaces normal but not tags/automatic/environment' do
|
220
|
-
expect_recipe {
|
221
|
-
chef_node 'blah' do
|
222
|
-
attributes 'c' => 'd'
|
223
|
-
end
|
224
|
-
}.to have_updated('chef_node[blah]', :create)
|
225
|
-
expect(get('nodes/blah')).to include(
|
226
|
-
'normal' => { 'c' => 'd', 'tags' => [ 'a', 'b' ] },
|
227
|
-
'automatic' => { 'x' => 'y' },
|
228
|
-
'chef_environment' => 'desert'
|
229
|
-
)
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'chef_node with attributes { c => f => g, y => z } replaces normal but not tags/automatic/environment' do
|
233
|
-
expect_recipe {
|
234
|
-
chef_node 'blah' do
|
235
|
-
attributes 'c' => { 'f' => 'g' }, 'y' => 'z'
|
236
|
-
end
|
237
|
-
}.to have_updated('chef_node[blah]', :create)
|
238
|
-
expect(get('nodes/blah')).to include(
|
239
|
-
'normal' => { 'c' => { 'f' => 'g' }, 'y' => 'z', 'tags' => [ 'a', 'b' ] },
|
240
|
-
'automatic' => { 'x' => 'y' },
|
241
|
-
'chef_environment' => 'desert'
|
242
|
-
)
|
243
|
-
end
|
244
|
-
|
245
|
-
it 'chef_node with attributes { tags => [ "x" ] } replaces normal and tags but not automatic/environment' do
|
246
|
-
expect_recipe {
|
247
|
-
chef_node 'blah' do
|
248
|
-
attributes 'tags' => [ 'x' ]
|
249
|
-
end
|
250
|
-
}.to have_updated('chef_node[blah]', :create)
|
251
|
-
expect(get('nodes/blah')).to include(
|
252
|
-
'normal' => { 'tags' => [ 'x' ] },
|
253
|
-
'automatic' => { 'x' => 'y' },
|
254
|
-
'chef_environment' => 'desert'
|
255
|
-
)
|
256
|
-
end
|
257
|
-
|
258
|
-
it 'chef_node with tags "x" and attributes { "tags" => [ "y" ] } sets tags to "x"' do
|
259
|
-
expect_recipe {
|
260
|
-
chef_node 'blah' do
|
261
|
-
tags 'x'
|
262
|
-
attributes 'tags' => [ 'y' ]
|
263
|
-
end
|
264
|
-
}.to have_updated('chef_node[blah]', :create)
|
265
|
-
expect(get('nodes/blah')).to include(
|
266
|
-
'normal' => {
|
267
|
-
'tags' => [ 'x' ]
|
268
|
-
},
|
269
|
-
'automatic' => { 'x' => 'y' },
|
270
|
-
'chef_environment' => 'desert'
|
271
|
-
)
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
describe '#attribute' do
|
277
|
-
context 'with a node with normal attributes a => b and c => { d => e }' do
|
278
|
-
node 'blah', {
|
279
|
-
'normal' => {
|
280
|
-
'a' => 'b',
|
281
|
-
'c' => { 'd' => 'e' },
|
282
|
-
'tags' => [ 'a', 'b' ]
|
283
|
-
},
|
284
|
-
'automatic' => {
|
285
|
-
'x' => 'y'
|
286
|
-
},
|
287
|
-
'chef_environment' => 'desert'
|
288
|
-
}
|
289
|
-
|
290
|
-
context 'basic scenarios' do
|
291
|
-
it 'chef_node with no attributes, leaves it alone' do
|
292
|
-
expect_recipe {
|
293
|
-
chef_node 'blah'
|
294
|
-
}.not_to have_updated('chef_node[blah]', :create)
|
295
|
-
expect(get('nodes/blah')).to include(
|
296
|
-
'normal' => {
|
297
|
-
'a' => 'b',
|
298
|
-
'c' => { 'd' => 'e' },
|
299
|
-
'tags' => [ 'a', 'b' ]
|
300
|
-
},
|
301
|
-
'automatic' => { 'x' => 'y' },
|
302
|
-
'chef_environment' => 'desert'
|
303
|
-
)
|
304
|
-
end
|
305
|
-
|
306
|
-
it 'chef_node with attribute d, e adds the attribute' do
|
307
|
-
expect_recipe {
|
308
|
-
chef_node 'blah' do
|
309
|
-
attribute 'd', 'e'
|
310
|
-
end
|
311
|
-
}.to have_updated('chef_node[blah]', :create)
|
312
|
-
expect(get('nodes/blah')).to include(
|
313
|
-
'normal' => {
|
314
|
-
'a' => 'b',
|
315
|
-
'c' => { 'd' => 'e' },
|
316
|
-
'd' => 'e',
|
317
|
-
'tags' => [ 'a', 'b' ]
|
318
|
-
},
|
319
|
-
'automatic' => { 'x' => 'y' },
|
320
|
-
'chef_environment' => 'desert'
|
321
|
-
)
|
322
|
-
end
|
323
|
-
|
324
|
-
it 'chef_node with attribute tags, [ "x" ] replaces tags' do
|
325
|
-
expect_recipe {
|
326
|
-
chef_node 'blah' do
|
327
|
-
attribute 'tags', [ 'x' ]
|
328
|
-
end
|
329
|
-
}.to have_updated('chef_node[blah]', :create)
|
330
|
-
expect(get('nodes/blah')).to include(
|
331
|
-
'normal' => {
|
332
|
-
'a' => 'b',
|
333
|
-
'c' => { 'd' => 'e' },
|
334
|
-
'tags' => [ 'x' ]
|
335
|
-
},
|
336
|
-
'automatic' => { 'x' => 'y' },
|
337
|
-
'chef_environment' => 'desert'
|
338
|
-
)
|
339
|
-
end
|
340
|
-
|
341
|
-
it 'chef_node with attribute c, x replaces the attribute' do
|
342
|
-
expect_recipe {
|
343
|
-
chef_node 'blah' do
|
344
|
-
attribute 'c', 'x'
|
345
|
-
end
|
346
|
-
}.to have_updated('chef_node[blah]', :create)
|
347
|
-
expect(get('nodes/blah')).to include(
|
348
|
-
'normal' => {
|
349
|
-
'a' => 'b',
|
350
|
-
'c' => 'x',
|
351
|
-
'tags' => [ 'a', 'b' ]
|
352
|
-
},
|
353
|
-
'automatic' => { 'x' => 'y' },
|
354
|
-
'chef_environment' => 'desert'
|
355
|
-
)
|
356
|
-
end
|
357
|
-
|
358
|
-
it 'chef_node with attribute c, { d => x } replaces the attribute' do
|
359
|
-
expect_recipe {
|
360
|
-
chef_node 'blah' do
|
361
|
-
attribute 'c', { 'd' => 'x' }
|
362
|
-
end
|
363
|
-
}.to have_updated('chef_node[blah]', :create)
|
364
|
-
expect(get('nodes/blah')).to include(
|
365
|
-
'normal' => {
|
366
|
-
'a' => 'b',
|
367
|
-
'c' => { 'd' => 'x' },
|
368
|
-
'tags' => [ 'a', 'b' ]
|
369
|
-
},
|
370
|
-
'automatic' => { 'x' => 'y' },
|
371
|
-
'chef_environment' => 'desert'
|
372
|
-
)
|
373
|
-
end
|
374
|
-
|
375
|
-
it 'chef_node with attribute [ c, d ], x replaces the attribute' do
|
376
|
-
expect_recipe {
|
377
|
-
chef_node 'blah' do
|
378
|
-
attribute [ 'c', 'd' ], 'x'
|
379
|
-
end
|
380
|
-
}.to have_updated('chef_node[blah]', :create)
|
381
|
-
expect(get('nodes/blah')).to include(
|
382
|
-
'normal' => {
|
383
|
-
'a' => 'b',
|
384
|
-
'c' => { 'd' => 'x' },
|
385
|
-
'tags' => [ 'a', 'b' ]
|
386
|
-
},
|
387
|
-
'automatic' => { 'x' => 'y' },
|
388
|
-
'chef_environment' => 'desert'
|
389
|
-
)
|
390
|
-
end
|
391
|
-
|
392
|
-
it 'chef_node with attribute [ a, b ], x raises an error' do
|
393
|
-
expect {
|
394
|
-
converge {
|
395
|
-
chef_node 'blah' do
|
396
|
-
attribute [ 'a', 'b' ], 'x'
|
397
|
-
end
|
398
|
-
}
|
399
|
-
}.to raise_error /Attempt to set \["a", "b"\] to x when \["a"\] is not a hash/
|
400
|
-
end
|
401
|
-
|
402
|
-
it 'chef_node with attribute [ a, b, c ], x raises an error' do
|
403
|
-
expect {
|
404
|
-
converge {
|
405
|
-
chef_node 'blah' do
|
406
|
-
attribute [ 'a', 'b', 'c' ], 'x'
|
407
|
-
end
|
408
|
-
}
|
409
|
-
}.to raise_error /Attempt to set \["a", "b", "c"\] to x when \["a"\] is not a hash/
|
410
|
-
end
|
411
|
-
|
412
|
-
it 'chef_node with attribute [ x, y ], z adds a new attribute' do
|
413
|
-
expect_recipe {
|
414
|
-
chef_node 'blah' do
|
415
|
-
attribute [ 'x', 'y' ], 'z'
|
416
|
-
end
|
417
|
-
}.to have_updated('chef_node[blah]', :create)
|
418
|
-
expect(get('nodes/blah')).to include(
|
419
|
-
'normal' => {
|
420
|
-
'a' => 'b',
|
421
|
-
'c' => { 'd' => 'e' },
|
422
|
-
'x' => { 'y' => 'z' },
|
423
|
-
'tags' => [ 'a', 'b' ]
|
424
|
-
},
|
425
|
-
'automatic' => { 'x' => 'y' },
|
426
|
-
'chef_environment' => 'desert'
|
427
|
-
)
|
428
|
-
end
|
429
|
-
|
430
|
-
it 'chef_node with attribute [], {} clears all attributes' do
|
431
|
-
expect_recipe {
|
432
|
-
chef_node 'blah' do
|
433
|
-
attribute([], {})
|
434
|
-
end
|
435
|
-
}.to have_updated('chef_node[blah]', :create)
|
436
|
-
expect(get('nodes/blah')).to include(
|
437
|
-
'normal' => { },
|
438
|
-
'automatic' => { 'x' => 'y' },
|
439
|
-
'chef_environment' => 'desert'
|
440
|
-
)
|
441
|
-
end
|
442
|
-
end
|
443
|
-
|
444
|
-
context 'delete' do
|
445
|
-
it 'chef_node with attribute a, :delete deletes the attribute' do
|
446
|
-
expect_recipe {
|
447
|
-
chef_node 'blah' do
|
448
|
-
attribute 'a', :delete
|
449
|
-
end
|
450
|
-
}.to have_updated('chef_node[blah]', :create)
|
451
|
-
expect(get('nodes/blah')).to include(
|
452
|
-
'normal' => {
|
453
|
-
'c' => { 'd' => 'e' },
|
454
|
-
'tags' => [ 'a', 'b' ]
|
455
|
-
},
|
456
|
-
'automatic' => { 'x' => 'y' },
|
457
|
-
'chef_environment' => 'desert'
|
458
|
-
)
|
459
|
-
end
|
460
|
-
|
461
|
-
it 'chef_node with attribute c, :delete deletes the attribute' do
|
462
|
-
expect_recipe {
|
463
|
-
chef_node 'blah' do
|
464
|
-
attribute 'c', :delete
|
465
|
-
end
|
466
|
-
}.to have_updated('chef_node[blah]', :create)
|
467
|
-
expect(get('nodes/blah')).to include(
|
468
|
-
'normal' => {
|
469
|
-
'a' => 'b',
|
470
|
-
'tags' => [ 'a', 'b' ]
|
471
|
-
},
|
472
|
-
'automatic' => { 'x' => 'y' },
|
473
|
-
'chef_environment' => 'desert'
|
474
|
-
)
|
475
|
-
end
|
476
|
-
|
477
|
-
it 'chef_node with attribute [ c, d ], :delete deletes the attribute' do
|
478
|
-
expect_recipe {
|
479
|
-
chef_node 'blah' do
|
480
|
-
attribute [ 'c', 'd' ], :delete
|
481
|
-
end
|
482
|
-
}.to have_updated('chef_node[blah]', :create)
|
483
|
-
expect(get('nodes/blah')).to include(
|
484
|
-
'normal' => {
|
485
|
-
'a' => 'b',
|
486
|
-
'c' => {},
|
487
|
-
'tags' => [ 'a', 'b' ]
|
488
|
-
},
|
489
|
-
'automatic' => { 'x' => 'y' },
|
490
|
-
'chef_environment' => 'desert'
|
491
|
-
)
|
492
|
-
end
|
493
|
-
|
494
|
-
it 'chef_node with attribute xyz, :delete does nothing' do
|
495
|
-
expect_recipe {
|
496
|
-
chef_node 'blah' do
|
497
|
-
attribute 'xyz', :delete
|
498
|
-
end
|
499
|
-
}.not_to have_updated('chef_node[blah]', :create)
|
500
|
-
expect(get('nodes/blah')).to include(
|
501
|
-
'normal' => {
|
502
|
-
'a' => 'b',
|
503
|
-
'c' => { 'd' => 'e' },
|
504
|
-
'tags' => [ 'a', 'b' ]
|
505
|
-
},
|
506
|
-
'automatic' => { 'x' => 'y' },
|
507
|
-
'chef_environment' => 'desert'
|
508
|
-
)
|
509
|
-
end
|
510
|
-
|
511
|
-
it 'chef_node with attribute [ c, x ], :delete does nothing' do
|
512
|
-
expect_recipe {
|
513
|
-
chef_node 'blah' do
|
514
|
-
attribute [ 'c', 'x' ], :delete
|
515
|
-
end
|
516
|
-
}.not_to have_updated('chef_node[blah]', :create)
|
517
|
-
expect(get('nodes/blah')).to include(
|
518
|
-
'normal' => {
|
519
|
-
'a' => 'b',
|
520
|
-
'c' => { 'd' => 'e' },
|
521
|
-
'tags' => [ 'a', 'b' ]
|
522
|
-
},
|
523
|
-
'automatic' => { 'x' => 'y' },
|
524
|
-
'chef_environment' => 'desert'
|
525
|
-
)
|
526
|
-
end
|
527
|
-
end
|
528
|
-
|
529
|
-
context 'types' do
|
530
|
-
it 'chef_node with attribute a, true sets a to true' do
|
531
|
-
expect_recipe {
|
532
|
-
chef_node 'blah' do
|
533
|
-
attribute 'a', true
|
534
|
-
end
|
535
|
-
}.to be_updated
|
536
|
-
expect(get('nodes/blah')).to include(
|
537
|
-
'normal' => {
|
538
|
-
'a' => true,
|
539
|
-
'c' => { 'd' => 'e' },
|
540
|
-
'tags' => [ 'a', 'b' ]
|
541
|
-
},
|
542
|
-
'automatic' => { 'x' => 'y' },
|
543
|
-
'chef_environment' => 'desert'
|
544
|
-
)
|
545
|
-
end
|
546
|
-
|
547
|
-
it 'chef_node with attribute a, 1 sets a to 1' do
|
548
|
-
expect_recipe {
|
549
|
-
chef_node 'blah' do
|
550
|
-
attribute 'a', 1
|
551
|
-
end
|
552
|
-
}.to be_updated
|
553
|
-
expect(get('nodes/blah')).to include(
|
554
|
-
'normal' => {
|
555
|
-
'a' => 1,
|
556
|
-
'c' => { 'd' => 'e' },
|
557
|
-
'tags' => [ 'a', 'b' ]
|
558
|
-
},
|
559
|
-
'automatic' => { 'x' => 'y' },
|
560
|
-
'chef_environment' => 'desert'
|
561
|
-
)
|
562
|
-
end
|
563
|
-
|
564
|
-
it 'chef_node with attribute a, "1" sets a to "1"' do
|
565
|
-
expect_recipe {
|
566
|
-
chef_node 'blah' do
|
567
|
-
attribute 'a', "1"
|
568
|
-
end
|
569
|
-
}.to be_updated
|
570
|
-
expect(get('nodes/blah')).to include(
|
571
|
-
'normal' => {
|
572
|
-
'a' => "1",
|
573
|
-
'c' => { 'd' => 'e' },
|
574
|
-
'tags' => [ 'a', 'b' ]
|
575
|
-
},
|
576
|
-
'automatic' => { 'x' => 'y' },
|
577
|
-
'chef_environment' => 'desert'
|
578
|
-
)
|
579
|
-
end
|
580
|
-
|
581
|
-
it 'chef_node with attribute a, "" sets a to ""' do
|
582
|
-
expect_recipe {
|
583
|
-
chef_node 'blah' do
|
584
|
-
attribute 'a', ""
|
585
|
-
end
|
586
|
-
}.to be_updated
|
587
|
-
expect(get('nodes/blah')).to include(
|
588
|
-
'normal' => {
|
589
|
-
'a' => "",
|
590
|
-
'c' => { 'd' => 'e' },
|
591
|
-
'tags' => [ 'a', 'b' ]
|
592
|
-
},
|
593
|
-
'automatic' => { 'x' => 'y' },
|
594
|
-
'chef_environment' => 'desert'
|
595
|
-
)
|
596
|
-
end
|
597
|
-
|
598
|
-
it 'chef_node with attribute a, nil sets a to nil' do
|
599
|
-
expect_recipe {
|
600
|
-
chef_node 'blah' do
|
601
|
-
attribute 'a', nil
|
602
|
-
end
|
603
|
-
}.to be_updated
|
604
|
-
expect(get('nodes/blah')).to include(
|
605
|
-
'normal' => {
|
606
|
-
'a' => nil,
|
607
|
-
'c' => { 'd' => 'e' },
|
608
|
-
'tags' => [ 'a', 'b' ]
|
609
|
-
},
|
610
|
-
'automatic' => { 'x' => 'y' },
|
611
|
-
'chef_environment' => 'desert'
|
612
|
-
)
|
613
|
-
end
|
614
|
-
end
|
615
|
-
|
616
|
-
context 'multiple attribute definitions' do
|
617
|
-
it 'chef_node with attribute a, x and c, y replaces both attributes' do
|
618
|
-
expect_recipe {
|
619
|
-
chef_node 'blah' do
|
620
|
-
attribute 'a', 'x'
|
621
|
-
attribute 'c', 'y'
|
622
|
-
end
|
623
|
-
}.to be_updated
|
624
|
-
expect(get('nodes/blah')).to include(
|
625
|
-
'normal' => {
|
626
|
-
'a' => 'x',
|
627
|
-
'c' => 'y',
|
628
|
-
'tags' => [ 'a', 'b' ]
|
629
|
-
},
|
630
|
-
'automatic' => { 'x' => 'y' },
|
631
|
-
'chef_environment' => 'desert'
|
632
|
-
)
|
633
|
-
end
|
634
|
-
|
635
|
-
it 'chef_node with attribute m, x and n, y adds both attributes' do
|
636
|
-
expect_recipe {
|
637
|
-
chef_node 'blah' do
|
638
|
-
attribute 'm', 'x'
|
639
|
-
attribute 'n', 'y'
|
640
|
-
end
|
641
|
-
}.to be_updated
|
642
|
-
expect(get('nodes/blah')).to include(
|
643
|
-
'normal' => {
|
644
|
-
'a' => 'b',
|
645
|
-
'c' => { 'd' => 'e' },
|
646
|
-
'm' => 'x',
|
647
|
-
'n' => 'y',
|
648
|
-
'tags' => [ 'a', 'b' ]
|
649
|
-
},
|
650
|
-
'automatic' => { 'x' => 'y' },
|
651
|
-
'chef_environment' => 'desert'
|
652
|
-
)
|
653
|
-
end
|
654
|
-
|
655
|
-
it 'chef_node with attribute [x, y], z and [x, yy], zz adds both attributes' do
|
656
|
-
expect_recipe {
|
657
|
-
chef_node 'blah' do
|
658
|
-
attribute [ 'x', 'y' ], 'z'
|
659
|
-
attribute [ 'x', 'yy' ], 'zz'
|
660
|
-
end
|
661
|
-
}.to be_updated
|
662
|
-
expect(get('nodes/blah')).to include(
|
663
|
-
'normal' => {
|
664
|
-
'a' => 'b',
|
665
|
-
'c' => { 'd' => 'e' },
|
666
|
-
'x' => {
|
667
|
-
'y' => 'z',
|
668
|
-
'yy' => 'zz'
|
669
|
-
},
|
670
|
-
'tags' => [ 'a', 'b' ]
|
671
|
-
},
|
672
|
-
'automatic' => { 'x' => 'y' },
|
673
|
-
'chef_environment' => 'desert'
|
674
|
-
)
|
675
|
-
end
|
676
|
-
|
677
|
-
describe 'precedence' do
|
678
|
-
it 'chef_node with attribute a, 1 and a, 2 sets a to 2' do
|
679
|
-
expect_recipe {
|
680
|
-
chef_node 'blah' do
|
681
|
-
attribute 'a', 1
|
682
|
-
attribute 'a', 2
|
683
|
-
end
|
684
|
-
}.to be_updated
|
685
|
-
expect(get('nodes/blah')).to include(
|
686
|
-
'normal' => {
|
687
|
-
'a' => 2,
|
688
|
-
'c' => { 'd' => 'e' },
|
689
|
-
'tags' => [ 'a', 'b' ]
|
690
|
-
},
|
691
|
-
'automatic' => { 'x' => 'y' },
|
692
|
-
'chef_environment' => 'desert'
|
693
|
-
)
|
694
|
-
end
|
695
|
-
|
696
|
-
it 'chef_node with attribute [ x, y ], 1 and [ x, y ], 2 sets [ x, y ], 2' do
|
697
|
-
expect_recipe {
|
698
|
-
chef_node 'blah' do
|
699
|
-
attribute [ 'x', 'y' ], 1
|
700
|
-
attribute [ 'x', 'y' ], 2
|
701
|
-
end
|
702
|
-
}.to be_updated
|
703
|
-
expect(get('nodes/blah')).to include(
|
704
|
-
'normal' => {
|
705
|
-
'a' => 'b',
|
706
|
-
'c' => { 'd' => 'e' },
|
707
|
-
'x' => { 'y' => 2 },
|
708
|
-
'tags' => [ 'a', 'b' ]
|
709
|
-
},
|
710
|
-
'automatic' => { 'x' => 'y' },
|
711
|
-
'chef_environment' => 'desert'
|
712
|
-
)
|
713
|
-
end
|
714
|
-
|
715
|
-
it 'chef_node with attribute [ c, e ], { a => 1 }, [ c, e ], { b => 2 } sets b only' do
|
716
|
-
expect_recipe {
|
717
|
-
chef_node 'blah' do
|
718
|
-
attribute [ 'c', 'e' ], { 'a' => 1 }
|
719
|
-
attribute [ 'c', 'e' ], { 'b' => 2 }
|
720
|
-
end
|
721
|
-
}.to be_updated
|
722
|
-
expect(get('nodes/blah')).to include(
|
723
|
-
'normal' => {
|
724
|
-
'a' => 'b',
|
725
|
-
'c' => { 'd' => 'e', 'e' => { 'b' => 2 } },
|
726
|
-
'tags' => [ 'a', 'b' ]
|
727
|
-
},
|
728
|
-
'automatic' => { 'x' => 'y' },
|
729
|
-
'chef_environment' => 'desert'
|
730
|
-
)
|
731
|
-
end
|
732
|
-
|
733
|
-
it 'chef_node with attribute [ c, e ], { a => 1 }, [ c, e, b ], 2 sets both' do
|
734
|
-
expect_recipe {
|
735
|
-
chef_node 'blah' do
|
736
|
-
attribute [ 'c', 'e' ], { 'a' => 1 }
|
737
|
-
attribute [ 'c', 'e', 'b' ], 2
|
738
|
-
end
|
739
|
-
}.to be_updated
|
740
|
-
expect(get('nodes/blah')).to include(
|
741
|
-
'normal' => {
|
742
|
-
'a' => 'b',
|
743
|
-
'c' => { 'd' => 'e', 'e' => { 'a' => 1, 'b' => 2 } },
|
744
|
-
'tags' => [ 'a', 'b' ]
|
745
|
-
},
|
746
|
-
'automatic' => { 'x' => 'y' },
|
747
|
-
'chef_environment' => 'desert'
|
748
|
-
)
|
749
|
-
end
|
750
|
-
|
751
|
-
it 'chef_node with attribute [ c, e, b ], 2, [ c, e ], { a => 1 } sets a only' do
|
752
|
-
expect_recipe {
|
753
|
-
chef_node 'blah' do
|
754
|
-
attribute [ 'c', 'e', 'b' ], 2
|
755
|
-
attribute [ 'c', 'e' ], { 'a' => 1 }
|
756
|
-
end
|
757
|
-
}.to be_updated
|
758
|
-
expect(get('nodes/blah')).to include(
|
759
|
-
'normal' => {
|
760
|
-
'a' => 'b',
|
761
|
-
'c' => { 'd' => 'e', 'e' => { 'a' => 1 } },
|
762
|
-
'tags' => [ 'a', 'b' ]
|
763
|
-
},
|
764
|
-
'automatic' => { 'x' => 'y' },
|
765
|
-
'chef_environment' => 'desert'
|
766
|
-
)
|
767
|
-
end
|
768
|
-
end
|
769
|
-
end
|
770
|
-
end
|
771
|
-
end
|
772
|
-
end
|
773
|
-
|
774
|
-
when_the_chef_server 'is in OSC mode' do
|
775
|
-
context 'and is empty' do
|
776
|
-
context 'and we run a recipe that creates node "blah"' do
|
777
|
-
it 'the node gets created' do
|
778
|
-
expect_recipe {
|
779
|
-
chef_node 'blah'
|
780
|
-
}.to have_updated 'chef_node[blah]', :create
|
781
|
-
expect(get('nodes/blah')['name']).to eq('blah')
|
782
|
-
end
|
783
|
-
end
|
784
|
-
end
|
785
|
-
end
|
786
|
-
end
|
1
|
+
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
3
|
+
require 'chef/resource/chef_node'
|
4
|
+
require 'chef/provider/chef_node'
|
5
|
+
|
6
|
+
describe Chef::Resource::ChefNode do
|
7
|
+
extend Cheffish::RSpec::ChefRunSupport
|
8
|
+
|
9
|
+
when_the_chef_12_server 'is in multi-org mode' do
|
10
|
+
organization 'foo'
|
11
|
+
|
12
|
+
before :each do
|
13
|
+
Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'and is empty' do
|
17
|
+
context 'and we run a recipe that creates node "blah"' do
|
18
|
+
it 'the node gets created' do
|
19
|
+
expect_recipe {
|
20
|
+
chef_node 'blah'
|
21
|
+
}.to have_updated 'chef_node[blah]', :create
|
22
|
+
expect(get('nodes/blah')['name']).to eq('blah')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# TODO why-run mode
|
27
|
+
|
28
|
+
context 'and another chef server is running on port 8899' do
|
29
|
+
before :each do
|
30
|
+
@server = ChefZero::Server.new(:port => 8899)
|
31
|
+
@server.start_background
|
32
|
+
end
|
33
|
+
|
34
|
+
after :each do
|
35
|
+
@server.stop
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'and a recipe is run that creates node "blah" on the second chef server using with_chef_server' do
|
39
|
+
|
40
|
+
it 'the node is created on the second chef server but not the first' do
|
41
|
+
expect_recipe {
|
42
|
+
with_chef_server 'http://127.0.0.1:8899'
|
43
|
+
chef_node 'blah'
|
44
|
+
}.to have_updated 'chef_node[blah]', :create
|
45
|
+
expect { get('nodes/blah') }.to raise_error(Net::HTTPServerException)
|
46
|
+
expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'and a recipe is run that creates node "blah" on the second chef server using chef_server' do
|
51
|
+
|
52
|
+
it 'the node is created on the second chef server but not the first' do
|
53
|
+
expect_recipe {
|
54
|
+
chef_node 'blah' do
|
55
|
+
chef_server({ :chef_server_url => 'http://127.0.0.1:8899' })
|
56
|
+
end
|
57
|
+
}.to have_updated 'chef_node[blah]', :create
|
58
|
+
expect { get('nodes/blah') }.to raise_error(Net::HTTPServerException)
|
59
|
+
expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'and has a node named "blah"' do
|
66
|
+
node 'blah', {}
|
67
|
+
|
68
|
+
it 'chef_node "blah" does not get created or updated' do
|
69
|
+
expect_recipe {
|
70
|
+
chef_node 'blah'
|
71
|
+
}.not_to have_updated 'chef_node[blah]', :create
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'and has a node named "blah" with tags' do
|
76
|
+
node 'blah', {
|
77
|
+
'normal' => { 'tags' => [ 'a', 'b' ] }
|
78
|
+
}
|
79
|
+
|
80
|
+
context 'with chef_node "blah" that sets attributes' do
|
81
|
+
with_converge do
|
82
|
+
chef_node 'blah' do
|
83
|
+
attributes({})
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'the tags in attributes are used' do
|
88
|
+
expect(get('nodes/blah')['normal']['tags']).to eq([ 'a', 'b' ])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with chef_node "blah" that sets attributes with tags in them' do
|
93
|
+
with_converge do
|
94
|
+
chef_node 'blah' do
|
95
|
+
attributes 'tags' => [ 'c', 'd' ]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'the tags in attributes are used' do
|
100
|
+
expect(get('nodes/blah')['normal']['tags']).to eq([ 'c', 'd' ])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#complete' do
|
106
|
+
context 'when the Chef server has a node named "blah" with everything in it' do
|
107
|
+
node 'blah', {
|
108
|
+
'chef_environment' => 'blah',
|
109
|
+
'run_list' => [ 'recipe[bjork]' ],
|
110
|
+
'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
|
111
|
+
'default' => { 'foo2' => 'bar2' },
|
112
|
+
'automatic' => { 'foo3' => 'bar3' },
|
113
|
+
'override' => { 'foo4' => 'bar4' }
|
114
|
+
}
|
115
|
+
|
116
|
+
it 'chef_node with no attributes modifies nothing' do
|
117
|
+
expect_recipe {
|
118
|
+
chef_node 'blah'
|
119
|
+
}.to be_up_to_date
|
120
|
+
expect(get('nodes/blah')).to include(
|
121
|
+
'name' => 'blah',
|
122
|
+
'chef_environment' => 'blah',
|
123
|
+
'run_list' => [ 'recipe[bjork]' ],
|
124
|
+
'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
|
125
|
+
'default' => { 'foo2' => 'bar2' },
|
126
|
+
'automatic' => { 'foo3' => 'bar3' },
|
127
|
+
'override' => { 'foo4' => 'bar4' }
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'chef_node with complete true removes everything except default, automatic and override' do
|
132
|
+
expect_recipe {
|
133
|
+
chef_node 'blah' do
|
134
|
+
complete true
|
135
|
+
end
|
136
|
+
}.to be_updated
|
137
|
+
expect(get('nodes/blah')).to include(
|
138
|
+
'name' => 'blah',
|
139
|
+
'chef_environment' => '_default',
|
140
|
+
'run_list' => [ ],
|
141
|
+
'normal' => { 'tags' => [ 'a', 'b' ] },
|
142
|
+
'default' => { 'foo2' => 'bar2' },
|
143
|
+
'automatic' => { 'foo3' => 'bar3' },
|
144
|
+
'override' => { 'foo4' => 'bar4' }
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'chef_node with complete true sets the given attributes' do
|
149
|
+
expect_recipe {
|
150
|
+
chef_node 'blah' do
|
151
|
+
chef_environment 'x'
|
152
|
+
run_list [ 'recipe[y]' ]
|
153
|
+
attributes 'a' => 'b'
|
154
|
+
tags 'c', 'd'
|
155
|
+
complete true
|
156
|
+
end
|
157
|
+
}.to be_updated
|
158
|
+
expect(get('nodes/blah')).to include(
|
159
|
+
'name' => 'blah',
|
160
|
+
'chef_environment' => 'x',
|
161
|
+
'run_list' => [ 'recipe[y]' ],
|
162
|
+
'normal' => { 'a' => 'b', 'tags' => [ 'c', 'd' ] },
|
163
|
+
'default' => { 'foo2' => 'bar2' },
|
164
|
+
'automatic' => { 'foo3' => 'bar3' },
|
165
|
+
'override' => { 'foo4' => 'bar4' }
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'chef_node with complete true and partial attributes sets the given attributes' do
|
170
|
+
expect_recipe {
|
171
|
+
chef_node 'blah' do
|
172
|
+
chef_environment 'x'
|
173
|
+
recipe 'y'
|
174
|
+
attribute 'a', 'b'
|
175
|
+
tags 'c', 'd'
|
176
|
+
complete true
|
177
|
+
end
|
178
|
+
}.to be_updated
|
179
|
+
expect(get('nodes/blah')).to include(
|
180
|
+
'name' => 'blah',
|
181
|
+
'chef_environment' => 'x',
|
182
|
+
'run_list' => [ 'recipe[y]' ],
|
183
|
+
'normal' => { 'a' => 'b', 'tags' => [ 'c', 'd' ] },
|
184
|
+
'default' => { 'foo2' => 'bar2' },
|
185
|
+
'automatic' => { 'foo3' => 'bar3' },
|
186
|
+
'override' => { 'foo4' => 'bar4' }
|
187
|
+
)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '#attributes' do
|
193
|
+
context 'with a node with normal attributes a => b and c => { d => e }' do
|
194
|
+
node 'blah', {
|
195
|
+
'normal' => {
|
196
|
+
'a' => 'b',
|
197
|
+
'c' => { 'd' => 'e' },
|
198
|
+
'tags' => [ 'a', 'b' ]
|
199
|
+
},
|
200
|
+
'automatic' => {
|
201
|
+
'x' => 'y'
|
202
|
+
},
|
203
|
+
'chef_environment' => 'desert'
|
204
|
+
}
|
205
|
+
|
206
|
+
it 'chef_node with attributes {} removes all normal attributes but leaves tags, automatic and environment alone' do
|
207
|
+
expect_recipe {
|
208
|
+
chef_node 'blah' do
|
209
|
+
attributes({})
|
210
|
+
end
|
211
|
+
}.to have_updated('chef_node[blah]', :create)
|
212
|
+
expect(get('nodes/blah')).to include(
|
213
|
+
'normal' => { 'tags' => [ 'a', 'b' ] },
|
214
|
+
'automatic' => { 'x' => 'y' },
|
215
|
+
'chef_environment' => 'desert'
|
216
|
+
)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'chef_node with attributes { c => d } replaces normal but not tags/automatic/environment' do
|
220
|
+
expect_recipe {
|
221
|
+
chef_node 'blah' do
|
222
|
+
attributes 'c' => 'd'
|
223
|
+
end
|
224
|
+
}.to have_updated('chef_node[blah]', :create)
|
225
|
+
expect(get('nodes/blah')).to include(
|
226
|
+
'normal' => { 'c' => 'd', 'tags' => [ 'a', 'b' ] },
|
227
|
+
'automatic' => { 'x' => 'y' },
|
228
|
+
'chef_environment' => 'desert'
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'chef_node with attributes { c => f => g, y => z } replaces normal but not tags/automatic/environment' do
|
233
|
+
expect_recipe {
|
234
|
+
chef_node 'blah' do
|
235
|
+
attributes 'c' => { 'f' => 'g' }, 'y' => 'z'
|
236
|
+
end
|
237
|
+
}.to have_updated('chef_node[blah]', :create)
|
238
|
+
expect(get('nodes/blah')).to include(
|
239
|
+
'normal' => { 'c' => { 'f' => 'g' }, 'y' => 'z', 'tags' => [ 'a', 'b' ] },
|
240
|
+
'automatic' => { 'x' => 'y' },
|
241
|
+
'chef_environment' => 'desert'
|
242
|
+
)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'chef_node with attributes { tags => [ "x" ] } replaces normal and tags but not automatic/environment' do
|
246
|
+
expect_recipe {
|
247
|
+
chef_node 'blah' do
|
248
|
+
attributes 'tags' => [ 'x' ]
|
249
|
+
end
|
250
|
+
}.to have_updated('chef_node[blah]', :create)
|
251
|
+
expect(get('nodes/blah')).to include(
|
252
|
+
'normal' => { 'tags' => [ 'x' ] },
|
253
|
+
'automatic' => { 'x' => 'y' },
|
254
|
+
'chef_environment' => 'desert'
|
255
|
+
)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'chef_node with tags "x" and attributes { "tags" => [ "y" ] } sets tags to "x"' do
|
259
|
+
expect_recipe {
|
260
|
+
chef_node 'blah' do
|
261
|
+
tags 'x'
|
262
|
+
attributes 'tags' => [ 'y' ]
|
263
|
+
end
|
264
|
+
}.to have_updated('chef_node[blah]', :create)
|
265
|
+
expect(get('nodes/blah')).to include(
|
266
|
+
'normal' => {
|
267
|
+
'tags' => [ 'x' ]
|
268
|
+
},
|
269
|
+
'automatic' => { 'x' => 'y' },
|
270
|
+
'chef_environment' => 'desert'
|
271
|
+
)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
describe '#attribute' do
|
277
|
+
context 'with a node with normal attributes a => b and c => { d => e }' do
|
278
|
+
node 'blah', {
|
279
|
+
'normal' => {
|
280
|
+
'a' => 'b',
|
281
|
+
'c' => { 'd' => 'e' },
|
282
|
+
'tags' => [ 'a', 'b' ]
|
283
|
+
},
|
284
|
+
'automatic' => {
|
285
|
+
'x' => 'y'
|
286
|
+
},
|
287
|
+
'chef_environment' => 'desert'
|
288
|
+
}
|
289
|
+
|
290
|
+
context 'basic scenarios' do
|
291
|
+
it 'chef_node with no attributes, leaves it alone' do
|
292
|
+
expect_recipe {
|
293
|
+
chef_node 'blah'
|
294
|
+
}.not_to have_updated('chef_node[blah]', :create)
|
295
|
+
expect(get('nodes/blah')).to include(
|
296
|
+
'normal' => {
|
297
|
+
'a' => 'b',
|
298
|
+
'c' => { 'd' => 'e' },
|
299
|
+
'tags' => [ 'a', 'b' ]
|
300
|
+
},
|
301
|
+
'automatic' => { 'x' => 'y' },
|
302
|
+
'chef_environment' => 'desert'
|
303
|
+
)
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'chef_node with attribute d, e adds the attribute' do
|
307
|
+
expect_recipe {
|
308
|
+
chef_node 'blah' do
|
309
|
+
attribute 'd', 'e'
|
310
|
+
end
|
311
|
+
}.to have_updated('chef_node[blah]', :create)
|
312
|
+
expect(get('nodes/blah')).to include(
|
313
|
+
'normal' => {
|
314
|
+
'a' => 'b',
|
315
|
+
'c' => { 'd' => 'e' },
|
316
|
+
'd' => 'e',
|
317
|
+
'tags' => [ 'a', 'b' ]
|
318
|
+
},
|
319
|
+
'automatic' => { 'x' => 'y' },
|
320
|
+
'chef_environment' => 'desert'
|
321
|
+
)
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'chef_node with attribute tags, [ "x" ] replaces tags' do
|
325
|
+
expect_recipe {
|
326
|
+
chef_node 'blah' do
|
327
|
+
attribute 'tags', [ 'x' ]
|
328
|
+
end
|
329
|
+
}.to have_updated('chef_node[blah]', :create)
|
330
|
+
expect(get('nodes/blah')).to include(
|
331
|
+
'normal' => {
|
332
|
+
'a' => 'b',
|
333
|
+
'c' => { 'd' => 'e' },
|
334
|
+
'tags' => [ 'x' ]
|
335
|
+
},
|
336
|
+
'automatic' => { 'x' => 'y' },
|
337
|
+
'chef_environment' => 'desert'
|
338
|
+
)
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'chef_node with attribute c, x replaces the attribute' do
|
342
|
+
expect_recipe {
|
343
|
+
chef_node 'blah' do
|
344
|
+
attribute 'c', 'x'
|
345
|
+
end
|
346
|
+
}.to have_updated('chef_node[blah]', :create)
|
347
|
+
expect(get('nodes/blah')).to include(
|
348
|
+
'normal' => {
|
349
|
+
'a' => 'b',
|
350
|
+
'c' => 'x',
|
351
|
+
'tags' => [ 'a', 'b' ]
|
352
|
+
},
|
353
|
+
'automatic' => { 'x' => 'y' },
|
354
|
+
'chef_environment' => 'desert'
|
355
|
+
)
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'chef_node with attribute c, { d => x } replaces the attribute' do
|
359
|
+
expect_recipe {
|
360
|
+
chef_node 'blah' do
|
361
|
+
attribute 'c', { 'd' => 'x' }
|
362
|
+
end
|
363
|
+
}.to have_updated('chef_node[blah]', :create)
|
364
|
+
expect(get('nodes/blah')).to include(
|
365
|
+
'normal' => {
|
366
|
+
'a' => 'b',
|
367
|
+
'c' => { 'd' => 'x' },
|
368
|
+
'tags' => [ 'a', 'b' ]
|
369
|
+
},
|
370
|
+
'automatic' => { 'x' => 'y' },
|
371
|
+
'chef_environment' => 'desert'
|
372
|
+
)
|
373
|
+
end
|
374
|
+
|
375
|
+
it 'chef_node with attribute [ c, d ], x replaces the attribute' do
|
376
|
+
expect_recipe {
|
377
|
+
chef_node 'blah' do
|
378
|
+
attribute [ 'c', 'd' ], 'x'
|
379
|
+
end
|
380
|
+
}.to have_updated('chef_node[blah]', :create)
|
381
|
+
expect(get('nodes/blah')).to include(
|
382
|
+
'normal' => {
|
383
|
+
'a' => 'b',
|
384
|
+
'c' => { 'd' => 'x' },
|
385
|
+
'tags' => [ 'a', 'b' ]
|
386
|
+
},
|
387
|
+
'automatic' => { 'x' => 'y' },
|
388
|
+
'chef_environment' => 'desert'
|
389
|
+
)
|
390
|
+
end
|
391
|
+
|
392
|
+
it 'chef_node with attribute [ a, b ], x raises an error' do
|
393
|
+
expect {
|
394
|
+
converge {
|
395
|
+
chef_node 'blah' do
|
396
|
+
attribute [ 'a', 'b' ], 'x'
|
397
|
+
end
|
398
|
+
}
|
399
|
+
}.to raise_error /Attempt to set \["a", "b"\] to x when \["a"\] is not a hash/
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'chef_node with attribute [ a, b, c ], x raises an error' do
|
403
|
+
expect {
|
404
|
+
converge {
|
405
|
+
chef_node 'blah' do
|
406
|
+
attribute [ 'a', 'b', 'c' ], 'x'
|
407
|
+
end
|
408
|
+
}
|
409
|
+
}.to raise_error /Attempt to set \["a", "b", "c"\] to x when \["a"\] is not a hash/
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'chef_node with attribute [ x, y ], z adds a new attribute' do
|
413
|
+
expect_recipe {
|
414
|
+
chef_node 'blah' do
|
415
|
+
attribute [ 'x', 'y' ], 'z'
|
416
|
+
end
|
417
|
+
}.to have_updated('chef_node[blah]', :create)
|
418
|
+
expect(get('nodes/blah')).to include(
|
419
|
+
'normal' => {
|
420
|
+
'a' => 'b',
|
421
|
+
'c' => { 'd' => 'e' },
|
422
|
+
'x' => { 'y' => 'z' },
|
423
|
+
'tags' => [ 'a', 'b' ]
|
424
|
+
},
|
425
|
+
'automatic' => { 'x' => 'y' },
|
426
|
+
'chef_environment' => 'desert'
|
427
|
+
)
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'chef_node with attribute [], {} clears all attributes' do
|
431
|
+
expect_recipe {
|
432
|
+
chef_node 'blah' do
|
433
|
+
attribute([], {})
|
434
|
+
end
|
435
|
+
}.to have_updated('chef_node[blah]', :create)
|
436
|
+
expect(get('nodes/blah')).to include(
|
437
|
+
'normal' => { },
|
438
|
+
'automatic' => { 'x' => 'y' },
|
439
|
+
'chef_environment' => 'desert'
|
440
|
+
)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
context 'delete' do
|
445
|
+
it 'chef_node with attribute a, :delete deletes the attribute' do
|
446
|
+
expect_recipe {
|
447
|
+
chef_node 'blah' do
|
448
|
+
attribute 'a', :delete
|
449
|
+
end
|
450
|
+
}.to have_updated('chef_node[blah]', :create)
|
451
|
+
expect(get('nodes/blah')).to include(
|
452
|
+
'normal' => {
|
453
|
+
'c' => { 'd' => 'e' },
|
454
|
+
'tags' => [ 'a', 'b' ]
|
455
|
+
},
|
456
|
+
'automatic' => { 'x' => 'y' },
|
457
|
+
'chef_environment' => 'desert'
|
458
|
+
)
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'chef_node with attribute c, :delete deletes the attribute' do
|
462
|
+
expect_recipe {
|
463
|
+
chef_node 'blah' do
|
464
|
+
attribute 'c', :delete
|
465
|
+
end
|
466
|
+
}.to have_updated('chef_node[blah]', :create)
|
467
|
+
expect(get('nodes/blah')).to include(
|
468
|
+
'normal' => {
|
469
|
+
'a' => 'b',
|
470
|
+
'tags' => [ 'a', 'b' ]
|
471
|
+
},
|
472
|
+
'automatic' => { 'x' => 'y' },
|
473
|
+
'chef_environment' => 'desert'
|
474
|
+
)
|
475
|
+
end
|
476
|
+
|
477
|
+
it 'chef_node with attribute [ c, d ], :delete deletes the attribute' do
|
478
|
+
expect_recipe {
|
479
|
+
chef_node 'blah' do
|
480
|
+
attribute [ 'c', 'd' ], :delete
|
481
|
+
end
|
482
|
+
}.to have_updated('chef_node[blah]', :create)
|
483
|
+
expect(get('nodes/blah')).to include(
|
484
|
+
'normal' => {
|
485
|
+
'a' => 'b',
|
486
|
+
'c' => {},
|
487
|
+
'tags' => [ 'a', 'b' ]
|
488
|
+
},
|
489
|
+
'automatic' => { 'x' => 'y' },
|
490
|
+
'chef_environment' => 'desert'
|
491
|
+
)
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'chef_node with attribute xyz, :delete does nothing' do
|
495
|
+
expect_recipe {
|
496
|
+
chef_node 'blah' do
|
497
|
+
attribute 'xyz', :delete
|
498
|
+
end
|
499
|
+
}.not_to have_updated('chef_node[blah]', :create)
|
500
|
+
expect(get('nodes/blah')).to include(
|
501
|
+
'normal' => {
|
502
|
+
'a' => 'b',
|
503
|
+
'c' => { 'd' => 'e' },
|
504
|
+
'tags' => [ 'a', 'b' ]
|
505
|
+
},
|
506
|
+
'automatic' => { 'x' => 'y' },
|
507
|
+
'chef_environment' => 'desert'
|
508
|
+
)
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'chef_node with attribute [ c, x ], :delete does nothing' do
|
512
|
+
expect_recipe {
|
513
|
+
chef_node 'blah' do
|
514
|
+
attribute [ 'c', 'x' ], :delete
|
515
|
+
end
|
516
|
+
}.not_to have_updated('chef_node[blah]', :create)
|
517
|
+
expect(get('nodes/blah')).to include(
|
518
|
+
'normal' => {
|
519
|
+
'a' => 'b',
|
520
|
+
'c' => { 'd' => 'e' },
|
521
|
+
'tags' => [ 'a', 'b' ]
|
522
|
+
},
|
523
|
+
'automatic' => { 'x' => 'y' },
|
524
|
+
'chef_environment' => 'desert'
|
525
|
+
)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
context 'types' do
|
530
|
+
it 'chef_node with attribute a, true sets a to true' do
|
531
|
+
expect_recipe {
|
532
|
+
chef_node 'blah' do
|
533
|
+
attribute 'a', true
|
534
|
+
end
|
535
|
+
}.to be_updated
|
536
|
+
expect(get('nodes/blah')).to include(
|
537
|
+
'normal' => {
|
538
|
+
'a' => true,
|
539
|
+
'c' => { 'd' => 'e' },
|
540
|
+
'tags' => [ 'a', 'b' ]
|
541
|
+
},
|
542
|
+
'automatic' => { 'x' => 'y' },
|
543
|
+
'chef_environment' => 'desert'
|
544
|
+
)
|
545
|
+
end
|
546
|
+
|
547
|
+
it 'chef_node with attribute a, 1 sets a to 1' do
|
548
|
+
expect_recipe {
|
549
|
+
chef_node 'blah' do
|
550
|
+
attribute 'a', 1
|
551
|
+
end
|
552
|
+
}.to be_updated
|
553
|
+
expect(get('nodes/blah')).to include(
|
554
|
+
'normal' => {
|
555
|
+
'a' => 1,
|
556
|
+
'c' => { 'd' => 'e' },
|
557
|
+
'tags' => [ 'a', 'b' ]
|
558
|
+
},
|
559
|
+
'automatic' => { 'x' => 'y' },
|
560
|
+
'chef_environment' => 'desert'
|
561
|
+
)
|
562
|
+
end
|
563
|
+
|
564
|
+
it 'chef_node with attribute a, "1" sets a to "1"' do
|
565
|
+
expect_recipe {
|
566
|
+
chef_node 'blah' do
|
567
|
+
attribute 'a', "1"
|
568
|
+
end
|
569
|
+
}.to be_updated
|
570
|
+
expect(get('nodes/blah')).to include(
|
571
|
+
'normal' => {
|
572
|
+
'a' => "1",
|
573
|
+
'c' => { 'd' => 'e' },
|
574
|
+
'tags' => [ 'a', 'b' ]
|
575
|
+
},
|
576
|
+
'automatic' => { 'x' => 'y' },
|
577
|
+
'chef_environment' => 'desert'
|
578
|
+
)
|
579
|
+
end
|
580
|
+
|
581
|
+
it 'chef_node with attribute a, "" sets a to ""' do
|
582
|
+
expect_recipe {
|
583
|
+
chef_node 'blah' do
|
584
|
+
attribute 'a', ""
|
585
|
+
end
|
586
|
+
}.to be_updated
|
587
|
+
expect(get('nodes/blah')).to include(
|
588
|
+
'normal' => {
|
589
|
+
'a' => "",
|
590
|
+
'c' => { 'd' => 'e' },
|
591
|
+
'tags' => [ 'a', 'b' ]
|
592
|
+
},
|
593
|
+
'automatic' => { 'x' => 'y' },
|
594
|
+
'chef_environment' => 'desert'
|
595
|
+
)
|
596
|
+
end
|
597
|
+
|
598
|
+
it 'chef_node with attribute a, nil sets a to nil' do
|
599
|
+
expect_recipe {
|
600
|
+
chef_node 'blah' do
|
601
|
+
attribute 'a', nil
|
602
|
+
end
|
603
|
+
}.to be_updated
|
604
|
+
expect(get('nodes/blah')).to include(
|
605
|
+
'normal' => {
|
606
|
+
'a' => nil,
|
607
|
+
'c' => { 'd' => 'e' },
|
608
|
+
'tags' => [ 'a', 'b' ]
|
609
|
+
},
|
610
|
+
'automatic' => { 'x' => 'y' },
|
611
|
+
'chef_environment' => 'desert'
|
612
|
+
)
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
context 'multiple attribute definitions' do
|
617
|
+
it 'chef_node with attribute a, x and c, y replaces both attributes' do
|
618
|
+
expect_recipe {
|
619
|
+
chef_node 'blah' do
|
620
|
+
attribute 'a', 'x'
|
621
|
+
attribute 'c', 'y'
|
622
|
+
end
|
623
|
+
}.to be_updated
|
624
|
+
expect(get('nodes/blah')).to include(
|
625
|
+
'normal' => {
|
626
|
+
'a' => 'x',
|
627
|
+
'c' => 'y',
|
628
|
+
'tags' => [ 'a', 'b' ]
|
629
|
+
},
|
630
|
+
'automatic' => { 'x' => 'y' },
|
631
|
+
'chef_environment' => 'desert'
|
632
|
+
)
|
633
|
+
end
|
634
|
+
|
635
|
+
it 'chef_node with attribute m, x and n, y adds both attributes' do
|
636
|
+
expect_recipe {
|
637
|
+
chef_node 'blah' do
|
638
|
+
attribute 'm', 'x'
|
639
|
+
attribute 'n', 'y'
|
640
|
+
end
|
641
|
+
}.to be_updated
|
642
|
+
expect(get('nodes/blah')).to include(
|
643
|
+
'normal' => {
|
644
|
+
'a' => 'b',
|
645
|
+
'c' => { 'd' => 'e' },
|
646
|
+
'm' => 'x',
|
647
|
+
'n' => 'y',
|
648
|
+
'tags' => [ 'a', 'b' ]
|
649
|
+
},
|
650
|
+
'automatic' => { 'x' => 'y' },
|
651
|
+
'chef_environment' => 'desert'
|
652
|
+
)
|
653
|
+
end
|
654
|
+
|
655
|
+
it 'chef_node with attribute [x, y], z and [x, yy], zz adds both attributes' do
|
656
|
+
expect_recipe {
|
657
|
+
chef_node 'blah' do
|
658
|
+
attribute [ 'x', 'y' ], 'z'
|
659
|
+
attribute [ 'x', 'yy' ], 'zz'
|
660
|
+
end
|
661
|
+
}.to be_updated
|
662
|
+
expect(get('nodes/blah')).to include(
|
663
|
+
'normal' => {
|
664
|
+
'a' => 'b',
|
665
|
+
'c' => { 'd' => 'e' },
|
666
|
+
'x' => {
|
667
|
+
'y' => 'z',
|
668
|
+
'yy' => 'zz'
|
669
|
+
},
|
670
|
+
'tags' => [ 'a', 'b' ]
|
671
|
+
},
|
672
|
+
'automatic' => { 'x' => 'y' },
|
673
|
+
'chef_environment' => 'desert'
|
674
|
+
)
|
675
|
+
end
|
676
|
+
|
677
|
+
describe 'precedence' do
|
678
|
+
it 'chef_node with attribute a, 1 and a, 2 sets a to 2' do
|
679
|
+
expect_recipe {
|
680
|
+
chef_node 'blah' do
|
681
|
+
attribute 'a', 1
|
682
|
+
attribute 'a', 2
|
683
|
+
end
|
684
|
+
}.to be_updated
|
685
|
+
expect(get('nodes/blah')).to include(
|
686
|
+
'normal' => {
|
687
|
+
'a' => 2,
|
688
|
+
'c' => { 'd' => 'e' },
|
689
|
+
'tags' => [ 'a', 'b' ]
|
690
|
+
},
|
691
|
+
'automatic' => { 'x' => 'y' },
|
692
|
+
'chef_environment' => 'desert'
|
693
|
+
)
|
694
|
+
end
|
695
|
+
|
696
|
+
it 'chef_node with attribute [ x, y ], 1 and [ x, y ], 2 sets [ x, y ], 2' do
|
697
|
+
expect_recipe {
|
698
|
+
chef_node 'blah' do
|
699
|
+
attribute [ 'x', 'y' ], 1
|
700
|
+
attribute [ 'x', 'y' ], 2
|
701
|
+
end
|
702
|
+
}.to be_updated
|
703
|
+
expect(get('nodes/blah')).to include(
|
704
|
+
'normal' => {
|
705
|
+
'a' => 'b',
|
706
|
+
'c' => { 'd' => 'e' },
|
707
|
+
'x' => { 'y' => 2 },
|
708
|
+
'tags' => [ 'a', 'b' ]
|
709
|
+
},
|
710
|
+
'automatic' => { 'x' => 'y' },
|
711
|
+
'chef_environment' => 'desert'
|
712
|
+
)
|
713
|
+
end
|
714
|
+
|
715
|
+
it 'chef_node with attribute [ c, e ], { a => 1 }, [ c, e ], { b => 2 } sets b only' do
|
716
|
+
expect_recipe {
|
717
|
+
chef_node 'blah' do
|
718
|
+
attribute [ 'c', 'e' ], { 'a' => 1 }
|
719
|
+
attribute [ 'c', 'e' ], { 'b' => 2 }
|
720
|
+
end
|
721
|
+
}.to be_updated
|
722
|
+
expect(get('nodes/blah')).to include(
|
723
|
+
'normal' => {
|
724
|
+
'a' => 'b',
|
725
|
+
'c' => { 'd' => 'e', 'e' => { 'b' => 2 } },
|
726
|
+
'tags' => [ 'a', 'b' ]
|
727
|
+
},
|
728
|
+
'automatic' => { 'x' => 'y' },
|
729
|
+
'chef_environment' => 'desert'
|
730
|
+
)
|
731
|
+
end
|
732
|
+
|
733
|
+
it 'chef_node with attribute [ c, e ], { a => 1 }, [ c, e, b ], 2 sets both' do
|
734
|
+
expect_recipe {
|
735
|
+
chef_node 'blah' do
|
736
|
+
attribute [ 'c', 'e' ], { 'a' => 1 }
|
737
|
+
attribute [ 'c', 'e', 'b' ], 2
|
738
|
+
end
|
739
|
+
}.to be_updated
|
740
|
+
expect(get('nodes/blah')).to include(
|
741
|
+
'normal' => {
|
742
|
+
'a' => 'b',
|
743
|
+
'c' => { 'd' => 'e', 'e' => { 'a' => 1, 'b' => 2 } },
|
744
|
+
'tags' => [ 'a', 'b' ]
|
745
|
+
},
|
746
|
+
'automatic' => { 'x' => 'y' },
|
747
|
+
'chef_environment' => 'desert'
|
748
|
+
)
|
749
|
+
end
|
750
|
+
|
751
|
+
it 'chef_node with attribute [ c, e, b ], 2, [ c, e ], { a => 1 } sets a only' do
|
752
|
+
expect_recipe {
|
753
|
+
chef_node 'blah' do
|
754
|
+
attribute [ 'c', 'e', 'b' ], 2
|
755
|
+
attribute [ 'c', 'e' ], { 'a' => 1 }
|
756
|
+
end
|
757
|
+
}.to be_updated
|
758
|
+
expect(get('nodes/blah')).to include(
|
759
|
+
'normal' => {
|
760
|
+
'a' => 'b',
|
761
|
+
'c' => { 'd' => 'e', 'e' => { 'a' => 1 } },
|
762
|
+
'tags' => [ 'a', 'b' ]
|
763
|
+
},
|
764
|
+
'automatic' => { 'x' => 'y' },
|
765
|
+
'chef_environment' => 'desert'
|
766
|
+
)
|
767
|
+
end
|
768
|
+
end
|
769
|
+
end
|
770
|
+
end
|
771
|
+
end
|
772
|
+
end
|
773
|
+
|
774
|
+
when_the_chef_server 'is in OSC mode' do
|
775
|
+
context 'and is empty' do
|
776
|
+
context 'and we run a recipe that creates node "blah"' do
|
777
|
+
it 'the node gets created' do
|
778
|
+
expect_recipe {
|
779
|
+
chef_node 'blah'
|
780
|
+
}.to have_updated 'chef_node[blah]', :create
|
781
|
+
expect(get('nodes/blah')['name']).to eq('blah')
|
782
|
+
end
|
783
|
+
end
|
784
|
+
end
|
785
|
+
end
|
786
|
+
end
|