cheffish 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +120 -117
  4. data/Rakefile +23 -23
  5. data/lib/chef/provider/chef_acl.rb +439 -434
  6. data/lib/chef/provider/chef_client.rb +53 -48
  7. data/lib/chef/provider/chef_container.rb +55 -50
  8. data/lib/chef/provider/chef_data_bag.rb +55 -50
  9. data/lib/chef/provider/chef_data_bag_item.rb +278 -273
  10. data/lib/chef/provider/chef_environment.rb +83 -78
  11. data/lib/chef/provider/chef_group.rb +83 -78
  12. data/lib/chef/provider/chef_mirror.rb +169 -164
  13. data/lib/chef/provider/chef_node.rb +87 -82
  14. data/lib/chef/provider/chef_organization.rb +155 -150
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -41
  16. data/lib/chef/provider/chef_role.rb +84 -79
  17. data/lib/chef/provider/chef_user.rb +59 -54
  18. data/lib/chef/provider/private_key.rb +225 -220
  19. data/lib/chef/provider/public_key.rb +88 -82
  20. data/lib/chef/resource/chef_acl.rb +69 -65
  21. data/lib/chef/resource/chef_client.rb +48 -44
  22. data/lib/chef/resource/chef_container.rb +22 -18
  23. data/lib/chef/resource/chef_data_bag.rb +22 -18
  24. data/lib/chef/resource/chef_data_bag_item.rb +121 -114
  25. data/lib/chef/resource/chef_environment.rb +77 -71
  26. data/lib/chef/resource/chef_group.rb +53 -49
  27. data/lib/chef/resource/chef_mirror.rb +52 -48
  28. data/lib/chef/resource/chef_node.rb +22 -18
  29. data/lib/chef/resource/chef_organization.rb +69 -64
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -31
  31. data/lib/chef/resource/chef_role.rb +110 -104
  32. data/lib/chef/resource/chef_user.rb +56 -52
  33. data/lib/chef/resource/private_key.rb +48 -44
  34. data/lib/chef/resource/public_key.rb +25 -21
  35. data/lib/cheffish.rb +235 -233
  36. data/lib/cheffish/actor_provider_base.rb +131 -131
  37. data/lib/cheffish/basic_chef_client.rb +184 -184
  38. data/lib/cheffish/chef_provider_base.rb +246 -246
  39. data/lib/cheffish/chef_run.rb +162 -155
  40. data/lib/cheffish/chef_run_data.rb +19 -19
  41. data/lib/cheffish/chef_run_listener.rb +30 -30
  42. data/lib/cheffish/key_formatter.rb +113 -113
  43. data/lib/cheffish/merged_config.rb +94 -94
  44. data/lib/cheffish/recipe_dsl.rb +157 -157
  45. data/lib/cheffish/rspec.rb +8 -8
  46. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  47. data/lib/cheffish/rspec/matchers.rb +4 -4
  48. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  49. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  50. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  51. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  52. data/lib/cheffish/rspec/recipe_run_wrapper.rb +59 -47
  53. data/lib/cheffish/rspec/repository_support.rb +108 -108
  54. data/lib/cheffish/server_api.rb +52 -52
  55. data/lib/cheffish/version.rb +3 -3
  56. data/lib/cheffish/with_pattern.rb +21 -21
  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 -0
  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 -0
  76. metadata +8 -5
@@ -1,64 +1,64 @@
1
- require 'cheffish/key_formatter'
2
- require 'support/key_support'
3
-
4
- describe 'Cheffish fingerprint key formatter' do
5
-
6
- # Sample key: 0x9a6fa4c43b328c3d04c1fbc0498539218b6728e41cd35f6d27d491ef705f0b2083dc1ac977da19f54ba82b044773f20667e9627c543abb3b41b6eb9e4318ca3c68f487bbd0f1c9eea9a3101b7d1d180983c5440ac4183e78e9e256fa687d8aac63b21617a4b02b35bf5e307a3b76961a16cd8493e923536b34cc2b2da8d45220d57ef2243b081b555b84f1da0ade0e896c2aa96911b41430b59eaf75dbffb7eaa7c5b3a686f2d47a24e3b7f1acb0844f84a2fedc63660ae366b800cd9448093d6b1d96503ebb7807b48257e16c3d8a7c9a8cc5dd63116aa673bd9e09754de09358486e743e34c6a3642eeb64b2208efc96df39151572557a75638bd059c21a55 = 0xd6e92677d4e1d2aa6d14f87b5f49ee6916c6b92411536254fae4a21e82eebb0a40600247c701c1c938b21ca9f25b7b330c35fded57b4de3a951e83329a80bdbf2ba138fe2f190bffce43967b5fa93b179367bcd15cb1db7f9e3ab62caca95dc9489b62bc0a10b53841b932455a43409f96eed90dc80abc8cce5593ead8f0a26d * 0xb7f68cd427045788d5e315375f71d3a416784ec2597776a60ed77c821294d9bd66e96658bdcb43072cee0c849d297bd9f94991738f1a0df313ceb51b093a9372f12a61987f40e7a03d773911deb270916a574962ae8ff4f2d8bfcedee1c885e9c3e54212471636a6330b05b78c3a7ddf96b013be389a08ab7971db2f68fb2689
7
-
8
- sample_private_key = <<EOF
9
- -----BEGIN RSA PRIVATE KEY-----
10
- MIIEowIBAAKCAQEAmm+kxDsyjD0EwfvASYU5IYtnKOQc019tJ9SR73BfCyCD3BrJd9oZ9UuoKwRH
11
- c/IGZ+lifFQ6uztBtuueQxjKPGj0h7vQ8cnuqaMQG30dGAmDxUQKxBg+eOniVvpofYqsY7IWF6Sw
12
- KzW/XjB6O3aWGhbNhJPpI1NrNMwrLajUUiDVfvIkOwgbVVuE8doK3g6JbCqpaRG0FDC1nq912/+3
13
- 6qfFs6aG8tR6JOO38aywhE+Eov7cY2YK42a4AM2USAk9ax2WUD67eAe0glfhbD2KfJqMxd1jEWqm
14
- c72eCXVN4JNYSG50PjTGo2Qu62SyII78lt85FRVyVXp1Y4vQWcIaVQIDAQABAoIBABY+JC37FLGs
15
- DCZgOvab0HmrWUVDbX9oDBGjhQ1GUvoISdWGqiOv7vMsXWEssZnabt/CdmPPwdG7nCBbWSTyyhXf
16
- S/DMtTBN1CjsimJbJ7iRjj/4J9DMaRsDHI1IbYo/UcreGF55YsImcJSBSOmNj9rcE+eXYgmrdxJY
17
- oZNm8IWPaZ1/8KdPHSq6/HfTzRxXhcGOMGnf3lGfzkzIbV9Ee88Lv9sSV3bYrOsWMNabOe2TeTpC
18
- UTfFkC++0RkFjEDINSCnoCi+ybzHLUDnurANCwnRWLTVEAeffwNVmiDfgimuqFtzCInW5/5bOTPz
19
- rBmcC6QAFbyk2WKAlY8Zd4SBYqECgYEA1ukmd9Th0qptFPh7X0nuaRbGuSQRU2JU+uSiHoLuuwpA
20
- YAJHxwHByTiyHKnyW3szDDX97Ve03jqVHoMymoC9vyuhOP4vGQv/zkOWe1+pOxeTZ7zRXLHbf546
21
- tiysqV3JSJtivAoQtThBuTJFWkNAn5bu2Q3ICryMzlWT6tjwom0CgYEAt/aM1CcEV4jV4xU3X3HT
22
- pBZ4TsJZd3amDtd8ghKU2b1m6WZYvctDByzuDISdKXvZ+UmRc48aDfMTzrUbCTqTcvEqYZh/QOeg
23
- PXc5Ed6ycJFqV0liro/08ti/zt7hyIXpw+VCEkcWNqYzCwW3jDp935awE744mgireXHbL2j7JokC
24
- gYAOHErRTWHyYgw9dz8qd4E21y7/EvYsQmWP/5kBZdlk4HxvkVbDI0NlAdr39NSb2w/z+kuM3Nhc
25
- Sv5lfXnCGTfcKHIyesX+4AHQujFUMmi7H4YnJoecjXT7ARmbwn0ntae0o7cs34BPVb1C+qEBFy9U
26
- CyXtjHEY+15HYekPX2UVVQKBgBT8Nwxsdv5VSbDh1rM4lN//ADJb0UDjdAX1ZuqfnANKq9asKitc
27
- aIUFBxK+ff8hdbgOQF1iUaKNvBC0cCUZXYCbKi5/6uRIh+r7ErOLJ+fXbr4OTQeEvHiHaTn8Ct2J
28
- CSWjnWngWhRZ2TDEsi947Kr40ZUu+d34ZzcvWcWKwDuhAoGBAJzCRoGOu6YGy+rBPxaIg0vB+Grx
29
- rxs0NeNqGdrzmyAPN35OHXYclPwfp+DbtbJHgGMRc/9VFPqW9PeTKjIByeEsXyrcdreR35AR/fwR
30
- AUcSSKTvw+PobCpXhdkiw4TgJhFNuZnoC63FOjNqA5mu1ICZYBb4ZVlgUAgSmDQxSIgK
31
- -----END RSA PRIVATE KEY-----
32
- EOF
33
- sample_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCab6TEOzKMPQTB+8BJhTkhi2co5BzTX20n1JHvcF8LIIPcGsl32hn1S6grBEdz8gZn6WJ8VDq7O0G2655DGMo8aPSHu9Dxye6poxAbfR0YCYPFRArEGD546eJW+mh9iqxjshYXpLArNb9eMHo7dpYaFs2Ek+kjU2s0zCstqNRSINV+8iQ7CBtVW4Tx2greDolsKqlpEbQUMLWer3Xb/7fqp8Wzpoby1Hok47fxrLCET4Si/txjZgrjZrgAzZRICT1rHZZQPrt4B7SCV+FsPYp8mozF3WMRaqZzvZ4JdU3gk1hIbnQ+NMajZC7rZLIgjvyW3zkVFXJVenVji9BZwhpV"
34
-
35
- def key_to_format(key, format)
36
- keyobj, f = Cheffish::KeyFormatter.decode(key)
37
- Cheffish::KeyFormatter.encode(keyobj, {:format => format})
38
- end
39
-
40
- context 'when computing key fingperprints' do
41
-
42
- it 'computes the PKCS#8 SHA1 private key fingerprint correctly', :pending => (RUBY_VERSION.to_f >= 2.0) do
43
- expect(key_to_format(sample_private_key, :pkcs8sha1fingerprint)).to eq(
44
- '88:7e:3a:bd:26:9f:b5:c5:d8:ae:52:f9:df:0b:64:a4:5c:17:0a:87')
45
- end
46
-
47
- it 'computes the PKCS#1 MD5 public key fingerprint correctly' do
48
- expect(key_to_format(sample_public_key, :pkcs1md5fingerprint)).to eq(
49
- '1f:e8:da:c1:16:c3:72:7d:90:e2:b7:64:c4:b4:55:20')
50
- end
51
-
52
- it 'computes the RFC4716 MD5 public key fingerprint correctly' do
53
- expect(key_to_format(sample_public_key, :rfc4716md5fingerprint)).to eq(
54
- 'b0:13:4f:da:cf:8c:dc:a7:4a:1f:d2:3a:51:92:cf:6b')
55
- end
56
-
57
- it 'defaults to the PKCS#1 MD5 public key fingerprint' do
58
- expect(key_to_format(sample_public_key, :fingerprint)).to eq(
59
- key_to_format(sample_public_key, :pkcs1md5fingerprint))
60
- end
61
-
62
- end
63
-
64
- end
1
+ require 'cheffish/key_formatter'
2
+ require 'support/key_support'
3
+
4
+ describe 'Cheffish fingerprint key formatter' do
5
+
6
+ # Sample key: 0x9a6fa4c43b328c3d04c1fbc0498539218b6728e41cd35f6d27d491ef705f0b2083dc1ac977da19f54ba82b044773f20667e9627c543abb3b41b6eb9e4318ca3c68f487bbd0f1c9eea9a3101b7d1d180983c5440ac4183e78e9e256fa687d8aac63b21617a4b02b35bf5e307a3b76961a16cd8493e923536b34cc2b2da8d45220d57ef2243b081b555b84f1da0ade0e896c2aa96911b41430b59eaf75dbffb7eaa7c5b3a686f2d47a24e3b7f1acb0844f84a2fedc63660ae366b800cd9448093d6b1d96503ebb7807b48257e16c3d8a7c9a8cc5dd63116aa673bd9e09754de09358486e743e34c6a3642eeb64b2208efc96df39151572557a75638bd059c21a55 = 0xd6e92677d4e1d2aa6d14f87b5f49ee6916c6b92411536254fae4a21e82eebb0a40600247c701c1c938b21ca9f25b7b330c35fded57b4de3a951e83329a80bdbf2ba138fe2f190bffce43967b5fa93b179367bcd15cb1db7f9e3ab62caca95dc9489b62bc0a10b53841b932455a43409f96eed90dc80abc8cce5593ead8f0a26d * 0xb7f68cd427045788d5e315375f71d3a416784ec2597776a60ed77c821294d9bd66e96658bdcb43072cee0c849d297bd9f94991738f1a0df313ceb51b093a9372f12a61987f40e7a03d773911deb270916a574962ae8ff4f2d8bfcedee1c885e9c3e54212471636a6330b05b78c3a7ddf96b013be389a08ab7971db2f68fb2689
7
+
8
+ sample_private_key = <<EOF
9
+ -----BEGIN RSA PRIVATE KEY-----
10
+ MIIEowIBAAKCAQEAmm+kxDsyjD0EwfvASYU5IYtnKOQc019tJ9SR73BfCyCD3BrJd9oZ9UuoKwRH
11
+ c/IGZ+lifFQ6uztBtuueQxjKPGj0h7vQ8cnuqaMQG30dGAmDxUQKxBg+eOniVvpofYqsY7IWF6Sw
12
+ KzW/XjB6O3aWGhbNhJPpI1NrNMwrLajUUiDVfvIkOwgbVVuE8doK3g6JbCqpaRG0FDC1nq912/+3
13
+ 6qfFs6aG8tR6JOO38aywhE+Eov7cY2YK42a4AM2USAk9ax2WUD67eAe0glfhbD2KfJqMxd1jEWqm
14
+ c72eCXVN4JNYSG50PjTGo2Qu62SyII78lt85FRVyVXp1Y4vQWcIaVQIDAQABAoIBABY+JC37FLGs
15
+ DCZgOvab0HmrWUVDbX9oDBGjhQ1GUvoISdWGqiOv7vMsXWEssZnabt/CdmPPwdG7nCBbWSTyyhXf
16
+ S/DMtTBN1CjsimJbJ7iRjj/4J9DMaRsDHI1IbYo/UcreGF55YsImcJSBSOmNj9rcE+eXYgmrdxJY
17
+ oZNm8IWPaZ1/8KdPHSq6/HfTzRxXhcGOMGnf3lGfzkzIbV9Ee88Lv9sSV3bYrOsWMNabOe2TeTpC
18
+ UTfFkC++0RkFjEDINSCnoCi+ybzHLUDnurANCwnRWLTVEAeffwNVmiDfgimuqFtzCInW5/5bOTPz
19
+ rBmcC6QAFbyk2WKAlY8Zd4SBYqECgYEA1ukmd9Th0qptFPh7X0nuaRbGuSQRU2JU+uSiHoLuuwpA
20
+ YAJHxwHByTiyHKnyW3szDDX97Ve03jqVHoMymoC9vyuhOP4vGQv/zkOWe1+pOxeTZ7zRXLHbf546
21
+ tiysqV3JSJtivAoQtThBuTJFWkNAn5bu2Q3ICryMzlWT6tjwom0CgYEAt/aM1CcEV4jV4xU3X3HT
22
+ pBZ4TsJZd3amDtd8ghKU2b1m6WZYvctDByzuDISdKXvZ+UmRc48aDfMTzrUbCTqTcvEqYZh/QOeg
23
+ PXc5Ed6ycJFqV0liro/08ti/zt7hyIXpw+VCEkcWNqYzCwW3jDp935awE744mgireXHbL2j7JokC
24
+ gYAOHErRTWHyYgw9dz8qd4E21y7/EvYsQmWP/5kBZdlk4HxvkVbDI0NlAdr39NSb2w/z+kuM3Nhc
25
+ Sv5lfXnCGTfcKHIyesX+4AHQujFUMmi7H4YnJoecjXT7ARmbwn0ntae0o7cs34BPVb1C+qEBFy9U
26
+ CyXtjHEY+15HYekPX2UVVQKBgBT8Nwxsdv5VSbDh1rM4lN//ADJb0UDjdAX1ZuqfnANKq9asKitc
27
+ aIUFBxK+ff8hdbgOQF1iUaKNvBC0cCUZXYCbKi5/6uRIh+r7ErOLJ+fXbr4OTQeEvHiHaTn8Ct2J
28
+ CSWjnWngWhRZ2TDEsi947Kr40ZUu+d34ZzcvWcWKwDuhAoGBAJzCRoGOu6YGy+rBPxaIg0vB+Grx
29
+ rxs0NeNqGdrzmyAPN35OHXYclPwfp+DbtbJHgGMRc/9VFPqW9PeTKjIByeEsXyrcdreR35AR/fwR
30
+ AUcSSKTvw+PobCpXhdkiw4TgJhFNuZnoC63FOjNqA5mu1ICZYBb4ZVlgUAgSmDQxSIgK
31
+ -----END RSA PRIVATE KEY-----
32
+ EOF
33
+ sample_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCab6TEOzKMPQTB+8BJhTkhi2co5BzTX20n1JHvcF8LIIPcGsl32hn1S6grBEdz8gZn6WJ8VDq7O0G2655DGMo8aPSHu9Dxye6poxAbfR0YCYPFRArEGD546eJW+mh9iqxjshYXpLArNb9eMHo7dpYaFs2Ek+kjU2s0zCstqNRSINV+8iQ7CBtVW4Tx2greDolsKqlpEbQUMLWer3Xb/7fqp8Wzpoby1Hok47fxrLCET4Si/txjZgrjZrgAzZRICT1rHZZQPrt4B7SCV+FsPYp8mozF3WMRaqZzvZ4JdU3gk1hIbnQ+NMajZC7rZLIgjvyW3zkVFXJVenVji9BZwhpV"
34
+
35
+ def key_to_format(key, format)
36
+ keyobj, f = Cheffish::KeyFormatter.decode(key)
37
+ Cheffish::KeyFormatter.encode(keyobj, {:format => format})
38
+ end
39
+
40
+ context 'when computing key fingperprints' do
41
+
42
+ it 'computes the PKCS#8 SHA1 private key fingerprint correctly', :pending => (RUBY_VERSION.to_f >= 2.0) do
43
+ expect(key_to_format(sample_private_key, :pkcs8sha1fingerprint)).to eq(
44
+ '88:7e:3a:bd:26:9f:b5:c5:d8:ae:52:f9:df:0b:64:a4:5c:17:0a:87')
45
+ end
46
+
47
+ it 'computes the PKCS#1 MD5 public key fingerprint correctly' do
48
+ expect(key_to_format(sample_public_key, :pkcs1md5fingerprint)).to eq(
49
+ '1f:e8:da:c1:16:c3:72:7d:90:e2:b7:64:c4:b4:55:20')
50
+ end
51
+
52
+ it 'computes the RFC4716 MD5 public key fingerprint correctly' do
53
+ expect(key_to_format(sample_public_key, :rfc4716md5fingerprint)).to eq(
54
+ 'b0:13:4f:da:cf:8c:dc:a7:4a:1f:d2:3a:51:92:cf:6b')
55
+ end
56
+
57
+ it 'defaults to the PKCS#1 MD5 public key fingerprint' do
58
+ expect(key_to_format(sample_public_key, :fingerprint)).to eq(
59
+ key_to_format(sample_public_key, :pkcs1md5fingerprint))
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -1,20 +1,20 @@
1
- require 'cheffish/merged_config'
2
-
3
- describe "merged_config" do
4
-
5
- let(:config) do
6
- Cheffish::MergedConfig.new({:test=>'val'})
7
- end
8
-
9
- it "returns value in config" do
10
- expect(config.test).to eq('val')
11
- end
12
-
13
- it "raises a NoMethodError if calling an unknown method with arguments" do
14
- expect{config.merge({:some => 'hash'})}.to raise_error(NoMethodError)
15
- end
16
-
17
- it "has an informative string representation" do
18
- expect("#{config}").to eq("{:test=>\"val\"}")
19
- end
1
+ require 'cheffish/merged_config'
2
+
3
+ describe "merged_config" do
4
+
5
+ let(:config) do
6
+ Cheffish::MergedConfig.new({:test=>'val'})
7
+ end
8
+
9
+ it "returns value in config" do
10
+ expect(config.test).to eq('val')
11
+ end
12
+
13
+ it "raises a NoMethodError if calling an unknown method with arguments" do
14
+ expect{config.merge({:some => 'hash'})}.to raise_error(NoMethodError)
15
+ end
16
+
17
+ it "has an informative string representation" do
18
+ expect("#{config}").to eq("{:test=>\"val\"}")
19
+ end
20
20
  end
@@ -1,13 +1,13 @@
1
- require 'cheffish'
2
-
3
- describe "api version" do
4
-
5
- let(:server_api) do
6
- Cheffish.chef_server_api({:chef_server_url => "my.chef.server"})
7
- end
8
-
9
- it "is pinned to 0" do
10
- expect(Cheffish::ServerAPI).to receive(:new).with("my.chef.server", {api_version: "0"})
11
- server_api
12
- end
13
- end
1
+ require 'cheffish'
2
+
3
+ describe "api version" do
4
+
5
+ let(:server_api) do
6
+ Cheffish.chef_server_api({:chef_server_url => "my.chef.server"})
7
+ end
8
+
9
+ it "is pinned to 0" do
10
+ expect(Cheffish::ServerAPI).to receive(:new).with("my.chef.server", {api_version: "0"})
11
+ server_api
12
+ end
13
+ end
@@ -1,879 +1,879 @@
1
- require 'support/spec_support'
2
- require 'cheffish/rspec/chef_run_support'
3
- require 'chef/resource/chef_acl'
4
- require 'chef/provider/chef_acl'
5
- require 'chef_zero/version'
6
- require 'uri'
7
-
8
- if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
9
- describe Chef::Resource::ChefAcl do
10
- extend Cheffish::RSpec::ChefRunSupport
11
-
12
- # let(:chef_config) { super().merge(log_level: :debug, stdout: STDOUT, stderr: STDERR, log_location: STDOUT) }
13
-
14
- context "Rights attributes" do
15
- when_the_chef_server 'has a node named x', :osc_compat => false do
16
- node 'x', {}
17
-
18
- it 'Converging chef_acl "nodes/x" changes nothing' do
19
- expect_recipe {
20
- chef_acl 'nodes/x'
21
- }.to be_up_to_date
22
- expect(get('nodes/x/_acl')).to partially_match({})
23
- end
24
-
25
- it 'Converging chef_acl "nodes/x" with "complete true" and no rights raises an error' do
26
- expect_converge {
27
- chef_acl 'nodes/x' do
28
- complete true
29
- end
30
- }.to raise_error(RuntimeError)
31
- end
32
-
33
- it 'Removing all :grant rights from a node raises an error' do
34
- expect_converge {
35
- chef_acl 'nodes/x' do
36
- remove_rights :grant, users: %w(pivotal), groups: %w(admins users clients)
37
- end
38
- }.to raise_error(RuntimeError)
39
- end
40
-
41
- context 'and a user "blarghle"' do
42
- user 'blarghle', {}
43
-
44
- it 'Converging chef_acl "nodes/x" with user "blarghle" adds the user' do
45
- expect_recipe {
46
- chef_acl 'nodes/x' do
47
- rights :read, users: %w(blarghle)
48
- end
49
- }.to be_updated
50
- expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
51
- end
52
-
53
- it 'Converging chef_acl "nodes/x" with "complete true" removes all ACLs except those specified' do
54
- expect_recipe {
55
- chef_acl 'nodes/x' do
56
- rights :grant, users: %w(blarghle)
57
- complete true
58
- end
59
- }.to be_updated
60
- expect(get('nodes/x/_acl')).to eq(
61
- "create"=>{"actors"=>[], "groups"=>[]},
62
- "read" =>{"actors"=>[], "groups"=>[]},
63
- "update"=>{"actors"=>[], "groups"=>[]},
64
- "delete"=>{"actors"=>[], "groups"=>[]},
65
- "grant" =>{"actors"=>["blarghle"], "groups"=>[]}
66
- )
67
- end
68
- end
69
-
70
- it 'Converging chef_acl "nodes/x" with "complete true" removes all ACLs except those specified in :all' do
71
- expect_recipe {
72
- chef_acl 'nodes/x' do
73
- rights :all, users: %w(blarghle)
74
- complete true
75
- end
76
- }.to be_updated
77
- expect(get('nodes/x/_acl')).to eq(
78
- "create"=>{"actors"=>["blarghle"], "groups"=>[]},
79
- "read" =>{"actors"=>["blarghle"], "groups"=>[]},
80
- "update"=>{"actors"=>["blarghle"], "groups"=>[]},
81
- "delete"=>{"actors"=>["blarghle"], "groups"=>[]},
82
- "grant" =>{"actors"=>["blarghle"], "groups"=>[]}
83
- )
84
- end
85
-
86
- context 'and a client "blarghle"' do
87
- user 'blarghle', {}
88
-
89
- it 'Converging chef_acl "nodes/x" with client "blarghle" adds the client' do
90
- expect_recipe {
91
- chef_acl 'nodes/x' do
92
- rights :read, clients: %w(blarghle)
93
- end
94
- }.to be_updated
95
- expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
96
- end
97
- end
98
-
99
- context 'and a group "blarghle"' do
100
- group 'blarghle', {}
101
-
102
- it 'Converging chef_acl "nodes/x" with group "blarghle" adds the group' do
103
- expect_recipe {
104
- chef_acl 'nodes/x' do
105
- rights :read, groups: %w(blarghle)
106
- end
107
- }.to be_updated
108
- expect(get('nodes/x/_acl')).to partially_match('read' => { 'groups' => %w(blarghle) })
109
- end
110
- end
111
-
112
- context 'and multiple users and groups' do
113
- user 'u1', {}
114
- user 'u2', {}
115
- user 'u3', {}
116
- client 'c1', {}
117
- client 'c2', {}
118
- client 'c3', {}
119
- group 'g1', {}
120
- group 'g2', {}
121
- group 'g3', {}
122
-
123
- it 'Converging chef_acl "nodes/x" with multiple groups, users and clients in an acl makes the appropriate changes' do
124
- expect_recipe {
125
- chef_acl 'nodes/x' do
126
- rights :create, users: [ 'u1', 'u2', 'u3' ], clients: [ 'c1', 'c2', 'c3' ], groups: [ 'g1', 'g2', 'g3' ]
127
- end
128
- }.to be_updated
129
- expect(get('nodes/x/_acl')).to partially_match(
130
- 'create' => { 'groups' => %w(g1 g2 g3), 'actors' => %w(u1 u2 u3 c1 c2 c3) }
131
- )
132
- end
133
-
134
- it 'Converging chef_acl "nodes/x" with multiple groups, users and clients across multiple "rights" groups makes the appropriate changes' do
135
- expect_recipe {
136
- chef_acl 'nodes/x' do
137
- rights :create, users: %w(u1), clients: %w(c1), groups: %w(g1)
138
- rights :create, users: %w(u2 u3), clients: %w(c2 c3), groups: %w(g2)
139
- rights :read, users: %w(u1)
140
- rights :read, groups: %w(g1)
141
- end
142
- }.to be_updated
143
- expect(get('nodes/x/_acl')).to partially_match(
144
- 'create' => { 'groups' => %w(g1 g2), 'actors' => %w(u1 u2 u3 c1 c2 c3) },
145
- 'read' => { 'groups' => %w(g1), 'actors' => %w(u1) }
146
- )
147
- end
148
-
149
- it 'Converging chef_acl "nodes/x" with rights [ :read, :create, :update, :delete, :grant ] modifies all rights' do
150
- expect_recipe {
151
- chef_acl 'nodes/x' do
152
- rights [ :create, :read, :update, :delete, :grant ], users: %w(u1 u2), clients: %w(c1), groups: %w(g1)
153
- end
154
- }.to be_updated
155
- expect(get('nodes/x/_acl')).to partially_match(
156
- 'create' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
157
- 'read' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
158
- 'update' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
159
- 'delete' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
160
- 'grant' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
161
- )
162
- end
163
-
164
- it 'Converging chef_acl "nodes/x" with rights :all modifies all rights' do
165
- expect_recipe {
166
- chef_acl 'nodes/x' do
167
- rights :all, users: %w(u1 u2), clients: %w(c1), groups: %w(g1)
168
- end
169
- }.to be_updated
170
- expect(get('nodes/x/_acl')).to partially_match(
171
- 'create' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
172
- 'read' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
173
- 'update' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
174
- 'delete' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
175
- 'grant' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
176
- )
177
- end
178
- end
179
-
180
- it 'Converging chef_acl "nodes/y" throws a 404' do
181
- expect_converge {
182
- chef_acl 'nodes/y'
183
- }.to raise_error(Net::HTTPServerException)
184
- end
185
- end
186
-
187
- when_the_chef_server 'has a node named x with user blarghle in its acl', :osc_compat => false do
188
- user 'blarghle', {}
189
- node 'x', {} do
190
- acl 'read' => { 'actors' => %w(blarghle) }
191
- end
192
-
193
- it 'Converging chef_acl "nodes/x" with that user changes nothing' do
194
- expect_recipe {
195
- chef_acl 'nodes/x' do
196
- rights :read, users: %w(blarghle)
197
- end
198
- }.to be_up_to_date
199
- expect(get('nodes/x/_acl')).to partially_match({})
200
- end
201
- end
202
-
203
- when_the_chef_server 'has a node named x with users foo and bar in all its acls', :osc_compat => false do
204
- user 'foo', {}
205
- user 'bar', {}
206
- node 'x', {} do
207
- acl 'create' => { 'actors' => %w(foo bar) },
208
- 'read' => { 'actors' => %w(foo bar) },
209
- 'update' => { 'actors' => %w(foo bar) },
210
- 'delete' => { 'actors' => %w(foo bar) },
211
- 'grant' => { 'actors' => %w(foo bar) }
212
- end
213
-
214
- it 'Converging chef_acl "nodes/x" with remove_rights :all removes foo from everything' do
215
- expect_recipe {
216
- chef_acl 'nodes/x' do
217
- remove_rights :all, users: %w(foo)
218
- end
219
- }.to be_updated
220
- expect(get('nodes/x/_acl')).to partially_match(
221
- 'create' => { 'actors' => exclude('foo') },
222
- 'read' => { 'actors' => exclude('foo') },
223
- 'update' => { 'actors' => exclude('foo') },
224
- 'delete' => { 'actors' => exclude('foo') },
225
- 'grant' => { 'actors' => exclude('foo') },
226
- )
227
- end
228
- end
229
-
230
- ::RSpec::Matchers.define_negated_matcher :exclude, :include
231
-
232
- context 'recursive' do
233
- when_the_chef_server 'has a nodes container with user blarghle in its acl', :osc_compat => false do
234
- user 'blarghle', {}
235
- acl_for 'containers/nodes', 'read' => { 'actors' => %w(blarghle) }
236
- node 'x', {} do
237
- acl 'read' => { 'actors' => [] }
238
- end
239
-
240
- it 'Converging chef_acl "nodes" makes no changes' do
241
- expect {
242
- expect_recipe {
243
- chef_acl 'nodes' do
244
- rights :read, users: %w(blarghle)
245
- end
246
- }.to be_up_to_date
247
- }.to not_change { get('containers/nodes/_acl') }.
248
- and not_change { get('nodes/x/_acl') }
249
- end
250
-
251
- RSpec::Matchers.define_negated_matcher :not_change, :change
252
-
253
- it 'Converging chef_acl "nodes" with recursive :on_change makes no changes' do
254
- expect {
255
- expect_recipe {
256
- chef_acl 'nodes' do
257
- rights :read, users: %w(blarghle)
258
- recursive :on_change
259
- end
260
- }.to be_up_to_date
261
- }.to not_change { get('containers/nodes/_acl') }.
262
- and not_change { get('nodes/x/_acl') }
263
- end
264
-
265
- it 'Converging chef_acl "nodes" with recursive true changes nodes/x\'s acls' do
266
- expect_recipe {
267
- chef_acl 'nodes' do
268
- rights :read, users: %w(blarghle)
269
- recursive true
270
- end
271
- }.to be_updated
272
- expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
273
- end
274
-
275
- it 'Converging chef_acl "" with recursive false does not change nodes/x\'s acls' do
276
- expect_recipe {
277
- chef_acl '' do
278
- rights :read, users: %w(blarghle)
279
- recursive false
280
- end
281
- }.to be_updated
282
- expect(get('containers/nodes/_acl')).to partially_match({})
283
- expect(get('nodes/x/_acl')).to partially_match({})
284
- end
285
-
286
- it 'Converging chef_acl "" with recursive :on_change does not change nodes/x\'s acls' do
287
- expect_recipe {
288
- chef_acl '' do
289
- rights :read, users: %w(blarghle)
290
- recursive :on_change
291
- end
292
- }.to be_updated
293
- expect(get('containers/nodes/_acl')).to partially_match({})
294
- expect(get('nodes/x/_acl')).to partially_match({})
295
- end
296
-
297
- it 'Converging chef_acl "" with recursive true changes nodes/x\'s acls' do
298
- expect_recipe {
299
- chef_acl '' do
300
- rights :read, users: %w(blarghle)
301
- recursive true
302
- end
303
- }.to be_updated
304
- expect(get('/organizations/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
305
- expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
306
- end
307
- end
308
- end
309
- end
310
-
311
- context 'ACLs on each type of thing' do
312
- when_the_chef_server 'has an organization named foo', :osc_compat => false, :single_org => false do
313
- organization 'foo' do
314
- user 'u', {}
315
- client 'x', {}
316
- container 'x', {}
317
- cookbook 'x', '1.0.0', {}
318
- data_bag 'x', { 'y' => {} }
319
- environment 'x', {}
320
- group 'x', {}
321
- node 'x', {}
322
- role 'x', {}
323
- sandbox 'x', {}
324
- user 'x', {}
325
- end
326
-
327
- organization 'bar' do
328
- user 'u', {}
329
- node 'x', {}
330
- end
331
-
332
- context 'and the chef server URL points at /organizations/foo' do
333
- before :each do
334
- Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
335
- end
336
-
337
- context 'relative paths' do
338
- it "chef_acl 'nodes/x' changes the acls" do
339
- expect_recipe {
340
- chef_acl "nodes/x" do
341
- rights :read, users: %w(u)
342
- end
343
- }.to be_updated
344
- expect(get("nodes/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
345
- end
346
-
347
- it "chef_acl '*/*' changes the acls" do
348
- expect_recipe {
349
- chef_acl "*/*" do
350
- rights :read, users: %w(u)
351
- end
352
- }.to be_updated
353
- %w(clients containers cookbooks data environments groups nodes roles).each do |type|
354
- expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match(
355
- 'read' => { 'actors' => %w(u) })
356
- end
357
- end
358
- end
359
-
360
- context 'absolute paths' do
361
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
362
- it "chef_acl '/organizations/foo/#{type}/x' changes the acl" do
363
- expect_recipe {
364
- chef_acl "/organizations/foo/#{type}/x" do
365
- rights :read, users: %w(u)
366
- end
367
- }.to be_updated
368
- expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
369
- end
370
- end
371
-
372
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
373
- it "chef_acl '/organizations/foo/#{type}/x' changes the acl" do
374
- expect_recipe {
375
- chef_acl "/organizations/foo/#{type}/x" do
376
- rights :read, users: %w(u)
377
- end
378
- }.to be_updated
379
- expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
380
- end
381
- end
382
-
383
- %w(clients containers cookbooks data environments groups nodes roles).each do |type|
384
- it "chef_acl '/*/*/#{type}/*' changes the acl" do
385
- expect_recipe {
386
- chef_acl "/*/*/#{type}/*" do
387
- rights :read, users: %w(u)
388
- end
389
- }.to be_updated
390
- expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
391
- end
392
- end
393
-
394
- it "chef_acl '/*/*/*/x' changes the acls" do
395
- expect_recipe {
396
- chef_acl "/*/*/*/x" do
397
- rights :read, users: %w(u)
398
- end
399
- }.to be_updated
400
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
401
- expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match(
402
- 'read' => { 'actors' => %w(u) })
403
- end
404
- end
405
-
406
- it "chef_acl '/*/*/*/*' changes the acls" do
407
- expect_recipe {
408
- chef_acl "/*/*/*/*" do
409
- rights :read, users: %w(u)
410
- end
411
- }.to be_updated
412
- %w(clients containers cookbooks data environments groups nodes roles).each do |type|
413
- expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match(
414
- 'read' => { 'actors' => %w(u) })
415
- end
416
- end
417
-
418
- it 'chef_acl "/organizations/foo/data_bags/x" changes the acl' do
419
- expect_recipe {
420
- chef_acl '/organizations/foo/data_bags/x' do
421
- rights :read, users: %w(u)
422
- end
423
- }.to be_updated
424
- expect(get('/organizations/foo/data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
425
- end
426
-
427
- it 'chef_acl "/*/*/data_bags/*" changes the acl' do
428
- expect_recipe {
429
- chef_acl '/*/*/data_bags/*' do
430
- rights :read, users: %w(u)
431
- end
432
- }.to be_updated
433
- expect(get('/organizations/foo/data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
434
- end
435
-
436
- it "chef_acl '/organizations/foo/cookbooks/x/1.0.0' raises an error" do
437
- expect_converge {
438
- chef_acl "/organizations/foo/cookbooks/x/1.0.0" do
439
- rights :read, users: %w(u)
440
- end
441
- }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/cookbooks\/x/)
442
- end
443
-
444
- it "chef_acl '/organizations/foo/cookbooks/*/*' raises an error" do
445
- pending
446
- expect_converge {
447
- chef_acl "/organizations/foo/cookbooks/*/*" do
448
- rights :read, users: %w(u)
449
- end
450
- }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/cookbooks\/*/)
451
- end
452
-
453
- it 'chef_acl "/organizations/foo/data/x/y" raises an error' do
454
- expect_converge {
455
- chef_acl '/organizations/foo/data/x/y' do
456
- rights :read, users: %w(u)
457
- end
458
- }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/data\/x/)
459
- end
460
-
461
- it 'chef_acl "/organizations/foo/data/*/*" raises an error' do
462
- pending
463
- expect_converge {
464
- chef_acl '/organizations/foo/data/*/*' do
465
- rights :read, users: %w(u)
466
- end
467
- }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/data\/*/)
468
- end
469
-
470
- it 'chef_acl "/organizations/foo" changes the acl' do
471
- expect_recipe {
472
- chef_acl '/organizations/foo' do
473
- rights :read, users: %w(u)
474
- end
475
- }.to be_updated
476
- expect(get('/organizations/foo/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
477
- expect(get('/organizations/foo/nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
478
- end
479
-
480
- it 'chef_acl "/organizations/*" changes the acl' do
481
- expect_recipe {
482
- chef_acl '/organizations/*' do
483
- rights :read, users: %w(u)
484
- end
485
- }.to be_updated
486
- expect(get('/organizations/foo/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
487
- expect(get('/organizations/foo/nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
488
- end
489
-
490
- it 'chef_acl "/users/x" changes the acl' do
491
- expect_recipe {
492
- chef_acl '/users/x' do
493
- rights :read, users: %w(u)
494
- end
495
- }.to be_updated
496
- expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
497
- end
498
-
499
- it 'chef_acl "/users/*" changes the acl' do
500
- expect_recipe {
501
- chef_acl '/users/*' do
502
- rights :read, users: %w(u)
503
- end
504
- }.to be_updated
505
- expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
506
- end
507
-
508
- it 'chef_acl "/*/x" changes the acl' do
509
- expect_recipe {
510
- chef_acl '/*/x' do
511
- rights :read, users: %w(u)
512
- end
513
- }.to be_updated
514
- expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
515
- end
516
-
517
- it 'chef_acl "/*/*" changes the acl' do
518
- expect_recipe {
519
- chef_acl '/*/*' do
520
- rights :read, users: %w(u)
521
- end
522
- }.to be_updated
523
- expect(get('/organizations/foo/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
524
- expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
525
- end
526
- end
527
- end
528
-
529
- context 'and the chef server URL points at /organizations/bar' do
530
- before :each do
531
- Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url.to_s, '/organizations/bar').to_s
532
- end
533
-
534
- it "chef_acl '/organizations/foo/nodes/*' changes the acl" do
535
- expect_recipe {
536
- chef_acl "/organizations/foo/nodes/*" do
537
- rights :read, users: %w(u)
538
- end
539
- }.to be_updated
540
- expect(get("/organizations/foo/nodes/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
541
- end
542
- end
543
-
544
- context 'and the chef server URL points at /' do
545
- before :each do
546
- Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url.to_s, '/').to_s
547
- end
548
-
549
- it "chef_acl '/organizations/foo/nodes/*' changes the acl" do
550
- expect_recipe {
551
- chef_acl "/organizations/foo/nodes/*" do
552
- rights :read, users: %w(u)
553
- end
554
- }.to be_updated
555
- expect(get("/organizations/foo/nodes/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
556
- end
557
- end
558
- end
559
-
560
- when_the_chef_server 'has a user "u" in single org mode', :osc_compat => false do
561
- user 'u', {}
562
- client 'x', {}
563
- container 'x', {}
564
- cookbook 'x', '1.0.0', {}
565
- data_bag 'x', { 'y' => {} }
566
- environment 'x', {}
567
- group 'x', {}
568
- node 'x', {}
569
- role 'x', {}
570
- sandbox 'x', {}
571
- user 'x', {}
572
-
573
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
574
- it "chef_acl #{type}/x' changes the acl" do
575
- expect_recipe {
576
- chef_acl "#{type}/x" do
577
- rights :read, users: %w(u)
578
- end
579
- }.to be_updated
580
- expect(get("#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
581
- end
582
- end
583
-
584
- %w(clients containers cookbooks data environments groups nodes roles).each do |type|
585
- it "chef_acl '#{type}/*' changes the acl" do
586
- expect_recipe {
587
- chef_acl "#{type}/*" do
588
- rights :read, users: %w(u)
589
- end
590
- }.to be_updated
591
- expect(get("#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
592
- end
593
- end
594
-
595
- it "chef_acl '*/x' changes the acls" do
596
- expect_recipe {
597
- chef_acl "*/x" do
598
- rights :read, users: %w(u)
599
- end
600
- }.to be_updated
601
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
602
- expect(get("#{type}/x/_acl")).to partially_match(
603
- 'read' => { 'actors' => %w(u) })
604
- end
605
- end
606
-
607
- it "chef_acl '*/*' changes the acls" do
608
- expect_recipe {
609
- chef_acl "*/*" do
610
- rights :read, users: %w(u)
611
- end
612
- }.to be_updated
613
- %w(clients containers cookbooks data environments groups nodes roles).each do |type|
614
- expect(get("#{type}/x/_acl")).to partially_match(
615
- 'read' => { 'actors' => %w(u) })
616
- end
617
- end
618
-
619
- it "chef_acl 'groups/*' changes the acl" do
620
- expect_recipe {
621
- chef_acl "groups/*" do
622
- rights :read, users: %w(u)
623
- end
624
- }.to be_updated
625
- %w(admins billing-admins clients users x).each do |n|
626
- expect(get("groups/#{n}/_acl")).to partially_match(
627
- 'read' => { 'actors' => %w(u) })
628
- end
629
- end
630
-
631
- it 'chef_acl "data_bags/x" changes the acl' do
632
- expect_recipe {
633
- chef_acl 'data_bags/x' do
634
- rights :read, users: %w(u)
635
- end
636
- }.to be_updated
637
- expect(get('data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
638
- end
639
-
640
- it 'chef_acl "data_bags/*" changes the acl' do
641
- expect_recipe {
642
- chef_acl 'data_bags/*' do
643
- rights :read, users: %w(u)
644
- end
645
- }.to be_updated
646
- expect(get('data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
647
- end
648
-
649
- it 'chef_acl "" changes the organization acl' do
650
- expect_recipe {
651
- chef_acl '' do
652
- rights :read, users: %w(u)
653
- end
654
- }.to be_updated
655
- expect(get('/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
656
- expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
657
- end
658
- end
659
- end
660
-
661
- context 'ACLs on each container type' do
662
- when_the_chef_server 'has an organization named foo', :osc_compat => false, :single_org => false do
663
- organization 'foo' do
664
- user 'u', {}
665
- client 'x', {}
666
- container 'x', {}
667
- cookbook 'x', '1.0.0', {}
668
- data_bag 'x', { 'y' => {} }
669
- environment 'x', {}
670
- group 'x', {}
671
- node 'x', {}
672
- role 'x', {}
673
- sandbox 'x', {}
674
- user 'x', {}
675
- end
676
-
677
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
678
- it "chef_acl '/organizations/foo/#{type}' changes the acl" do
679
- expect_recipe {
680
- chef_acl "/organizations/foo/#{type}" do
681
- rights :read, users: %w(u)
682
- end
683
- }.to be_updated
684
- expect(get("/organizations/foo/containers/#{type}/_acl")).to partially_match('read' => { 'actors' => %w(u) })
685
- end
686
- end
687
-
688
- %w(clients containers cookbooks data environments groups nodes roles).each do |type|
689
- it "chef_acl '/*/*/#{type}' changes the acl" do
690
- expect_recipe {
691
- chef_acl "/*/*/#{type}" do
692
- rights :read, users: %w(u)
693
- end
694
- }.to be_updated
695
- expect(get("/organizations/foo/containers/#{type}/_acl")).to partially_match('read' => { 'actors' => %w(u) })
696
- end
697
- end
698
-
699
- it "chef_acl '/*/*/*' changes the acls" do
700
- expect_recipe {
701
- chef_acl "/*/*/*" do
702
- rights :read, users: %w(u)
703
- end
704
- }.to be_updated
705
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
706
- expect(get("/organizations/foo/containers/#{type}/_acl")).to partially_match(
707
- 'read' => { 'actors' => %w(u) })
708
- end
709
- end
710
-
711
- it 'chef_acl "/organizations/foo/data_bags" changes the acl' do
712
- expect_recipe {
713
- chef_acl '/organizations/foo/data_bags' do
714
- rights :read, users: %w(u)
715
- end
716
- }.to be_updated
717
- expect(get('/organizations/foo/containers/data/_acl')).to partially_match('read' => { 'actors' => %w(u) })
718
- end
719
-
720
- it 'chef_acl "/*/*/data_bags" changes the acl' do
721
- expect_recipe {
722
- chef_acl '/*/*/data_bags' do
723
- rights :read, users: %w(u)
724
- end
725
- }.to be_updated
726
- expect(get('/organizations/foo/containers/data/_acl')).to partially_match('read' => { 'actors' => %w(u) })
727
- end
728
- end
729
-
730
- when_the_chef_server 'has a user "u" in single org mode', :osc_compat => false do
731
- user 'u', {}
732
- client 'x', {}
733
- container 'x', {}
734
- cookbook 'x', '1.0.0', {}
735
- data_bag 'x', { 'y' => {} }
736
- environment 'x', {}
737
- group 'x', {}
738
- node 'x', {}
739
- role 'x', {}
740
- sandbox 'x', {}
741
- user 'x', {}
742
-
743
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
744
- it "chef_acl #{type}' changes the acl" do
745
- expect_recipe {
746
- chef_acl "#{type}" do
747
- rights :read, users: %w(u)
748
- end
749
- }.to be_updated
750
- expect(get("containers/#{type}/_acl")).to partially_match('read' => { 'actors' => %w(u) })
751
- end
752
- end
753
-
754
- it "chef_acl '*' changes the acls" do
755
- expect_recipe {
756
- chef_acl "*" do
757
- rights :read, users: %w(u)
758
- end
759
- }.to be_updated
760
- %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
761
- expect(get("containers/#{type}/_acl")).to partially_match(
762
- 'read' => { 'actors' => %w(u) })
763
- end
764
- end
765
- end
766
- end
767
-
768
- context 'remove_rights' do
769
- when_the_chef_server 'has a node "x" with "u", "c" and "g" in its acl', :osc_compat => false do
770
- user 'u', {}
771
- user 'u2', {}
772
- client 'c', {}
773
- client 'c2', {}
774
- group 'g', {}
775
- group 'g2', {}
776
- node 'x', {} do
777
- acl 'create' => { 'actors' => [ 'u', 'c' ], 'groups' => [ 'g' ] },
778
- 'read' => { 'actors' => [ 'u', 'c' ], 'groups' => [ 'g' ] },
779
- 'update' => { 'actors' => [ 'u', 'c' ], 'groups' => [ 'g' ] }
780
- end
781
-
782
- it 'chef_acl with remove_rights "u" removes the user\'s rights' do
783
- expect_recipe {
784
- chef_acl "nodes/x" do
785
- remove_rights :read, users: %w(u)
786
- end
787
- }.to be_updated
788
- expect(get("nodes/x/_acl")).to partially_match('read' => { 'actors' => exclude('u') })
789
- end
790
-
791
- it 'chef_acl with remove_rights "c" removes the client\'s rights' do
792
- expect_recipe {
793
- chef_acl "nodes/x" do
794
- remove_rights :read, clients: %w(c)
795
- end
796
- }.to be_updated
797
- expect(get("nodes/x/_acl")).to partially_match('read' => { 'actors' => exclude('c') })
798
- end
799
-
800
- it 'chef_acl with remove_rights "g" removes the group\'s rights' do
801
- expect_recipe {
802
- chef_acl "nodes/x" do
803
- remove_rights :read, groups: %w(g)
804
- end
805
- }.to be_updated
806
- expect(get("nodes/x/_acl")).to partially_match(
807
- 'read' => { 'groups' => exclude('g') }
808
- )
809
- end
810
-
811
- it 'chef_acl with remove_rights [ :create, :read ], "u", "c", "g" removes all three' do
812
- expect_recipe {
813
- chef_acl "nodes/x" do
814
- remove_rights [ :create, :read ], users: %w(u), clients: %w(c), groups: %w(g)
815
- end
816
- }.to be_updated
817
- expect(get("nodes/x/_acl")).to partially_match(
818
- 'create' => { 'actors' => exclude('u').and(exclude('c')), 'groups' => exclude('g') },
819
- 'read' => { 'actors' => exclude('u').and(exclude('c')), 'groups' => exclude('g') }
820
- )
821
- end
822
-
823
- it 'chef_acl with remove_rights "u2", "c2", "g2" has no effect' do
824
- expect {
825
- expect_recipe {
826
- chef_acl "nodes/x" do
827
- remove_rights :read, users: %w(u2), clients: %w(c2), groups: %w(g2)
828
- end
829
- }.to be_up_to_date
830
- }.not_to change { get("nodes/x/_acl") }
831
- end
832
- end
833
- end
834
-
835
- when_the_chef_server 'has a node named data_bags', :osc_compat => false do
836
- user 'blarghle', {}
837
- node 'data_bags', {}
838
-
839
- it 'Converging chef_acl "nodes/data_bags" with user "blarghle" adds the user' do
840
- expect_recipe {
841
- chef_acl 'nodes/data_bags' do
842
- rights :read, users: %w(blarghle)
843
- end
844
- }.to be_updated
845
- expect(get('nodes/data_bags/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
846
- end
847
- end
848
-
849
- when_the_chef_server 'has a node named data_bags in multi-org mode', :osc_compat => false, :single_org => false do
850
- user 'blarghle', {}
851
- organization 'foo' do
852
- node 'data_bags', {}
853
- end
854
-
855
- it 'Converging chef_acl "/organizations/foo/nodes/data_bags" with user "blarghle" adds the user' do
856
- expect_recipe {
857
- chef_acl '/organizations/foo/nodes/data_bags' do
858
- rights :read, users: %w(blarghle)
859
- end
860
- }.to be_updated
861
- expect(get('/organizations/foo/nodes/data_bags/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
862
- end
863
- end
864
-
865
- when_the_chef_server 'has a user named data_bags in multi-org mode', :osc_compat => false, :single_org => false do
866
- user 'data_bags', {}
867
- user 'blarghle', {}
868
-
869
- it 'Converging chef_acl "/users/data_bags" with user "blarghle" adds the user' do
870
- expect_recipe {
871
- chef_acl '/users/data_bags' do
872
- rights :read, users: %w(blarghle)
873
- end
874
- }.to be_updated
875
- expect(get('/users/data_bags/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
876
- end
877
- end
878
- end
879
- end
1
+ require 'support/spec_support'
2
+ require 'cheffish/rspec/chef_run_support'
3
+ require 'chef/resource/chef_acl'
4
+ require 'chef/provider/chef_acl'
5
+ require 'chef_zero/version'
6
+ require 'uri'
7
+
8
+ if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
9
+ describe Chef::Resource::ChefAcl do
10
+ extend Cheffish::RSpec::ChefRunSupport
11
+
12
+ # let(:chef_config) { super().merge(log_level: :debug, stdout: STDOUT, stderr: STDERR, log_location: STDOUT) }
13
+
14
+ context "Rights attributes" do
15
+ when_the_chef_server 'has a node named x', :osc_compat => false do
16
+ node 'x', {}
17
+
18
+ it 'Converging chef_acl "nodes/x" changes nothing' do
19
+ expect_recipe {
20
+ chef_acl 'nodes/x'
21
+ }.to be_up_to_date
22
+ expect(get('nodes/x/_acl')).to partially_match({})
23
+ end
24
+
25
+ it 'Converging chef_acl "nodes/x" with "complete true" and no rights raises an error' do
26
+ expect_converge {
27
+ chef_acl 'nodes/x' do
28
+ complete true
29
+ end
30
+ }.to raise_error(RuntimeError)
31
+ end
32
+
33
+ it 'Removing all :grant rights from a node raises an error' do
34
+ expect_converge {
35
+ chef_acl 'nodes/x' do
36
+ remove_rights :grant, users: %w(pivotal), groups: %w(admins users clients)
37
+ end
38
+ }.to raise_error(RuntimeError)
39
+ end
40
+
41
+ context 'and a user "blarghle"' do
42
+ user 'blarghle', {}
43
+
44
+ it 'Converging chef_acl "nodes/x" with user "blarghle" adds the user' do
45
+ expect_recipe {
46
+ chef_acl 'nodes/x' do
47
+ rights :read, users: %w(blarghle)
48
+ end
49
+ }.to be_updated
50
+ expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
51
+ end
52
+
53
+ it 'Converging chef_acl "nodes/x" with "complete true" removes all ACLs except those specified' do
54
+ expect_recipe {
55
+ chef_acl 'nodes/x' do
56
+ rights :grant, users: %w(blarghle)
57
+ complete true
58
+ end
59
+ }.to be_updated
60
+ expect(get('nodes/x/_acl')).to eq(
61
+ "create"=>{"actors"=>[], "groups"=>[]},
62
+ "read" =>{"actors"=>[], "groups"=>[]},
63
+ "update"=>{"actors"=>[], "groups"=>[]},
64
+ "delete"=>{"actors"=>[], "groups"=>[]},
65
+ "grant" =>{"actors"=>["blarghle"], "groups"=>[]}
66
+ )
67
+ end
68
+ end
69
+
70
+ it 'Converging chef_acl "nodes/x" with "complete true" removes all ACLs except those specified in :all' do
71
+ expect_recipe {
72
+ chef_acl 'nodes/x' do
73
+ rights :all, users: %w(blarghle)
74
+ complete true
75
+ end
76
+ }.to be_updated
77
+ expect(get('nodes/x/_acl')).to eq(
78
+ "create"=>{"actors"=>["blarghle"], "groups"=>[]},
79
+ "read" =>{"actors"=>["blarghle"], "groups"=>[]},
80
+ "update"=>{"actors"=>["blarghle"], "groups"=>[]},
81
+ "delete"=>{"actors"=>["blarghle"], "groups"=>[]},
82
+ "grant" =>{"actors"=>["blarghle"], "groups"=>[]}
83
+ )
84
+ end
85
+
86
+ context 'and a client "blarghle"' do
87
+ user 'blarghle', {}
88
+
89
+ it 'Converging chef_acl "nodes/x" with client "blarghle" adds the client' do
90
+ expect_recipe {
91
+ chef_acl 'nodes/x' do
92
+ rights :read, clients: %w(blarghle)
93
+ end
94
+ }.to be_updated
95
+ expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
96
+ end
97
+ end
98
+
99
+ context 'and a group "blarghle"' do
100
+ group 'blarghle', {}
101
+
102
+ it 'Converging chef_acl "nodes/x" with group "blarghle" adds the group' do
103
+ expect_recipe {
104
+ chef_acl 'nodes/x' do
105
+ rights :read, groups: %w(blarghle)
106
+ end
107
+ }.to be_updated
108
+ expect(get('nodes/x/_acl')).to partially_match('read' => { 'groups' => %w(blarghle) })
109
+ end
110
+ end
111
+
112
+ context 'and multiple users and groups' do
113
+ user 'u1', {}
114
+ user 'u2', {}
115
+ user 'u3', {}
116
+ client 'c1', {}
117
+ client 'c2', {}
118
+ client 'c3', {}
119
+ group 'g1', {}
120
+ group 'g2', {}
121
+ group 'g3', {}
122
+
123
+ it 'Converging chef_acl "nodes/x" with multiple groups, users and clients in an acl makes the appropriate changes' do
124
+ expect_recipe {
125
+ chef_acl 'nodes/x' do
126
+ rights :create, users: [ 'u1', 'u2', 'u3' ], clients: [ 'c1', 'c2', 'c3' ], groups: [ 'g1', 'g2', 'g3' ]
127
+ end
128
+ }.to be_updated
129
+ expect(get('nodes/x/_acl')).to partially_match(
130
+ 'create' => { 'groups' => %w(g1 g2 g3), 'actors' => %w(u1 u2 u3 c1 c2 c3) }
131
+ )
132
+ end
133
+
134
+ it 'Converging chef_acl "nodes/x" with multiple groups, users and clients across multiple "rights" groups makes the appropriate changes' do
135
+ expect_recipe {
136
+ chef_acl 'nodes/x' do
137
+ rights :create, users: %w(u1), clients: %w(c1), groups: %w(g1)
138
+ rights :create, users: %w(u2 u3), clients: %w(c2 c3), groups: %w(g2)
139
+ rights :read, users: %w(u1)
140
+ rights :read, groups: %w(g1)
141
+ end
142
+ }.to be_updated
143
+ expect(get('nodes/x/_acl')).to partially_match(
144
+ 'create' => { 'groups' => %w(g1 g2), 'actors' => %w(u1 u2 u3 c1 c2 c3) },
145
+ 'read' => { 'groups' => %w(g1), 'actors' => %w(u1) }
146
+ )
147
+ end
148
+
149
+ it 'Converging chef_acl "nodes/x" with rights [ :read, :create, :update, :delete, :grant ] modifies all rights' do
150
+ expect_recipe {
151
+ chef_acl 'nodes/x' do
152
+ rights [ :create, :read, :update, :delete, :grant ], users: %w(u1 u2), clients: %w(c1), groups: %w(g1)
153
+ end
154
+ }.to be_updated
155
+ expect(get('nodes/x/_acl')).to partially_match(
156
+ 'create' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
157
+ 'read' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
158
+ 'update' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
159
+ 'delete' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
160
+ 'grant' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
161
+ )
162
+ end
163
+
164
+ it 'Converging chef_acl "nodes/x" with rights :all modifies all rights' do
165
+ expect_recipe {
166
+ chef_acl 'nodes/x' do
167
+ rights :all, users: %w(u1 u2), clients: %w(c1), groups: %w(g1)
168
+ end
169
+ }.to be_updated
170
+ expect(get('nodes/x/_acl')).to partially_match(
171
+ 'create' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
172
+ 'read' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
173
+ 'update' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
174
+ 'delete' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
175
+ 'grant' => { 'groups' => %w(g1), 'actors' => %w(u1 u2 c1) },
176
+ )
177
+ end
178
+ end
179
+
180
+ it 'Converging chef_acl "nodes/y" throws a 404' do
181
+ expect_converge {
182
+ chef_acl 'nodes/y'
183
+ }.to raise_error(Net::HTTPServerException)
184
+ end
185
+ end
186
+
187
+ when_the_chef_server 'has a node named x with user blarghle in its acl', :osc_compat => false do
188
+ user 'blarghle', {}
189
+ node 'x', {} do
190
+ acl 'read' => { 'actors' => %w(blarghle) }
191
+ end
192
+
193
+ it 'Converging chef_acl "nodes/x" with that user changes nothing' do
194
+ expect_recipe {
195
+ chef_acl 'nodes/x' do
196
+ rights :read, users: %w(blarghle)
197
+ end
198
+ }.to be_up_to_date
199
+ expect(get('nodes/x/_acl')).to partially_match({})
200
+ end
201
+ end
202
+
203
+ when_the_chef_server 'has a node named x with users foo and bar in all its acls', :osc_compat => false do
204
+ user 'foo', {}
205
+ user 'bar', {}
206
+ node 'x', {} do
207
+ acl 'create' => { 'actors' => %w(foo bar) },
208
+ 'read' => { 'actors' => %w(foo bar) },
209
+ 'update' => { 'actors' => %w(foo bar) },
210
+ 'delete' => { 'actors' => %w(foo bar) },
211
+ 'grant' => { 'actors' => %w(foo bar) }
212
+ end
213
+
214
+ it 'Converging chef_acl "nodes/x" with remove_rights :all removes foo from everything' do
215
+ expect_recipe {
216
+ chef_acl 'nodes/x' do
217
+ remove_rights :all, users: %w(foo)
218
+ end
219
+ }.to be_updated
220
+ expect(get('nodes/x/_acl')).to partially_match(
221
+ 'create' => { 'actors' => exclude('foo') },
222
+ 'read' => { 'actors' => exclude('foo') },
223
+ 'update' => { 'actors' => exclude('foo') },
224
+ 'delete' => { 'actors' => exclude('foo') },
225
+ 'grant' => { 'actors' => exclude('foo') },
226
+ )
227
+ end
228
+ end
229
+
230
+ ::RSpec::Matchers.define_negated_matcher :exclude, :include
231
+
232
+ context 'recursive' do
233
+ when_the_chef_server 'has a nodes container with user blarghle in its acl', :osc_compat => false do
234
+ user 'blarghle', {}
235
+ acl_for 'containers/nodes', 'read' => { 'actors' => %w(blarghle) }
236
+ node 'x', {} do
237
+ acl 'read' => { 'actors' => [] }
238
+ end
239
+
240
+ it 'Converging chef_acl "nodes" makes no changes' do
241
+ expect {
242
+ expect_recipe {
243
+ chef_acl 'nodes' do
244
+ rights :read, users: %w(blarghle)
245
+ end
246
+ }.to be_up_to_date
247
+ }.to not_change { get('containers/nodes/_acl') }.
248
+ and not_change { get('nodes/x/_acl') }
249
+ end
250
+
251
+ RSpec::Matchers.define_negated_matcher :not_change, :change
252
+
253
+ it 'Converging chef_acl "nodes" with recursive :on_change makes no changes' do
254
+ expect {
255
+ expect_recipe {
256
+ chef_acl 'nodes' do
257
+ rights :read, users: %w(blarghle)
258
+ recursive :on_change
259
+ end
260
+ }.to be_up_to_date
261
+ }.to not_change { get('containers/nodes/_acl') }.
262
+ and not_change { get('nodes/x/_acl') }
263
+ end
264
+
265
+ it 'Converging chef_acl "nodes" with recursive true changes nodes/x\'s acls' do
266
+ expect_recipe {
267
+ chef_acl 'nodes' do
268
+ rights :read, users: %w(blarghle)
269
+ recursive true
270
+ end
271
+ }.to be_updated
272
+ expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
273
+ end
274
+
275
+ it 'Converging chef_acl "" with recursive false does not change nodes/x\'s acls' do
276
+ expect_recipe {
277
+ chef_acl '' do
278
+ rights :read, users: %w(blarghle)
279
+ recursive false
280
+ end
281
+ }.to be_updated
282
+ expect(get('containers/nodes/_acl')).to partially_match({})
283
+ expect(get('nodes/x/_acl')).to partially_match({})
284
+ end
285
+
286
+ it 'Converging chef_acl "" with recursive :on_change does not change nodes/x\'s acls' do
287
+ expect_recipe {
288
+ chef_acl '' do
289
+ rights :read, users: %w(blarghle)
290
+ recursive :on_change
291
+ end
292
+ }.to be_updated
293
+ expect(get('containers/nodes/_acl')).to partially_match({})
294
+ expect(get('nodes/x/_acl')).to partially_match({})
295
+ end
296
+
297
+ it 'Converging chef_acl "" with recursive true changes nodes/x\'s acls' do
298
+ expect_recipe {
299
+ chef_acl '' do
300
+ rights :read, users: %w(blarghle)
301
+ recursive true
302
+ end
303
+ }.to be_updated
304
+ expect(get('/organizations/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
305
+ expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
306
+ end
307
+ end
308
+ end
309
+ end
310
+
311
+ context 'ACLs on each type of thing' do
312
+ when_the_chef_server 'has an organization named foo', :osc_compat => false, :single_org => false do
313
+ organization 'foo' do
314
+ user 'u', {}
315
+ client 'x', {}
316
+ container 'x', {}
317
+ cookbook 'x', '1.0.0', {}
318
+ data_bag 'x', { 'y' => {} }
319
+ environment 'x', {}
320
+ group 'x', {}
321
+ node 'x', {}
322
+ role 'x', {}
323
+ sandbox 'x', {}
324
+ user 'x', {}
325
+ end
326
+
327
+ organization 'bar' do
328
+ user 'u', {}
329
+ node 'x', {}
330
+ end
331
+
332
+ context 'and the chef server URL points at /organizations/foo' do
333
+ before :each do
334
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
335
+ end
336
+
337
+ context 'relative paths' do
338
+ it "chef_acl 'nodes/x' changes the acls" do
339
+ expect_recipe {
340
+ chef_acl "nodes/x" do
341
+ rights :read, users: %w(u)
342
+ end
343
+ }.to be_updated
344
+ expect(get("nodes/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
345
+ end
346
+
347
+ it "chef_acl '*/*' changes the acls" do
348
+ expect_recipe {
349
+ chef_acl "*/*" do
350
+ rights :read, users: %w(u)
351
+ end
352
+ }.to be_updated
353
+ %w(clients containers cookbooks data environments groups nodes roles).each do |type|
354
+ expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match(
355
+ 'read' => { 'actors' => %w(u) })
356
+ end
357
+ end
358
+ end
359
+
360
+ context 'absolute paths' do
361
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
362
+ it "chef_acl '/organizations/foo/#{type}/x' changes the acl" do
363
+ expect_recipe {
364
+ chef_acl "/organizations/foo/#{type}/x" do
365
+ rights :read, users: %w(u)
366
+ end
367
+ }.to be_updated
368
+ expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
369
+ end
370
+ end
371
+
372
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
373
+ it "chef_acl '/organizations/foo/#{type}/x' changes the acl" do
374
+ expect_recipe {
375
+ chef_acl "/organizations/foo/#{type}/x" do
376
+ rights :read, users: %w(u)
377
+ end
378
+ }.to be_updated
379
+ expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
380
+ end
381
+ end
382
+
383
+ %w(clients containers cookbooks data environments groups nodes roles).each do |type|
384
+ it "chef_acl '/*/*/#{type}/*' changes the acl" do
385
+ expect_recipe {
386
+ chef_acl "/*/*/#{type}/*" do
387
+ rights :read, users: %w(u)
388
+ end
389
+ }.to be_updated
390
+ expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
391
+ end
392
+ end
393
+
394
+ it "chef_acl '/*/*/*/x' changes the acls" do
395
+ expect_recipe {
396
+ chef_acl "/*/*/*/x" do
397
+ rights :read, users: %w(u)
398
+ end
399
+ }.to be_updated
400
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
401
+ expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match(
402
+ 'read' => { 'actors' => %w(u) })
403
+ end
404
+ end
405
+
406
+ it "chef_acl '/*/*/*/*' changes the acls" do
407
+ expect_recipe {
408
+ chef_acl "/*/*/*/*" do
409
+ rights :read, users: %w(u)
410
+ end
411
+ }.to be_updated
412
+ %w(clients containers cookbooks data environments groups nodes roles).each do |type|
413
+ expect(get("/organizations/foo/#{type}/x/_acl")).to partially_match(
414
+ 'read' => { 'actors' => %w(u) })
415
+ end
416
+ end
417
+
418
+ it 'chef_acl "/organizations/foo/data_bags/x" changes the acl' do
419
+ expect_recipe {
420
+ chef_acl '/organizations/foo/data_bags/x' do
421
+ rights :read, users: %w(u)
422
+ end
423
+ }.to be_updated
424
+ expect(get('/organizations/foo/data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
425
+ end
426
+
427
+ it 'chef_acl "/*/*/data_bags/*" changes the acl' do
428
+ expect_recipe {
429
+ chef_acl '/*/*/data_bags/*' do
430
+ rights :read, users: %w(u)
431
+ end
432
+ }.to be_updated
433
+ expect(get('/organizations/foo/data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
434
+ end
435
+
436
+ it "chef_acl '/organizations/foo/cookbooks/x/1.0.0' raises an error" do
437
+ expect_converge {
438
+ chef_acl "/organizations/foo/cookbooks/x/1.0.0" do
439
+ rights :read, users: %w(u)
440
+ end
441
+ }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/cookbooks\/x/)
442
+ end
443
+
444
+ it "chef_acl '/organizations/foo/cookbooks/*/*' raises an error" do
445
+ pending
446
+ expect_converge {
447
+ chef_acl "/organizations/foo/cookbooks/*/*" do
448
+ rights :read, users: %w(u)
449
+ end
450
+ }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/cookbooks\/*/)
451
+ end
452
+
453
+ it 'chef_acl "/organizations/foo/data/x/y" raises an error' do
454
+ expect_converge {
455
+ chef_acl '/organizations/foo/data/x/y' do
456
+ rights :read, users: %w(u)
457
+ end
458
+ }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/data\/x/)
459
+ end
460
+
461
+ it 'chef_acl "/organizations/foo/data/*/*" raises an error' do
462
+ pending
463
+ expect_converge {
464
+ chef_acl '/organizations/foo/data/*/*' do
465
+ rights :read, users: %w(u)
466
+ end
467
+ }.to raise_error(/ACLs cannot be set on children of \/organizations\/foo\/data\/*/)
468
+ end
469
+
470
+ it 'chef_acl "/organizations/foo" changes the acl' do
471
+ expect_recipe {
472
+ chef_acl '/organizations/foo' do
473
+ rights :read, users: %w(u)
474
+ end
475
+ }.to be_updated
476
+ expect(get('/organizations/foo/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
477
+ expect(get('/organizations/foo/nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
478
+ end
479
+
480
+ it 'chef_acl "/organizations/*" changes the acl' do
481
+ expect_recipe {
482
+ chef_acl '/organizations/*' do
483
+ rights :read, users: %w(u)
484
+ end
485
+ }.to be_updated
486
+ expect(get('/organizations/foo/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
487
+ expect(get('/organizations/foo/nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
488
+ end
489
+
490
+ it 'chef_acl "/users/x" changes the acl' do
491
+ expect_recipe {
492
+ chef_acl '/users/x' do
493
+ rights :read, users: %w(u)
494
+ end
495
+ }.to be_updated
496
+ expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
497
+ end
498
+
499
+ it 'chef_acl "/users/*" changes the acl' do
500
+ expect_recipe {
501
+ chef_acl '/users/*' do
502
+ rights :read, users: %w(u)
503
+ end
504
+ }.to be_updated
505
+ expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
506
+ end
507
+
508
+ it 'chef_acl "/*/x" changes the acl' do
509
+ expect_recipe {
510
+ chef_acl '/*/x' do
511
+ rights :read, users: %w(u)
512
+ end
513
+ }.to be_updated
514
+ expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
515
+ end
516
+
517
+ it 'chef_acl "/*/*" changes the acl' do
518
+ expect_recipe {
519
+ chef_acl '/*/*' do
520
+ rights :read, users: %w(u)
521
+ end
522
+ }.to be_updated
523
+ expect(get('/organizations/foo/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
524
+ expect(get('/users/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
525
+ end
526
+ end
527
+ end
528
+
529
+ context 'and the chef server URL points at /organizations/bar' do
530
+ before :each do
531
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url.to_s, '/organizations/bar').to_s
532
+ end
533
+
534
+ it "chef_acl '/organizations/foo/nodes/*' changes the acl" do
535
+ expect_recipe {
536
+ chef_acl "/organizations/foo/nodes/*" do
537
+ rights :read, users: %w(u)
538
+ end
539
+ }.to be_updated
540
+ expect(get("/organizations/foo/nodes/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
541
+ end
542
+ end
543
+
544
+ context 'and the chef server URL points at /' do
545
+ before :each do
546
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url.to_s, '/').to_s
547
+ end
548
+
549
+ it "chef_acl '/organizations/foo/nodes/*' changes the acl" do
550
+ expect_recipe {
551
+ chef_acl "/organizations/foo/nodes/*" do
552
+ rights :read, users: %w(u)
553
+ end
554
+ }.to be_updated
555
+ expect(get("/organizations/foo/nodes/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
556
+ end
557
+ end
558
+ end
559
+
560
+ when_the_chef_server 'has a user "u" in single org mode', :osc_compat => false do
561
+ user 'u', {}
562
+ client 'x', {}
563
+ container 'x', {}
564
+ cookbook 'x', '1.0.0', {}
565
+ data_bag 'x', { 'y' => {} }
566
+ environment 'x', {}
567
+ group 'x', {}
568
+ node 'x', {}
569
+ role 'x', {}
570
+ sandbox 'x', {}
571
+ user 'x', {}
572
+
573
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
574
+ it "chef_acl #{type}/x' changes the acl" do
575
+ expect_recipe {
576
+ chef_acl "#{type}/x" do
577
+ rights :read, users: %w(u)
578
+ end
579
+ }.to be_updated
580
+ expect(get("#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
581
+ end
582
+ end
583
+
584
+ %w(clients containers cookbooks data environments groups nodes roles).each do |type|
585
+ it "chef_acl '#{type}/*' changes the acl" do
586
+ expect_recipe {
587
+ chef_acl "#{type}/*" do
588
+ rights :read, users: %w(u)
589
+ end
590
+ }.to be_updated
591
+ expect(get("#{type}/x/_acl")).to partially_match('read' => { 'actors' => %w(u) })
592
+ end
593
+ end
594
+
595
+ it "chef_acl '*/x' changes the acls" do
596
+ expect_recipe {
597
+ chef_acl "*/x" do
598
+ rights :read, users: %w(u)
599
+ end
600
+ }.to be_updated
601
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
602
+ expect(get("#{type}/x/_acl")).to partially_match(
603
+ 'read' => { 'actors' => %w(u) })
604
+ end
605
+ end
606
+
607
+ it "chef_acl '*/*' changes the acls" do
608
+ expect_recipe {
609
+ chef_acl "*/*" do
610
+ rights :read, users: %w(u)
611
+ end
612
+ }.to be_updated
613
+ %w(clients containers cookbooks data environments groups nodes roles).each do |type|
614
+ expect(get("#{type}/x/_acl")).to partially_match(
615
+ 'read' => { 'actors' => %w(u) })
616
+ end
617
+ end
618
+
619
+ it "chef_acl 'groups/*' changes the acl" do
620
+ expect_recipe {
621
+ chef_acl "groups/*" do
622
+ rights :read, users: %w(u)
623
+ end
624
+ }.to be_updated
625
+ %w(admins billing-admins clients users x).each do |n|
626
+ expect(get("groups/#{n}/_acl")).to partially_match(
627
+ 'read' => { 'actors' => %w(u) })
628
+ end
629
+ end
630
+
631
+ it 'chef_acl "data_bags/x" changes the acl' do
632
+ expect_recipe {
633
+ chef_acl 'data_bags/x' do
634
+ rights :read, users: %w(u)
635
+ end
636
+ }.to be_updated
637
+ expect(get('data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
638
+ end
639
+
640
+ it 'chef_acl "data_bags/*" changes the acl' do
641
+ expect_recipe {
642
+ chef_acl 'data_bags/*' do
643
+ rights :read, users: %w(u)
644
+ end
645
+ }.to be_updated
646
+ expect(get('data/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
647
+ end
648
+
649
+ it 'chef_acl "" changes the organization acl' do
650
+ expect_recipe {
651
+ chef_acl '' do
652
+ rights :read, users: %w(u)
653
+ end
654
+ }.to be_updated
655
+ expect(get('/organizations/_acl')).to partially_match('read' => { 'actors' => %w(u) })
656
+ expect(get('nodes/x/_acl')).to partially_match('read' => { 'actors' => %w(u) })
657
+ end
658
+ end
659
+ end
660
+
661
+ context 'ACLs on each container type' do
662
+ when_the_chef_server 'has an organization named foo', :osc_compat => false, :single_org => false do
663
+ organization 'foo' do
664
+ user 'u', {}
665
+ client 'x', {}
666
+ container 'x', {}
667
+ cookbook 'x', '1.0.0', {}
668
+ data_bag 'x', { 'y' => {} }
669
+ environment 'x', {}
670
+ group 'x', {}
671
+ node 'x', {}
672
+ role 'x', {}
673
+ sandbox 'x', {}
674
+ user 'x', {}
675
+ end
676
+
677
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
678
+ it "chef_acl '/organizations/foo/#{type}' changes the acl" do
679
+ expect_recipe {
680
+ chef_acl "/organizations/foo/#{type}" do
681
+ rights :read, users: %w(u)
682
+ end
683
+ }.to be_updated
684
+ expect(get("/organizations/foo/containers/#{type}/_acl")).to partially_match('read' => { 'actors' => %w(u) })
685
+ end
686
+ end
687
+
688
+ %w(clients containers cookbooks data environments groups nodes roles).each do |type|
689
+ it "chef_acl '/*/*/#{type}' changes the acl" do
690
+ expect_recipe {
691
+ chef_acl "/*/*/#{type}" do
692
+ rights :read, users: %w(u)
693
+ end
694
+ }.to be_updated
695
+ expect(get("/organizations/foo/containers/#{type}/_acl")).to partially_match('read' => { 'actors' => %w(u) })
696
+ end
697
+ end
698
+
699
+ it "chef_acl '/*/*/*' changes the acls" do
700
+ expect_recipe {
701
+ chef_acl "/*/*/*" do
702
+ rights :read, users: %w(u)
703
+ end
704
+ }.to be_updated
705
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
706
+ expect(get("/organizations/foo/containers/#{type}/_acl")).to partially_match(
707
+ 'read' => { 'actors' => %w(u) })
708
+ end
709
+ end
710
+
711
+ it 'chef_acl "/organizations/foo/data_bags" changes the acl' do
712
+ expect_recipe {
713
+ chef_acl '/organizations/foo/data_bags' do
714
+ rights :read, users: %w(u)
715
+ end
716
+ }.to be_updated
717
+ expect(get('/organizations/foo/containers/data/_acl')).to partially_match('read' => { 'actors' => %w(u) })
718
+ end
719
+
720
+ it 'chef_acl "/*/*/data_bags" changes the acl' do
721
+ expect_recipe {
722
+ chef_acl '/*/*/data_bags' do
723
+ rights :read, users: %w(u)
724
+ end
725
+ }.to be_updated
726
+ expect(get('/organizations/foo/containers/data/_acl')).to partially_match('read' => { 'actors' => %w(u) })
727
+ end
728
+ end
729
+
730
+ when_the_chef_server 'has a user "u" in single org mode', :osc_compat => false do
731
+ user 'u', {}
732
+ client 'x', {}
733
+ container 'x', {}
734
+ cookbook 'x', '1.0.0', {}
735
+ data_bag 'x', { 'y' => {} }
736
+ environment 'x', {}
737
+ group 'x', {}
738
+ node 'x', {}
739
+ role 'x', {}
740
+ sandbox 'x', {}
741
+ user 'x', {}
742
+
743
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
744
+ it "chef_acl #{type}' changes the acl" do
745
+ expect_recipe {
746
+ chef_acl "#{type}" do
747
+ rights :read, users: %w(u)
748
+ end
749
+ }.to be_updated
750
+ expect(get("containers/#{type}/_acl")).to partially_match('read' => { 'actors' => %w(u) })
751
+ end
752
+ end
753
+
754
+ it "chef_acl '*' changes the acls" do
755
+ expect_recipe {
756
+ chef_acl "*" do
757
+ rights :read, users: %w(u)
758
+ end
759
+ }.to be_updated
760
+ %w(clients containers cookbooks data environments groups nodes roles sandboxes).each do |type|
761
+ expect(get("containers/#{type}/_acl")).to partially_match(
762
+ 'read' => { 'actors' => %w(u) })
763
+ end
764
+ end
765
+ end
766
+ end
767
+
768
+ context 'remove_rights' do
769
+ when_the_chef_server 'has a node "x" with "u", "c" and "g" in its acl', :osc_compat => false do
770
+ user 'u', {}
771
+ user 'u2', {}
772
+ client 'c', {}
773
+ client 'c2', {}
774
+ group 'g', {}
775
+ group 'g2', {}
776
+ node 'x', {} do
777
+ acl 'create' => { 'actors' => [ 'u', 'c' ], 'groups' => [ 'g' ] },
778
+ 'read' => { 'actors' => [ 'u', 'c' ], 'groups' => [ 'g' ] },
779
+ 'update' => { 'actors' => [ 'u', 'c' ], 'groups' => [ 'g' ] }
780
+ end
781
+
782
+ it 'chef_acl with remove_rights "u" removes the user\'s rights' do
783
+ expect_recipe {
784
+ chef_acl "nodes/x" do
785
+ remove_rights :read, users: %w(u)
786
+ end
787
+ }.to be_updated
788
+ expect(get("nodes/x/_acl")).to partially_match('read' => { 'actors' => exclude('u') })
789
+ end
790
+
791
+ it 'chef_acl with remove_rights "c" removes the client\'s rights' do
792
+ expect_recipe {
793
+ chef_acl "nodes/x" do
794
+ remove_rights :read, clients: %w(c)
795
+ end
796
+ }.to be_updated
797
+ expect(get("nodes/x/_acl")).to partially_match('read' => { 'actors' => exclude('c') })
798
+ end
799
+
800
+ it 'chef_acl with remove_rights "g" removes the group\'s rights' do
801
+ expect_recipe {
802
+ chef_acl "nodes/x" do
803
+ remove_rights :read, groups: %w(g)
804
+ end
805
+ }.to be_updated
806
+ expect(get("nodes/x/_acl")).to partially_match(
807
+ 'read' => { 'groups' => exclude('g') }
808
+ )
809
+ end
810
+
811
+ it 'chef_acl with remove_rights [ :create, :read ], "u", "c", "g" removes all three' do
812
+ expect_recipe {
813
+ chef_acl "nodes/x" do
814
+ remove_rights [ :create, :read ], users: %w(u), clients: %w(c), groups: %w(g)
815
+ end
816
+ }.to be_updated
817
+ expect(get("nodes/x/_acl")).to partially_match(
818
+ 'create' => { 'actors' => exclude('u').and(exclude('c')), 'groups' => exclude('g') },
819
+ 'read' => { 'actors' => exclude('u').and(exclude('c')), 'groups' => exclude('g') }
820
+ )
821
+ end
822
+
823
+ it 'chef_acl with remove_rights "u2", "c2", "g2" has no effect' do
824
+ expect {
825
+ expect_recipe {
826
+ chef_acl "nodes/x" do
827
+ remove_rights :read, users: %w(u2), clients: %w(c2), groups: %w(g2)
828
+ end
829
+ }.to be_up_to_date
830
+ }.not_to change { get("nodes/x/_acl") }
831
+ end
832
+ end
833
+ end
834
+
835
+ when_the_chef_server 'has a node named data_bags', :osc_compat => false do
836
+ user 'blarghle', {}
837
+ node 'data_bags', {}
838
+
839
+ it 'Converging chef_acl "nodes/data_bags" with user "blarghle" adds the user' do
840
+ expect_recipe {
841
+ chef_acl 'nodes/data_bags' do
842
+ rights :read, users: %w(blarghle)
843
+ end
844
+ }.to be_updated
845
+ expect(get('nodes/data_bags/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
846
+ end
847
+ end
848
+
849
+ when_the_chef_server 'has a node named data_bags in multi-org mode', :osc_compat => false, :single_org => false do
850
+ user 'blarghle', {}
851
+ organization 'foo' do
852
+ node 'data_bags', {}
853
+ end
854
+
855
+ it 'Converging chef_acl "/organizations/foo/nodes/data_bags" with user "blarghle" adds the user' do
856
+ expect_recipe {
857
+ chef_acl '/organizations/foo/nodes/data_bags' do
858
+ rights :read, users: %w(blarghle)
859
+ end
860
+ }.to be_updated
861
+ expect(get('/organizations/foo/nodes/data_bags/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
862
+ end
863
+ end
864
+
865
+ when_the_chef_server 'has a user named data_bags in multi-org mode', :osc_compat => false, :single_org => false do
866
+ user 'data_bags', {}
867
+ user 'blarghle', {}
868
+
869
+ it 'Converging chef_acl "/users/data_bags" with user "blarghle" adds the user' do
870
+ expect_recipe {
871
+ chef_acl '/users/data_bags' do
872
+ rights :read, users: %w(blarghle)
873
+ end
874
+ }.to be_updated
875
+ expect(get('/users/data_bags/_acl')).to partially_match('read' => { 'actors' => %w(blarghle) })
876
+ end
877
+ end
878
+ end
879
+ end