cheffish 1.4.1 → 1.4.2

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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +120 -120
  4. data/Rakefile +23 -23
  5. data/lib/chef/provider/chef_acl.rb +439 -439
  6. data/lib/chef/provider/chef_client.rb +53 -53
  7. data/lib/chef/provider/chef_container.rb +55 -55
  8. data/lib/chef/provider/chef_data_bag.rb +55 -55
  9. data/lib/chef/provider/chef_data_bag_item.rb +278 -278
  10. data/lib/chef/provider/chef_environment.rb +83 -83
  11. data/lib/chef/provider/chef_group.rb +83 -83
  12. data/lib/chef/provider/chef_mirror.rb +169 -169
  13. data/lib/chef/provider/chef_node.rb +87 -87
  14. data/lib/chef/provider/chef_organization.rb +155 -155
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -46
  16. data/lib/chef/provider/chef_role.rb +84 -84
  17. data/lib/chef/provider/chef_user.rb +59 -59
  18. data/lib/chef/provider/private_key.rb +225 -225
  19. data/lib/chef/provider/public_key.rb +88 -88
  20. data/lib/chef/resource/chef_acl.rb +69 -69
  21. data/lib/chef/resource/chef_client.rb +48 -48
  22. data/lib/chef/resource/chef_container.rb +22 -22
  23. data/lib/chef/resource/chef_data_bag.rb +22 -22
  24. data/lib/chef/resource/chef_data_bag_item.rb +121 -121
  25. data/lib/chef/resource/chef_environment.rb +77 -77
  26. data/lib/chef/resource/chef_group.rb +53 -53
  27. data/lib/chef/resource/chef_mirror.rb +52 -52
  28. data/lib/chef/resource/chef_node.rb +22 -22
  29. data/lib/chef/resource/chef_organization.rb +69 -69
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -35
  31. data/lib/chef/resource/chef_role.rb +110 -110
  32. data/lib/chef/resource/chef_user.rb +56 -56
  33. data/lib/chef/resource/private_key.rb +48 -48
  34. data/lib/chef/resource/public_key.rb +25 -25
  35. data/lib/cheffish/actor_provider_base.rb +131 -131
  36. data/lib/cheffish/basic_chef_client.rb +184 -184
  37. data/lib/cheffish/chef_provider_base.rb +246 -246
  38. data/lib/cheffish/chef_run.rb +162 -162
  39. data/lib/cheffish/chef_run_data.rb +19 -19
  40. data/lib/cheffish/chef_run_listener.rb +30 -30
  41. data/lib/cheffish/key_formatter.rb +113 -113
  42. data/lib/cheffish/merged_config.rb +94 -94
  43. data/lib/cheffish/recipe_dsl.rb +157 -157
  44. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  45. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  46. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  47. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  48. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  49. data/lib/cheffish/rspec/matchers.rb +4 -4
  50. data/lib/cheffish/rspec/recipe_run_wrapper.rb +78 -59
  51. data/lib/cheffish/rspec/repository_support.rb +108 -108
  52. data/lib/cheffish/rspec.rb +8 -8
  53. data/lib/cheffish/server_api.rb +52 -52
  54. data/lib/cheffish/version.rb +3 -3
  55. data/lib/cheffish/with_pattern.rb +21 -21
  56. data/lib/cheffish.rb +235 -235
  57. data/spec/functional/fingerprint_spec.rb +64 -64
  58. data/spec/functional/merged_config_spec.rb +19 -19
  59. data/spec/functional/server_api_spec.rb +13 -13
  60. data/spec/integration/chef_acl_spec.rb +879 -879
  61. data/spec/integration/chef_client_spec.rb +105 -105
  62. data/spec/integration/chef_container_spec.rb +33 -33
  63. data/spec/integration/chef_group_spec.rb +309 -309
  64. data/spec/integration/chef_mirror_spec.rb +491 -491
  65. data/spec/integration/chef_node_spec.rb +786 -786
  66. data/spec/integration/chef_organization_spec.rb +226 -226
  67. data/spec/integration/chef_role_spec.rb +78 -78
  68. data/spec/integration/chef_user_spec.rb +85 -85
  69. data/spec/integration/private_key_spec.rb +399 -399
  70. data/spec/integration/recipe_dsl_spec.rb +28 -28
  71. data/spec/integration/rspec/converge_spec.rb +183 -183
  72. data/spec/support/key_support.rb +29 -29
  73. data/spec/support/spec_support.rb +15 -15
  74. data/spec/unit/get_private_key_spec.rb +131 -131
  75. data/spec/unit/recipe_run_wrapper_spec.rb +37 -37
  76. metadata +3 -2
@@ -1,491 +1,491 @@
1
- require 'support/spec_support'
2
- require 'cheffish/rspec/chef_run_support'
3
- require 'chef/resource/chef_mirror'
4
- require 'chef/provider/chef_mirror'
5
-
6
- describe Chef::Resource::ChefMirror 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
- describe 'basic download and upload' do
17
- when_the_repository 'is full of stuff' do
18
- file 'nodes/x.json', {}
19
- file 'roles/x.json', {}
20
- directory 'cookbooks/x' do
21
- file 'metadata.rb', 'name "x"; version "2.0.0"'
22
- end
23
-
24
- it "Download grabs defaults" do
25
- expect_recipe {
26
- chef_mirror '' do
27
- action :download
28
- end
29
- }.to have_updated('chef_mirror[]', :download)
30
- expect(File.exist?(path_to('groups/admins.json'))).to be true
31
- expect(File.exist?(path_to('environments/_default.json'))).to be true
32
- end
33
-
34
- it "Upload uploads everything" do
35
- expect_recipe {
36
- chef_mirror '' do
37
- action :upload
38
- end
39
- }.to have_updated('chef_mirror[]', :upload)
40
- expect { get('nodes/x') }.not_to raise_error
41
- expect { get('roles/x') }.not_to raise_error
42
- expect { get('cookbooks/x/2.0.0') }.not_to raise_error
43
- end
44
-
45
- it 'chef_mirror with concurrency 0 fails with a reasonable message' do
46
- expect {
47
- converge {
48
- chef_mirror '' do
49
- concurrency 0
50
- action :download
51
- end
52
- }
53
- }.to raise_error /chef_mirror.concurrency must be above 0/
54
- end
55
- end
56
- end
57
-
58
- context 'and the Chef server has a node and role in it' do
59
- node 'x', {}
60
- role 'x', {}
61
-
62
- when_the_repository 'is empty' do
63
- it "Download grabs the node and role" do
64
- expect_recipe {
65
- chef_mirror '' do
66
- action :download
67
- end
68
- }.to have_updated('chef_mirror[]', :download)
69
- expect(File.exist?(path_to('nodes/x.json'))).to be true
70
- expect(File.exist?(path_to('roles/x.json'))).to be true
71
- end
72
-
73
- it "Upload uploads nothing" do
74
- expect_recipe {
75
- chef_mirror '' do
76
- action :upload
77
- end
78
- }.not_to have_updated('chef_mirror[]', :upload)
79
- end
80
- end
81
- end
82
-
83
- context 'and the Chef server has nodes and roles named x' do
84
- node 'x', {}
85
- role 'x', {}
86
-
87
- when_the_repository 'has nodes and roles named y' do
88
- file 'nodes/y.json', {}
89
- file 'roles/y.json', {}
90
-
91
- it "Download grabs the x's" do
92
- expect_recipe {
93
- chef_mirror '' do
94
- action :download
95
- end
96
- }.to have_updated('chef_mirror[]', :download)
97
- expect(File.exist?(path_to('nodes/x.json'))).to be true
98
- expect(File.exist?(path_to('roles/x.json'))).to be true
99
- expect(File.exist?(path_to('nodes/y.json'))).to be true
100
- expect(File.exist?(path_to('roles/y.json'))).to be true
101
- end
102
-
103
- it "Upload uploads the y's" do
104
- expect_recipe {
105
- chef_mirror '' do
106
- action :upload
107
- end
108
- }.to have_updated('chef_mirror[]', :upload)
109
- expect { get('nodes/x') }.not_to raise_error
110
- expect { get('roles/x') }.not_to raise_error
111
- expect { get('nodes/y') }.not_to raise_error
112
- expect { get('roles/y') }.not_to raise_error
113
- end
114
-
115
- it "Download with purge grabs the x's and deletes the y's" do
116
- expect_recipe {
117
- chef_mirror '' do
118
- purge true
119
- action :download
120
- end
121
- }.to have_updated('chef_mirror[]', :download)
122
- expect(File.exist?(path_to('nodes/x.json'))).to be true
123
- expect(File.exist?(path_to('roles/x.json'))).to be true
124
- end
125
-
126
- it "Upload with :purge uploads the y's and deletes the x's" do
127
- expect_recipe {
128
- chef_mirror '*/*.json' do
129
- purge true
130
- action :upload
131
- end
132
- }.to have_updated('chef_mirror[*/*.json]', :upload)
133
- expect { get('nodes/y') }.not_to raise_error
134
- expect { get('roles/y') }.not_to raise_error
135
- end
136
- end
137
- end
138
-
139
- describe "chef_repo_path" do
140
- when_the_repository 'has stuff but no chef_repo_path' do
141
- file 'repo/nodes/x.json', {}
142
- file 'repo/roles/x.json', {}
143
- file 'repo2/nodes/y.json', {}
144
- file 'repo2/roles/y.json', {}
145
-
146
- before do
147
- Chef::Config.delete(:chef_repo_path)
148
- Chef::Config.delete(:node_path)
149
- Chef::Config.delete(:cookbook_path)
150
- Chef::Config.delete(:role_path)
151
- end
152
-
153
- it "Upload with chef_repo_path('repo') uploads everything" do
154
- repo_path = path_to('repo')
155
- expect_recipe {
156
- chef_mirror '' do
157
- chef_repo_path repo_path
158
- action :upload
159
- end
160
- }.to have_updated('chef_mirror[]', :upload)
161
- expect { get('nodes/x') }.not_to raise_error
162
- expect { get('roles/x') }.not_to raise_error
163
- expect { get('nodes/y') }.to raise_error /404/
164
- expect { get('roles/y') }.to raise_error /404/
165
- end
166
-
167
- it "Upload with chef_repo_path(:chef_repo_path) with multiple paths uploads everything" do
168
- repo_path = path_to('repo')
169
- repo2_path = path_to('repo2')
170
- expect_recipe {
171
- chef_mirror '' do
172
- chef_repo_path :chef_repo_path => [ repo_path, repo2_path ]
173
- action :upload
174
- end
175
- }.to have_updated('chef_mirror[]', :upload)
176
- expect { get('nodes/x') }.not_to raise_error
177
- expect { get('roles/x') }.not_to raise_error
178
- expect { get('nodes/y') }.not_to raise_error
179
- expect { get('roles/y') }.not_to raise_error
180
- end
181
-
182
- it "Upload with chef_repo_path(:node_path, :role_path) uploads everything" do
183
- repo_path = path_to('repo')
184
- repo2_path = path_to('repo2')
185
-
186
- expect_recipe {
187
- chef_mirror '' do
188
- chef_repo_path :chef_repo_path => '/blahblah',
189
- :node_path => "#{repo_path}/nodes",
190
- :role_path => "#{repo2_path}/roles"
191
- action :upload
192
- end
193
- }.to have_updated('chef_mirror[]', :upload)
194
- expect { get('nodes/x') }.not_to raise_error
195
- expect { get('roles/x') }.to raise_error /404/
196
- expect { get('nodes/y') }.to raise_error /404/
197
- expect { get('roles/y') }.not_to raise_error
198
- end
199
-
200
- it "Upload with chef_repo_path(:chef_repo_path, :role_path) uploads everything" do
201
- repo_path = path_to('repo')
202
- repo2_path = path_to('repo2')
203
-
204
- expect_recipe {
205
- chef_mirror '' do
206
- chef_repo_path :chef_repo_path => repo_path,
207
- :role_path => "#{repo2_path}/roles"
208
- action :upload
209
- end
210
- }.to have_updated('chef_mirror[]', :upload)
211
- expect { get('nodes/x') }.not_to raise_error
212
- expect { get('roles/x') }.to raise_error /404/
213
- expect { get('nodes/y') }.to raise_error /404/
214
- expect { get('roles/y') }.not_to raise_error
215
- end
216
-
217
- it "Upload with chef_repo_path(:node_path, :role_path) with multiple paths uploads everything" do
218
- repo_path = path_to('repo')
219
- repo2_path = path_to('repo2')
220
-
221
- expect_recipe {
222
- chef_mirror '' do
223
- chef_repo_path :chef_repo_path => [ 'foo', 'bar' ],
224
- :node_path => [ "#{repo_path}/nodes", "#{repo2_path}/nodes" ],
225
- :role_path => [ "#{repo_path}/roles", "#{repo2_path}/roles" ]
226
- action :upload
227
- end
228
- }.to have_updated('chef_mirror[]', :upload)
229
- expect { get('nodes/x') }.not_to raise_error
230
- expect { get('roles/x') }.not_to raise_error
231
- expect { get('nodes/y') }.not_to raise_error
232
- expect { get('roles/y') }.not_to raise_error
233
- end
234
- end
235
- end
236
-
237
- describe "cookbook upload, chef_repo_path and versioned_cookbooks" do
238
- when_the_repository 'has cookbooks in non-versioned format' do
239
- file 'cookbooks/x-1.0.0/metadata.rb', 'name "x-1.0.0"; version "2.0.0"'
240
- file 'cookbooks/y-1.0.0/metadata.rb', 'name "y-3.0.0"; version "4.0.0"'
241
-
242
- it "chef_mirror :upload uploads everything" do
243
- expect_recipe {
244
- chef_mirror '' do
245
- action :upload
246
- end
247
- }.to have_updated('chef_mirror[]', :upload)
248
- expect { get('cookbooks/x-1.0.0/2.0.0') }.not_to raise_error
249
- expect { get('cookbooks/y-3.0.0/4.0.0') }.not_to raise_error
250
- end
251
-
252
- context 'and Chef::Config.versioned_cookbooks is false' do
253
- before do
254
- Chef::Config.versioned_cookbooks false
255
- end
256
- it "chef_mirror :upload uploads everything" do
257
- expect_recipe {
258
- chef_mirror '' do
259
- action :upload
260
- end
261
- }.to have_updated('chef_mirror[]', :upload)
262
- expect { get('cookbooks/x-1.0.0/2.0.0') }.not_to raise_error
263
- expect { get('cookbooks/y-3.0.0/4.0.0') }.not_to raise_error
264
- end
265
- end
266
-
267
- context 'and Chef::Config.chef_repo_path is not set but versioned_cookbooks is false' do
268
- before do
269
- Chef::Config.delete(:chef_repo_path)
270
- Chef::Config.versioned_cookbooks false
271
- end
272
-
273
- it "chef_mirror :upload with chef_repo_path and versioned_cookbooks false uploads cookbooks with name including version" do
274
- repository_dir = @repository_dir
275
- expect_recipe {
276
- chef_mirror '' do
277
- chef_repo_path repository_dir
278
- versioned_cookbooks false
279
- action :upload
280
- end
281
- }.to have_updated('chef_mirror[]', :upload)
282
- expect { get('cookbooks/x-1.0.0/2.0.0') }.not_to raise_error
283
- expect { get('cookbooks/y-3.0.0/4.0.0') }.not_to raise_error
284
- end
285
- end
286
- end
287
-
288
- when_the_repository 'has cookbooks in versioned_cookbook format' do
289
- file 'cookbooks/x-1.0.0/metadata.rb', 'name "x"; version "1.0.0"'
290
- file 'cookbooks/x-2.0.0/metadata.rb', 'name "x"; version "2.0.0"'
291
-
292
- context 'and Chef::Config.versioned_cookbooks is true' do
293
- before do
294
- Chef::Config.versioned_cookbooks true
295
- end
296
- it "chef_mirror :upload uploads everything" do
297
- expect_recipe {
298
- chef_mirror '' do
299
- action :upload
300
- end
301
- }.to have_updated('chef_mirror[]', :upload)
302
- expect { get('cookbooks/x/1.0.0') }.not_to raise_error
303
- expect { get('cookbooks/x/2.0.0') }.not_to raise_error
304
- end
305
- end
306
-
307
- context 'and Chef::Config.chef_repo_path set somewhere else' do
308
- before do
309
- Chef::Config.chef_repo_path = '/x/y/z'
310
- end
311
- it "chef_mirror :upload with chef_repo_path uploads cookbooks" do
312
- repository_dir = @repository_dir
313
- expect_recipe {
314
- chef_mirror '' do
315
- chef_repo_path repository_dir
316
- action :upload
317
- end
318
- }.to have_updated('chef_mirror[]', :upload)
319
- expect { get('cookbooks/x/1.0.0') }.not_to raise_error
320
- expect { get('cookbooks/x/2.0.0') }.not_to raise_error
321
- end
322
- end
323
-
324
- context 'and Chef::Config.chef_repo_path is not set but versioned_cookbooks is false' do
325
- before do
326
- Chef::Config.delete(:chef_repo_path)
327
- Chef::Config.versioned_cookbooks false
328
- end
329
-
330
- it "chef_mirror :upload with chef_repo_path uploads cookbooks with name split from version" do
331
- repository_dir = @repository_dir
332
- expect_recipe {
333
- chef_mirror '' do
334
- chef_repo_path repository_dir
335
- action :upload
336
- end
337
- }.to have_updated('chef_mirror[]', :upload)
338
- expect { get('cookbooks/x/1.0.0') }.not_to raise_error
339
- expect { get('cookbooks/x/2.0.0') }.not_to raise_error
340
- end
341
-
342
- it "chef_mirror :upload with chef_repo_path and versioned_cookbooks uploads cookbooks with name split from version" do
343
- repository_dir = @repository_dir
344
- expect_recipe {
345
- chef_mirror '' do
346
- chef_repo_path repository_dir
347
- versioned_cookbooks true
348
- action :upload
349
- end
350
- }.to have_updated('chef_mirror[]', :upload)
351
- expect { get('cookbooks/x/1.0.0') }.not_to raise_error
352
- expect { get('cookbooks/x/2.0.0') }.not_to raise_error
353
- end
354
- end
355
-
356
- context 'and Chef::Config.chef_repo_path is not set but versioned_cookbooks is true' do
357
- before do
358
- Chef::Config.delete(:chef_repo_path)
359
- Chef::Config.versioned_cookbooks true
360
- end
361
- it "chef_mirror :upload with chef_repo_path uploads cookbooks with name split from version" do
362
- repository_dir = @repository_dir
363
- expect_recipe {
364
- chef_mirror '' do
365
- chef_repo_path repository_dir
366
- action :upload
367
- end
368
- }.to have_updated('chef_mirror[]', :upload)
369
- expect { get('cookbooks/x/1.0.0') }.not_to raise_error
370
- expect { get('cookbooks/x/2.0.0') }.not_to raise_error
371
- end
372
- end
373
- end
374
- end
375
-
376
- describe 'cookbook download, chef_repo_path, and versioned_cookbooks' do
377
- context 'when the Chef server has a cookbook with multiple versions' do
378
- cookbook 'x', '1.0.0', 'metadata.rb' => 'name "x"; version "1.0.0"'
379
- cookbook 'x', '2.0.0', 'metadata.rb' => 'name "x"; version "2.0.0"'
380
-
381
- when_the_repository 'is empty' do
382
- it 'chef_mirror :download downloads the latest version of the cookbook' do
383
- expect_recipe {
384
- chef_mirror '' do
385
- action :download
386
- end
387
- }.to have_updated('chef_mirror[]', :download)
388
- expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
389
- end
390
-
391
- it 'chef_mirror :download with versioned_cookbooks = true downloads all versions of the cookbook' do
392
- expect_recipe {
393
- chef_mirror '' do
394
- versioned_cookbooks true
395
- action :download
396
- end
397
- }.to have_updated('chef_mirror[]', :download)
398
- expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
399
- expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
400
- end
401
-
402
- context 'and Chef::Config.chef_repo_path is set elsewhere' do
403
- before do
404
- Chef::Config.chef_repo_path = '/x/y/z'
405
- end
406
-
407
- it 'chef_mirror :download with chef_repo_path downloads all versions of the cookbook' do
408
- repository_dir = @repository_dir
409
- expect_recipe {
410
- chef_mirror '' do
411
- chef_repo_path repository_dir
412
- action :download
413
- end
414
- }.to have_updated('chef_mirror[]', :download)
415
- expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
416
- expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
417
- end
418
-
419
- it 'chef_mirror :download with chef_repo_path and versioned_cookbooks = false downloads the latest version of the cookbook' do
420
- repository_dir = @repository_dir
421
- expect_recipe {
422
- chef_mirror '' do
423
- chef_repo_path repository_dir
424
- versioned_cookbooks false
425
- action :download
426
- end
427
- }.to have_updated('chef_mirror[]', :download)
428
- expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
429
- end
430
- end
431
-
432
- context 'and Chef::Config.versioned_cookbooks is true' do
433
- before do
434
- Chef::Config.versioned_cookbooks = true
435
- end
436
-
437
- it 'chef_mirror :download downloads all versions of the cookbook' do
438
- expect_recipe {
439
- chef_mirror '' do
440
- action :download
441
- end
442
- }.to have_updated('chef_mirror[]', :download)
443
- expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
444
- expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
445
- end
446
-
447
- it 'chef_mirror :download with versioned_cookbooks = false downloads the latest version of the cookbook' do
448
- expect_recipe {
449
- chef_mirror '' do
450
- versioned_cookbooks false
451
- action :download
452
- end
453
- }.to have_updated('chef_mirror[]', :download)
454
- expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
455
- end
456
-
457
- context 'and Chef::Config.chef_repo_path is set elsewhere' do
458
- before do
459
- Chef::Config.chef_repo_path = '/x/y/z'
460
- end
461
-
462
- it 'chef_mirror :download with chef_repo_path downloads all versions of the cookbook' do
463
- repository_dir = @repository_dir
464
- expect_recipe {
465
- chef_mirror '' do
466
- chef_repo_path repository_dir
467
- action :download
468
- end
469
- }.to have_updated('chef_mirror[]', :download)
470
- expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
471
- expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
472
- end
473
-
474
- it 'chef_mirror :download with chef_repo_path and versioned_cookbooks = false downloads the latest version of the cookbook' do
475
- repository_dir = @repository_dir
476
- expect_recipe {
477
- chef_mirror '' do
478
- chef_repo_path repository_dir
479
- versioned_cookbooks false
480
- action :download
481
- end
482
- }.to have_updated('chef_mirror[]', :download)
483
- expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
484
- end
485
- end
486
- end
487
- end
488
- end
489
- end
490
- end
491
- end
1
+ require 'support/spec_support'
2
+ require 'cheffish/rspec/chef_run_support'
3
+ require 'chef/resource/chef_mirror'
4
+ require 'chef/provider/chef_mirror'
5
+
6
+ describe Chef::Resource::ChefMirror 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
+ describe 'basic download and upload' do
17
+ when_the_repository 'is full of stuff' do
18
+ file 'nodes/x.json', {}
19
+ file 'roles/x.json', {}
20
+ directory 'cookbooks/x' do
21
+ file 'metadata.rb', 'name "x"; version "2.0.0"'
22
+ end
23
+
24
+ it "Download grabs defaults" do
25
+ expect_recipe {
26
+ chef_mirror '' do
27
+ action :download
28
+ end
29
+ }.to have_updated('chef_mirror[]', :download)
30
+ expect(File.exist?(path_to('groups/admins.json'))).to be true
31
+ expect(File.exist?(path_to('environments/_default.json'))).to be true
32
+ end
33
+
34
+ it "Upload uploads everything" do
35
+ expect_recipe {
36
+ chef_mirror '' do
37
+ action :upload
38
+ end
39
+ }.to have_updated('chef_mirror[]', :upload)
40
+ expect { get('nodes/x') }.not_to raise_error
41
+ expect { get('roles/x') }.not_to raise_error
42
+ expect { get('cookbooks/x/2.0.0') }.not_to raise_error
43
+ end
44
+
45
+ it 'chef_mirror with concurrency 0 fails with a reasonable message' do
46
+ expect {
47
+ converge {
48
+ chef_mirror '' do
49
+ concurrency 0
50
+ action :download
51
+ end
52
+ }
53
+ }.to raise_error /chef_mirror.concurrency must be above 0/
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'and the Chef server has a node and role in it' do
59
+ node 'x', {}
60
+ role 'x', {}
61
+
62
+ when_the_repository 'is empty' do
63
+ it "Download grabs the node and role" do
64
+ expect_recipe {
65
+ chef_mirror '' do
66
+ action :download
67
+ end
68
+ }.to have_updated('chef_mirror[]', :download)
69
+ expect(File.exist?(path_to('nodes/x.json'))).to be true
70
+ expect(File.exist?(path_to('roles/x.json'))).to be true
71
+ end
72
+
73
+ it "Upload uploads nothing" do
74
+ expect_recipe {
75
+ chef_mirror '' do
76
+ action :upload
77
+ end
78
+ }.not_to have_updated('chef_mirror[]', :upload)
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'and the Chef server has nodes and roles named x' do
84
+ node 'x', {}
85
+ role 'x', {}
86
+
87
+ when_the_repository 'has nodes and roles named y' do
88
+ file 'nodes/y.json', {}
89
+ file 'roles/y.json', {}
90
+
91
+ it "Download grabs the x's" do
92
+ expect_recipe {
93
+ chef_mirror '' do
94
+ action :download
95
+ end
96
+ }.to have_updated('chef_mirror[]', :download)
97
+ expect(File.exist?(path_to('nodes/x.json'))).to be true
98
+ expect(File.exist?(path_to('roles/x.json'))).to be true
99
+ expect(File.exist?(path_to('nodes/y.json'))).to be true
100
+ expect(File.exist?(path_to('roles/y.json'))).to be true
101
+ end
102
+
103
+ it "Upload uploads the y's" do
104
+ expect_recipe {
105
+ chef_mirror '' do
106
+ action :upload
107
+ end
108
+ }.to have_updated('chef_mirror[]', :upload)
109
+ expect { get('nodes/x') }.not_to raise_error
110
+ expect { get('roles/x') }.not_to raise_error
111
+ expect { get('nodes/y') }.not_to raise_error
112
+ expect { get('roles/y') }.not_to raise_error
113
+ end
114
+
115
+ it "Download with purge grabs the x's and deletes the y's" do
116
+ expect_recipe {
117
+ chef_mirror '' do
118
+ purge true
119
+ action :download
120
+ end
121
+ }.to have_updated('chef_mirror[]', :download)
122
+ expect(File.exist?(path_to('nodes/x.json'))).to be true
123
+ expect(File.exist?(path_to('roles/x.json'))).to be true
124
+ end
125
+
126
+ it "Upload with :purge uploads the y's and deletes the x's" do
127
+ expect_recipe {
128
+ chef_mirror '*/*.json' do
129
+ purge true
130
+ action :upload
131
+ end
132
+ }.to have_updated('chef_mirror[*/*.json]', :upload)
133
+ expect { get('nodes/y') }.not_to raise_error
134
+ expect { get('roles/y') }.not_to raise_error
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "chef_repo_path" do
140
+ when_the_repository 'has stuff but no chef_repo_path' do
141
+ file 'repo/nodes/x.json', {}
142
+ file 'repo/roles/x.json', {}
143
+ file 'repo2/nodes/y.json', {}
144
+ file 'repo2/roles/y.json', {}
145
+
146
+ before do
147
+ Chef::Config.delete(:chef_repo_path)
148
+ Chef::Config.delete(:node_path)
149
+ Chef::Config.delete(:cookbook_path)
150
+ Chef::Config.delete(:role_path)
151
+ end
152
+
153
+ it "Upload with chef_repo_path('repo') uploads everything" do
154
+ repo_path = path_to('repo')
155
+ expect_recipe {
156
+ chef_mirror '' do
157
+ chef_repo_path repo_path
158
+ action :upload
159
+ end
160
+ }.to have_updated('chef_mirror[]', :upload)
161
+ expect { get('nodes/x') }.not_to raise_error
162
+ expect { get('roles/x') }.not_to raise_error
163
+ expect { get('nodes/y') }.to raise_error /404/
164
+ expect { get('roles/y') }.to raise_error /404/
165
+ end
166
+
167
+ it "Upload with chef_repo_path(:chef_repo_path) with multiple paths uploads everything" do
168
+ repo_path = path_to('repo')
169
+ repo2_path = path_to('repo2')
170
+ expect_recipe {
171
+ chef_mirror '' do
172
+ chef_repo_path :chef_repo_path => [ repo_path, repo2_path ]
173
+ action :upload
174
+ end
175
+ }.to have_updated('chef_mirror[]', :upload)
176
+ expect { get('nodes/x') }.not_to raise_error
177
+ expect { get('roles/x') }.not_to raise_error
178
+ expect { get('nodes/y') }.not_to raise_error
179
+ expect { get('roles/y') }.not_to raise_error
180
+ end
181
+
182
+ it "Upload with chef_repo_path(:node_path, :role_path) uploads everything" do
183
+ repo_path = path_to('repo')
184
+ repo2_path = path_to('repo2')
185
+
186
+ expect_recipe {
187
+ chef_mirror '' do
188
+ chef_repo_path :chef_repo_path => '/blahblah',
189
+ :node_path => "#{repo_path}/nodes",
190
+ :role_path => "#{repo2_path}/roles"
191
+ action :upload
192
+ end
193
+ }.to have_updated('chef_mirror[]', :upload)
194
+ expect { get('nodes/x') }.not_to raise_error
195
+ expect { get('roles/x') }.to raise_error /404/
196
+ expect { get('nodes/y') }.to raise_error /404/
197
+ expect { get('roles/y') }.not_to raise_error
198
+ end
199
+
200
+ it "Upload with chef_repo_path(:chef_repo_path, :role_path) uploads everything" do
201
+ repo_path = path_to('repo')
202
+ repo2_path = path_to('repo2')
203
+
204
+ expect_recipe {
205
+ chef_mirror '' do
206
+ chef_repo_path :chef_repo_path => repo_path,
207
+ :role_path => "#{repo2_path}/roles"
208
+ action :upload
209
+ end
210
+ }.to have_updated('chef_mirror[]', :upload)
211
+ expect { get('nodes/x') }.not_to raise_error
212
+ expect { get('roles/x') }.to raise_error /404/
213
+ expect { get('nodes/y') }.to raise_error /404/
214
+ expect { get('roles/y') }.not_to raise_error
215
+ end
216
+
217
+ it "Upload with chef_repo_path(:node_path, :role_path) with multiple paths uploads everything" do
218
+ repo_path = path_to('repo')
219
+ repo2_path = path_to('repo2')
220
+
221
+ expect_recipe {
222
+ chef_mirror '' do
223
+ chef_repo_path :chef_repo_path => [ 'foo', 'bar' ],
224
+ :node_path => [ "#{repo_path}/nodes", "#{repo2_path}/nodes" ],
225
+ :role_path => [ "#{repo_path}/roles", "#{repo2_path}/roles" ]
226
+ action :upload
227
+ end
228
+ }.to have_updated('chef_mirror[]', :upload)
229
+ expect { get('nodes/x') }.not_to raise_error
230
+ expect { get('roles/x') }.not_to raise_error
231
+ expect { get('nodes/y') }.not_to raise_error
232
+ expect { get('roles/y') }.not_to raise_error
233
+ end
234
+ end
235
+ end
236
+
237
+ describe "cookbook upload, chef_repo_path and versioned_cookbooks" do
238
+ when_the_repository 'has cookbooks in non-versioned format' do
239
+ file 'cookbooks/x-1.0.0/metadata.rb', 'name "x-1.0.0"; version "2.0.0"'
240
+ file 'cookbooks/y-1.0.0/metadata.rb', 'name "y-3.0.0"; version "4.0.0"'
241
+
242
+ it "chef_mirror :upload uploads everything" do
243
+ expect_recipe {
244
+ chef_mirror '' do
245
+ action :upload
246
+ end
247
+ }.to have_updated('chef_mirror[]', :upload)
248
+ expect { get('cookbooks/x-1.0.0/2.0.0') }.not_to raise_error
249
+ expect { get('cookbooks/y-3.0.0/4.0.0') }.not_to raise_error
250
+ end
251
+
252
+ context 'and Chef::Config.versioned_cookbooks is false' do
253
+ before do
254
+ Chef::Config.versioned_cookbooks false
255
+ end
256
+ it "chef_mirror :upload uploads everything" do
257
+ expect_recipe {
258
+ chef_mirror '' do
259
+ action :upload
260
+ end
261
+ }.to have_updated('chef_mirror[]', :upload)
262
+ expect { get('cookbooks/x-1.0.0/2.0.0') }.not_to raise_error
263
+ expect { get('cookbooks/y-3.0.0/4.0.0') }.not_to raise_error
264
+ end
265
+ end
266
+
267
+ context 'and Chef::Config.chef_repo_path is not set but versioned_cookbooks is false' do
268
+ before do
269
+ Chef::Config.delete(:chef_repo_path)
270
+ Chef::Config.versioned_cookbooks false
271
+ end
272
+
273
+ it "chef_mirror :upload with chef_repo_path and versioned_cookbooks false uploads cookbooks with name including version" do
274
+ repository_dir = @repository_dir
275
+ expect_recipe {
276
+ chef_mirror '' do
277
+ chef_repo_path repository_dir
278
+ versioned_cookbooks false
279
+ action :upload
280
+ end
281
+ }.to have_updated('chef_mirror[]', :upload)
282
+ expect { get('cookbooks/x-1.0.0/2.0.0') }.not_to raise_error
283
+ expect { get('cookbooks/y-3.0.0/4.0.0') }.not_to raise_error
284
+ end
285
+ end
286
+ end
287
+
288
+ when_the_repository 'has cookbooks in versioned_cookbook format' do
289
+ file 'cookbooks/x-1.0.0/metadata.rb', 'name "x"; version "1.0.0"'
290
+ file 'cookbooks/x-2.0.0/metadata.rb', 'name "x"; version "2.0.0"'
291
+
292
+ context 'and Chef::Config.versioned_cookbooks is true' do
293
+ before do
294
+ Chef::Config.versioned_cookbooks true
295
+ end
296
+ it "chef_mirror :upload uploads everything" do
297
+ expect_recipe {
298
+ chef_mirror '' do
299
+ action :upload
300
+ end
301
+ }.to have_updated('chef_mirror[]', :upload)
302
+ expect { get('cookbooks/x/1.0.0') }.not_to raise_error
303
+ expect { get('cookbooks/x/2.0.0') }.not_to raise_error
304
+ end
305
+ end
306
+
307
+ context 'and Chef::Config.chef_repo_path set somewhere else' do
308
+ before do
309
+ Chef::Config.chef_repo_path = '/x/y/z'
310
+ end
311
+ it "chef_mirror :upload with chef_repo_path uploads cookbooks" do
312
+ repository_dir = @repository_dir
313
+ expect_recipe {
314
+ chef_mirror '' do
315
+ chef_repo_path repository_dir
316
+ action :upload
317
+ end
318
+ }.to have_updated('chef_mirror[]', :upload)
319
+ expect { get('cookbooks/x/1.0.0') }.not_to raise_error
320
+ expect { get('cookbooks/x/2.0.0') }.not_to raise_error
321
+ end
322
+ end
323
+
324
+ context 'and Chef::Config.chef_repo_path is not set but versioned_cookbooks is false' do
325
+ before do
326
+ Chef::Config.delete(:chef_repo_path)
327
+ Chef::Config.versioned_cookbooks false
328
+ end
329
+
330
+ it "chef_mirror :upload with chef_repo_path uploads cookbooks with name split from version" do
331
+ repository_dir = @repository_dir
332
+ expect_recipe {
333
+ chef_mirror '' do
334
+ chef_repo_path repository_dir
335
+ action :upload
336
+ end
337
+ }.to have_updated('chef_mirror[]', :upload)
338
+ expect { get('cookbooks/x/1.0.0') }.not_to raise_error
339
+ expect { get('cookbooks/x/2.0.0') }.not_to raise_error
340
+ end
341
+
342
+ it "chef_mirror :upload with chef_repo_path and versioned_cookbooks uploads cookbooks with name split from version" do
343
+ repository_dir = @repository_dir
344
+ expect_recipe {
345
+ chef_mirror '' do
346
+ chef_repo_path repository_dir
347
+ versioned_cookbooks true
348
+ action :upload
349
+ end
350
+ }.to have_updated('chef_mirror[]', :upload)
351
+ expect { get('cookbooks/x/1.0.0') }.not_to raise_error
352
+ expect { get('cookbooks/x/2.0.0') }.not_to raise_error
353
+ end
354
+ end
355
+
356
+ context 'and Chef::Config.chef_repo_path is not set but versioned_cookbooks is true' do
357
+ before do
358
+ Chef::Config.delete(:chef_repo_path)
359
+ Chef::Config.versioned_cookbooks true
360
+ end
361
+ it "chef_mirror :upload with chef_repo_path uploads cookbooks with name split from version" do
362
+ repository_dir = @repository_dir
363
+ expect_recipe {
364
+ chef_mirror '' do
365
+ chef_repo_path repository_dir
366
+ action :upload
367
+ end
368
+ }.to have_updated('chef_mirror[]', :upload)
369
+ expect { get('cookbooks/x/1.0.0') }.not_to raise_error
370
+ expect { get('cookbooks/x/2.0.0') }.not_to raise_error
371
+ end
372
+ end
373
+ end
374
+ end
375
+
376
+ describe 'cookbook download, chef_repo_path, and versioned_cookbooks' do
377
+ context 'when the Chef server has a cookbook with multiple versions' do
378
+ cookbook 'x', '1.0.0', 'metadata.rb' => 'name "x"; version "1.0.0"'
379
+ cookbook 'x', '2.0.0', 'metadata.rb' => 'name "x"; version "2.0.0"'
380
+
381
+ when_the_repository 'is empty' do
382
+ it 'chef_mirror :download downloads the latest version of the cookbook' do
383
+ expect_recipe {
384
+ chef_mirror '' do
385
+ action :download
386
+ end
387
+ }.to have_updated('chef_mirror[]', :download)
388
+ expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
389
+ end
390
+
391
+ it 'chef_mirror :download with versioned_cookbooks = true downloads all versions of the cookbook' do
392
+ expect_recipe {
393
+ chef_mirror '' do
394
+ versioned_cookbooks true
395
+ action :download
396
+ end
397
+ }.to have_updated('chef_mirror[]', :download)
398
+ expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
399
+ expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
400
+ end
401
+
402
+ context 'and Chef::Config.chef_repo_path is set elsewhere' do
403
+ before do
404
+ Chef::Config.chef_repo_path = '/x/y/z'
405
+ end
406
+
407
+ it 'chef_mirror :download with chef_repo_path downloads all versions of the cookbook' do
408
+ repository_dir = @repository_dir
409
+ expect_recipe {
410
+ chef_mirror '' do
411
+ chef_repo_path repository_dir
412
+ action :download
413
+ end
414
+ }.to have_updated('chef_mirror[]', :download)
415
+ expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
416
+ expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
417
+ end
418
+
419
+ it 'chef_mirror :download with chef_repo_path and versioned_cookbooks = false downloads the latest version of the cookbook' do
420
+ repository_dir = @repository_dir
421
+ expect_recipe {
422
+ chef_mirror '' do
423
+ chef_repo_path repository_dir
424
+ versioned_cookbooks false
425
+ action :download
426
+ end
427
+ }.to have_updated('chef_mirror[]', :download)
428
+ expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
429
+ end
430
+ end
431
+
432
+ context 'and Chef::Config.versioned_cookbooks is true' do
433
+ before do
434
+ Chef::Config.versioned_cookbooks = true
435
+ end
436
+
437
+ it 'chef_mirror :download downloads all versions of the cookbook' do
438
+ expect_recipe {
439
+ chef_mirror '' do
440
+ action :download
441
+ end
442
+ }.to have_updated('chef_mirror[]', :download)
443
+ expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
444
+ expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
445
+ end
446
+
447
+ it 'chef_mirror :download with versioned_cookbooks = false downloads the latest version of the cookbook' do
448
+ expect_recipe {
449
+ chef_mirror '' do
450
+ versioned_cookbooks false
451
+ action :download
452
+ end
453
+ }.to have_updated('chef_mirror[]', :download)
454
+ expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
455
+ end
456
+
457
+ context 'and Chef::Config.chef_repo_path is set elsewhere' do
458
+ before do
459
+ Chef::Config.chef_repo_path = '/x/y/z'
460
+ end
461
+
462
+ it 'chef_mirror :download with chef_repo_path downloads all versions of the cookbook' do
463
+ repository_dir = @repository_dir
464
+ expect_recipe {
465
+ chef_mirror '' do
466
+ chef_repo_path repository_dir
467
+ action :download
468
+ end
469
+ }.to have_updated('chef_mirror[]', :download)
470
+ expect(File.read(path_to('cookbooks/x-1.0.0/metadata.rb'))).to eq('name "x"; version "1.0.0"')
471
+ expect(File.read(path_to('cookbooks/x-2.0.0/metadata.rb'))).to eq('name "x"; version "2.0.0"')
472
+ end
473
+
474
+ it 'chef_mirror :download with chef_repo_path and versioned_cookbooks = false downloads the latest version of the cookbook' do
475
+ repository_dir = @repository_dir
476
+ expect_recipe {
477
+ chef_mirror '' do
478
+ chef_repo_path repository_dir
479
+ versioned_cookbooks false
480
+ action :download
481
+ end
482
+ }.to have_updated('chef_mirror[]', :download)
483
+ expect(File.read(path_to('cookbooks/x/metadata.rb'))).to eq('name "x"; version "2.0.0"')
484
+ end
485
+ end
486
+ end
487
+ end
488
+ end
489
+ end
490
+ end
491
+ end