cheffish 1.3.1 → 1.4.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 (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