chef-dk 0.5.0.rc.1 → 0.5.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -24
  3. data/lib/chef-dk/builtin_commands.rb +2 -0
  4. data/lib/chef-dk/command/diff.rb +312 -0
  5. data/lib/chef-dk/command/push.rb +1 -1
  6. data/lib/chef-dk/command/shell_init.rb +21 -3
  7. data/lib/chef-dk/command/update.rb +28 -5
  8. data/lib/chef-dk/configurable.rb +1 -1
  9. data/lib/chef-dk/exceptions.rb +3 -0
  10. data/lib/chef-dk/pager.rb +106 -0
  11. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +114 -0
  12. data/lib/chef-dk/policyfile/comparison_base.rb +124 -0
  13. data/lib/chef-dk/policyfile/cookbook_sources.rb +1 -0
  14. data/lib/chef-dk/policyfile/differ.rb +266 -0
  15. data/lib/chef-dk/policyfile/dsl.rb +26 -3
  16. data/lib/chef-dk/policyfile/uploader.rb +4 -5
  17. data/lib/chef-dk/policyfile_compiler.rb +8 -0
  18. data/lib/chef-dk/policyfile_lock.rb +135 -3
  19. data/lib/chef-dk/policyfile_services/install.rb +1 -0
  20. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -0
  21. data/lib/chef-dk/service_exceptions.rb +12 -0
  22. data/lib/chef-dk/ui.rb +8 -0
  23. data/lib/chef-dk/version.rb +1 -1
  24. data/spec/spec_helper.rb +6 -0
  25. data/spec/test_helpers.rb +4 -0
  26. data/spec/unit/command/diff_spec.rb +283 -0
  27. data/spec/unit/command/shell_init_spec.rb +19 -2
  28. data/spec/unit/command/update_spec.rb +96 -0
  29. data/spec/unit/command/verify_spec.rb +0 -6
  30. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -0
  31. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -0
  32. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -0
  33. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -0
  34. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -0
  35. data/spec/unit/pager_spec.rb +119 -0
  36. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +66 -0
  37. data/spec/unit/policyfile/comparison_base_spec.rb +343 -0
  38. data/spec/unit/policyfile/differ_spec.rb +687 -0
  39. data/spec/unit/policyfile_evaluation_spec.rb +87 -0
  40. data/spec/unit/policyfile_lock_build_spec.rb +247 -8
  41. data/spec/unit/policyfile_lock_serialization_spec.rb +47 -0
  42. data/spec/unit/policyfile_services/export_repo_spec.rb +2 -0
  43. data/spec/unit/policyfile_services/push_spec.rb +2 -0
  44. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -0
  45. metadata +62 -6
@@ -243,6 +243,25 @@ E
243
243
 
244
244
  end
245
245
 
246
+ context "with the default source set to a chef-repo path" do
247
+
248
+ let(:chef_repo) { File.expand_path("spec/unit/fixtures/local_path_cookbooks", project_root) }
249
+
250
+ let(:policyfile_rb) do
251
+ <<-EOH
252
+ run_list "foo", "bar"
253
+ default_source :chef_repo, "#{chef_repo}"
254
+ EOH
255
+ end
256
+
257
+ it "has a default source" do
258
+ expect(policyfile.errors).to eq([])
259
+ expected = ChefDK::Policyfile::ChefRepoCookbookSource.new(chef_repo)
260
+ expect(policyfile.default_source).to eq(expected)
261
+ end
262
+
263
+ end
264
+
246
265
  end
247
266
 
248
267
  describe "assigning cookbooks to specific sources" do
@@ -323,6 +342,74 @@ EOH
323
342
 
324
343
  end
325
344
 
345
+ describe "defining attributes" do
346
+
347
+ let(:policyfile_rb) do
348
+ <<-EOH
349
+ name "policy-with-attrs"
350
+ run_list "foo"
351
+
352
+ # basic attribute setting:
353
+ default["foo"] = "bar"
354
+
355
+ # auto-vivify
356
+ default["abc"]["def"]["ghi"] = "xyz"
357
+
358
+ # literal data structures
359
+ default["baz"] = {
360
+ "more_nested_stuff" => "yup"
361
+ }
362
+
363
+ # Array literals work and we merge rather than overwrite:
364
+ default["baz"]["an_array"] = ["a", "b", "c"]
365
+
366
+ # all the same stuff works with overrides:
367
+
368
+ override["foo"] = "bar"
369
+
370
+ override["abc"]["def"]["ghi"] = "xyz"
371
+
372
+ override["baz_override"] = {
373
+ "more_nested_stuff" => "yup"
374
+ }
375
+
376
+ override["baz_override"]["an_array"] = ["a", "b", "c"]
377
+ EOH
378
+ end
379
+
380
+ let(:expected_combined_default_attrs) do
381
+ {
382
+ "foo" => "bar",
383
+ "abc" => { "def" => { "ghi" => "xyz" } },
384
+ "baz" => {
385
+ "more_nested_stuff" => "yup",
386
+ "an_array" => ["a", "b", "c"]
387
+ }
388
+ }
389
+ end
390
+
391
+ let(:expected_combined_override_attrs) do
392
+ {
393
+ "foo" => "bar",
394
+ "abc" => { "def" => { "ghi" => "xyz" } },
395
+ "baz_override" => {
396
+ "more_nested_stuff" => "yup",
397
+ "an_array" => ["a", "b", "c"]
398
+ }
399
+ }
400
+ end
401
+
402
+ it "defines default attributes" do
403
+ expect(policyfile.errors).to eq([])
404
+ expect(policyfile.default_attributes).to eq(expected_combined_default_attrs)
405
+ end
406
+
407
+ it "defines override attributes" do
408
+ expect(policyfile.errors).to eq([])
409
+ expect(policyfile.override_attributes).to eq(expected_combined_override_attrs)
410
+ end
411
+ end
412
+
326
413
  end
327
414
 
328
415
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: UTF-8 -*-
1
2
  #
2
3
  # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
4
  # License:: Apache License, Version 2.0
@@ -130,6 +131,61 @@ describe ChefDK::PolicyfileLock, "building a lockfile" do
130
131
 
131
132
  end
132
133
 
134
+ describe "policyfiles with invalid attributes" do
135
+
136
+ let(:policyfile_lock) do
137
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
138
+
139
+ p.name = "invalid_cache_key_policyfile"
140
+
141
+ p.run_list = [ "recipe[foo]" ]
142
+
143
+ p.cached_cookbook("foo") do |cb|
144
+ cb.cache_key = "foo-1.0.0"
145
+ end
146
+
147
+ p.default_attributes = default_attributes
148
+ end
149
+ end
150
+
151
+ context "invalid floats - infinity" do
152
+
153
+ let(:default_attributes) { {"infinity" => Float::INFINITY} }
154
+
155
+ it "raises a descriptive error" do
156
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
157
+ end
158
+ end
159
+
160
+ context "invalid floats - nan" do
161
+
162
+ let(:default_attributes) { {"infinity" => Float::NAN} }
163
+
164
+ it "raises a descriptive error" do
165
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
166
+ end
167
+ end
168
+
169
+ context "non-string hash/object keys" do
170
+
171
+ let(:default_attributes) { {1906 => "lol nope"} }
172
+
173
+ it "raises a descriptive error" do
174
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
175
+ end
176
+ end
177
+
178
+ context "values that are not Hash/Array/String/Float/Integer/true/false/nil" do
179
+
180
+ let(:default_attributes) { { "raw object" => Object.new } }
181
+
182
+ it "raises a descriptive error" do
183
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
184
+ end
185
+ end
186
+
187
+ end
188
+
133
189
  context "with a minimal policyfile" do
134
190
 
135
191
  let(:policyfile_lock) do
@@ -150,11 +206,99 @@ describe ChefDK::PolicyfileLock, "building a lockfile" do
150
206
  name:minimal_policyfile
151
207
  run-list-item:recipe[foo]
152
208
  cookbook:foo;id:467dc855408ce8b74f991c5dc2fd72a6aa369b60
209
+ default_attributes:{}
210
+ override_attributes:{}
211
+ REVISION_STRING
212
+ end
213
+
214
+ let(:expected_revision_id) do
215
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
216
+ end
217
+
218
+ let(:compiled_policyfile) do
219
+ {
220
+ "revision_id" => expected_revision_id,
221
+
222
+ "name" => "minimal_policyfile",
223
+
224
+ "run_list" => ["recipe[foo]"],
225
+
226
+ "cookbook_locks" => {
227
+
228
+ "foo" => {
229
+ "version" => "1.0.0",
230
+ "identifier" => cookbook_foo_cksum,
231
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
232
+ "cache_key" => "foo-1.0.0",
233
+ "origin" => nil,
234
+ "source_options" => nil
235
+ },
236
+ },
237
+ "default_attributes" => {},
238
+ "override_attributes" => {},
239
+
240
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
241
+ }
242
+ end
243
+
244
+ it "has a cache path" do
245
+ expect(policyfile_lock.cache_path).to eq(cache_path)
246
+ end
247
+
248
+ it "computes a minimal policyfile" do
249
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
250
+ end
251
+
252
+ it "generates a canonical revision string" do
253
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
254
+ end
255
+
256
+ it "generates a revision id" do
257
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
258
+ end
259
+
260
+ end
261
+
262
+ context "with a policyfile containing attributes" do
263
+
264
+ let(:policyfile_lock) do
265
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
266
+
267
+ p.name = "minimal_policyfile"
268
+
269
+ p.run_list = [ "recipe[foo]" ]
270
+ p.cached_cookbook("foo") do |cb|
271
+ cb.cache_key = "foo-1.0.0"
272
+ end
273
+
274
+ p.default_attributes = {
275
+ "foo" => "bar",
276
+ "aaa".encode('utf-16') => "aaa".encode('utf-16'),
277
+ "ddd" => true,
278
+ "ccc" => false,
279
+ "bbb" => nil,
280
+ "e" => 1.2,
281
+ "f" => 5,
282
+ "g" => 1_000_000_000_000_000.0,
283
+ "nested" => { "a" => "b" }
284
+ }
285
+ p.override_attributes = { "foo2" => "baz" }
286
+
287
+ end
288
+ end
289
+
290
+ let(:expected_canonical_revision_string) do
291
+ <<-REVISION_STRING
292
+ name:minimal_policyfile
293
+ run-list-item:recipe[foo]
294
+ cookbook:foo;id:467dc855408ce8b74f991c5dc2fd72a6aa369b60
295
+ default_attributes:{"aaa":"aaa","bbb":null,"ccc":false,"ddd":true,"e":1.2,"f":5,"foo":"bar","g":1e+15,"nested":{"a":"b"}}
296
+ override_attributes:{"foo2":"baz"}
153
297
  REVISION_STRING
154
298
  end
155
299
 
156
300
  let(:expected_revision_id) do
157
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
301
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
158
302
  end
159
303
 
160
304
  let(:compiled_policyfile) do
@@ -176,6 +320,19 @@ REVISION_STRING
176
320
  "source_options" => nil
177
321
  },
178
322
  },
323
+ "default_attributes" => {
324
+ "foo" => "bar",
325
+ "aaa".encode('utf-16') => "aaa".encode('utf-16'),
326
+ "ddd" => true,
327
+ "ccc" => false,
328
+ "bbb" => nil,
329
+ "e" => 1.2,
330
+ "f" => 5,
331
+ "g" => 1_000_000_000_000_000.0,
332
+ "nested" => { "a" => "b" }
333
+ },
334
+ "override_attributes" => { "foo2" => "baz" },
335
+
179
336
  "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
180
337
  }
181
338
  end
@@ -225,11 +382,13 @@ REVISION_STRING
225
382
  name:dev_cookbook
226
383
  run-list-item:recipe[bar]
227
384
  cookbook:bar;id:#{cookbook_bar_cksum}
385
+ default_attributes:{}
386
+ override_attributes:{}
228
387
  REVISION_STRING
229
388
  end
230
389
 
231
390
  let(:expected_revision_id) do
232
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
391
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
233
392
  end
234
393
 
235
394
  let(:compiled_policyfile) do
@@ -261,6 +420,10 @@ REVISION_STRING
261
420
  "source_options" => nil
262
421
  },
263
422
  },
423
+
424
+ "default_attributes" => {},
425
+ "override_attributes" => {},
426
+
264
427
  "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
265
428
  }
266
429
  end
@@ -319,11 +482,13 @@ name:custom_identifier
319
482
  run-list-item:recipe[foo]
320
483
  cookbook:foo;id:1.0.0
321
484
  cookbook:bar;id:0.1.0
485
+ default_attributes:{}
486
+ override_attributes:{}
322
487
  REVISION_STRING
323
488
  end
324
489
 
325
490
  let(:expected_revision_id) do
326
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
491
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
327
492
  end
328
493
 
329
494
  let(:compiled_policyfile) do
@@ -364,6 +529,10 @@ REVISION_STRING
364
529
  "source_options" => nil
365
530
  },
366
531
  },
532
+
533
+ "default_attributes" => {},
534
+ "override_attributes" => {},
535
+
367
536
  "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
368
537
  }
369
538
  end
@@ -438,11 +607,13 @@ cookbook:foo;id:#{cookbook_foo_cksum}
438
607
  cookbook:bar;id:#{cookbook_bar_cksum}
439
608
  cookbook:baz;id:#{cookbook_baz_cksum}
440
609
  cookbook:dep_of_bar;id:#{cookbook_dep_of_bar_cksum}
610
+ default_attributes:{}
611
+ override_attributes:{}
441
612
  REVISION_STRING
442
613
  end
443
614
 
444
615
  let(:expected_revision_id) do
445
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
616
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
446
617
  end
447
618
 
448
619
  let(:compiled_policyfile) do
@@ -504,6 +675,9 @@ REVISION_STRING
504
675
 
505
676
  },
506
677
 
678
+ "default_attributes" => {},
679
+ "override_attributes" => {},
680
+
507
681
  "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
508
682
 
509
683
  }
@@ -560,11 +734,13 @@ REVISION_STRING
560
734
  name:minimal_policyfile
561
735
  run-list-item:recipe[foo]
562
736
  cookbook:foo;id:#{cookbook_foo_cksum}
737
+ default_attributes:{}
738
+ override_attributes:{}
563
739
  REVISION_STRING
564
740
  end
565
741
 
566
742
  let(:expected_revision_id) do
567
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
743
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
568
744
  end
569
745
 
570
746
  let(:compiled_policyfile) do
@@ -587,6 +763,10 @@ REVISION_STRING
587
763
  "source_options" => nil
588
764
  },
589
765
  },
766
+
767
+ "default_attributes" => {},
768
+ "override_attributes" => {},
769
+
590
770
  "solution_dependencies" => {
591
771
  "Policyfile" => [],
592
772
  "dependencies" => {"foo (1.0.0)" => []}
@@ -624,11 +804,13 @@ name:minimal_policyfile
624
804
  run-list-item:recipe[foo]
625
805
  named-run-list:rl2;run-list-item:recipe[foo::bar]
626
806
  cookbook:foo;id:#{cookbook_foo_cksum}
807
+ default_attributes:{}
808
+ override_attributes:{}
627
809
  REVISION_STRING
628
810
  end
629
811
 
630
812
  let(:expected_revision_id) do
631
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
813
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
632
814
  end
633
815
 
634
816
  let(:compiled_policyfile) do
@@ -654,6 +836,9 @@ REVISION_STRING
654
836
  },
655
837
  },
656
838
 
839
+ "default_attributes" => {},
840
+ "override_attributes" => {},
841
+
657
842
  "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
658
843
  }
659
844
  end
@@ -706,13 +891,48 @@ REVISION_STRING
706
891
  end
707
892
  end
708
893
 
894
+ let(:policyfile_default_attrs) do
895
+ {
896
+ "foo" => "bar",
897
+ "abc" => { "def" => { "ghi" => "xyz" } },
898
+ "baz" => {
899
+ "more_nested_stuff" => "yup",
900
+ "an_array" => ["a", "b", "c"]
901
+ }
902
+ }
903
+ end
904
+
905
+ let(:canonicalized_default_attrs) do
906
+ elements = [
907
+ %q{"abc":{"def":{"ghi":"xyz"}}},
908
+ %q{"baz":{"an_array":["a","b","c"],"more_nested_stuff":"yup"}},
909
+ %q{"foo":"bar"}
910
+ ]
911
+ "{" + elements.join(',') + "}"
912
+ end
913
+
914
+ let(:policyfile_override_attrs) do
915
+ {
916
+ "foo" => "bar",
917
+ "abc" => { "def" => { "ghi" => "xyz" } },
918
+ "baz" => {
919
+ "more_nested_stuff" => "yup",
920
+ "an_array" => ["a", "b", "c"]
921
+ }
922
+ }
923
+ end
924
+
925
+ let(:canonicalized_override_attrs) { canonicalized_default_attrs }
926
+
709
927
  let(:policyfile_compiler) do
710
928
  double( "ChefDK::PolicyfileCompiler",
711
929
  name: "my-policyfile",
712
930
  normalized_run_list: %w[recipe[foo::default] recipe[bar::default]],
713
931
  normalized_named_run_lists: { "rl2" => %w[recipe[bar::default]] },
714
932
  all_cookbook_location_specs: {"foo" => cached_location_spec, "bar" => local_location_spec},
715
- solution_dependencies: policyfile_solution_dependencies )
933
+ solution_dependencies: policyfile_solution_dependencies,
934
+ default_attributes: policyfile_default_attrs,
935
+ override_attributes: policyfile_override_attrs )
716
936
  end
717
937
 
718
938
  let(:policyfile_lock) do
@@ -728,11 +948,13 @@ run-list-item:recipe[bar::default]
728
948
  named-run-list:rl2;run-list-item:recipe[bar::default]
729
949
  cookbook:foo;id:#{cookbook_foo_cksum}
730
950
  cookbook:bar;id:#{cookbook_bar_cksum}
951
+ default_attributes:#{canonicalized_default_attrs}
952
+ override_attributes:#{canonicalized_override_attrs}
731
953
  REVISION_STRING
732
954
  end
733
955
 
734
956
  let(:expected_revision_id) do
735
- Digest::SHA1.new.hexdigest(expected_canonical_revision_string)
957
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
736
958
  end
737
959
 
738
960
  let(:compiled_policyfile) do
@@ -776,6 +998,23 @@ REVISION_STRING
776
998
  }
777
999
  },
778
1000
 
1001
+ "default_attributes" => {
1002
+ "foo" => "bar",
1003
+ "abc" => { "def" => { "ghi" => "xyz" } },
1004
+ "baz" => {
1005
+ "more_nested_stuff" => "yup",
1006
+ "an_array" => ["a", "b", "c"]
1007
+ }
1008
+ },
1009
+
1010
+ "override_attributes" => {
1011
+ "foo" => "bar",
1012
+ "abc" => { "def" => { "ghi" => "xyz" } },
1013
+ "baz" => {
1014
+ "more_nested_stuff" => "yup",
1015
+ "an_array" => ["a", "b", "c"]
1016
+ }
1017
+ },
779
1018
  "solution_dependencies" => {
780
1019
  "Policyfile" => [ [ "foo", "~> 1.0" ] ],
781
1020
  "dependencies" => { "foo (1.0.0)" => [], "bar (0.1.0)" => [] }