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.
- checksums.yaml +4 -4
- data/LICENSE +201 -201
- data/README.md +120 -117
- data/Rakefile +23 -23
- data/lib/chef/provider/chef_acl.rb +439 -434
- data/lib/chef/provider/chef_client.rb +53 -48
- data/lib/chef/provider/chef_container.rb +55 -50
- data/lib/chef/provider/chef_data_bag.rb +55 -50
- data/lib/chef/provider/chef_data_bag_item.rb +278 -273
- data/lib/chef/provider/chef_environment.rb +83 -78
- data/lib/chef/provider/chef_group.rb +83 -78
- data/lib/chef/provider/chef_mirror.rb +169 -164
- data/lib/chef/provider/chef_node.rb +87 -82
- data/lib/chef/provider/chef_organization.rb +155 -150
- data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -41
- data/lib/chef/provider/chef_role.rb +84 -79
- data/lib/chef/provider/chef_user.rb +59 -54
- data/lib/chef/provider/private_key.rb +225 -220
- data/lib/chef/provider/public_key.rb +88 -82
- data/lib/chef/resource/chef_acl.rb +69 -65
- data/lib/chef/resource/chef_client.rb +48 -44
- data/lib/chef/resource/chef_container.rb +22 -18
- data/lib/chef/resource/chef_data_bag.rb +22 -18
- data/lib/chef/resource/chef_data_bag_item.rb +121 -114
- data/lib/chef/resource/chef_environment.rb +77 -71
- data/lib/chef/resource/chef_group.rb +53 -49
- data/lib/chef/resource/chef_mirror.rb +52 -48
- data/lib/chef/resource/chef_node.rb +22 -18
- data/lib/chef/resource/chef_organization.rb +69 -64
- data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -31
- data/lib/chef/resource/chef_role.rb +110 -104
- data/lib/chef/resource/chef_user.rb +56 -52
- data/lib/chef/resource/private_key.rb +48 -44
- data/lib/chef/resource/public_key.rb +25 -21
- data/lib/cheffish.rb +235 -233
- data/lib/cheffish/actor_provider_base.rb +131 -131
- data/lib/cheffish/basic_chef_client.rb +184 -184
- data/lib/cheffish/chef_provider_base.rb +246 -246
- data/lib/cheffish/chef_run.rb +162 -155
- data/lib/cheffish/chef_run_data.rb +19 -19
- data/lib/cheffish/chef_run_listener.rb +30 -30
- data/lib/cheffish/key_formatter.rb +113 -113
- data/lib/cheffish/merged_config.rb +94 -94
- data/lib/cheffish/recipe_dsl.rb +157 -157
- data/lib/cheffish/rspec.rb +8 -8
- data/lib/cheffish/rspec/chef_run_support.rb +83 -83
- data/lib/cheffish/rspec/matchers.rb +4 -4
- data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
- data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
- data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
- data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
- data/lib/cheffish/rspec/recipe_run_wrapper.rb +59 -47
- data/lib/cheffish/rspec/repository_support.rb +108 -108
- data/lib/cheffish/server_api.rb +52 -52
- data/lib/cheffish/version.rb +3 -3
- data/lib/cheffish/with_pattern.rb +21 -21
- data/spec/functional/fingerprint_spec.rb +64 -64
- data/spec/functional/merged_config_spec.rb +19 -19
- data/spec/functional/server_api_spec.rb +13 -13
- data/spec/integration/chef_acl_spec.rb +879 -879
- data/spec/integration/chef_client_spec.rb +105 -105
- data/spec/integration/chef_container_spec.rb +33 -33
- data/spec/integration/chef_group_spec.rb +309 -309
- data/spec/integration/chef_mirror_spec.rb +491 -491
- data/spec/integration/chef_node_spec.rb +786 -786
- data/spec/integration/chef_organization_spec.rb +226 -226
- data/spec/integration/chef_role_spec.rb +78 -0
- data/spec/integration/chef_user_spec.rb +85 -85
- data/spec/integration/private_key_spec.rb +399 -399
- data/spec/integration/recipe_dsl_spec.rb +28 -28
- data/spec/integration/rspec/converge_spec.rb +183 -183
- data/spec/support/key_support.rb +29 -29
- data/spec/support/spec_support.rb +15 -15
- data/spec/unit/get_private_key_spec.rb +131 -131
- data/spec/unit/recipe_run_wrapper_spec.rb +37 -0
- 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
|