cheffish 0.7.1 → 0.8

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/provider/chef_acl.rb +434 -0
  3. data/lib/chef/provider/chef_client.rb +5 -1
  4. data/lib/chef/provider/chef_container.rb +50 -0
  5. data/lib/chef/provider/chef_group.rb +78 -0
  6. data/lib/chef/provider/chef_mirror.rb +138 -0
  7. data/lib/chef/provider/chef_organization.rb +150 -0
  8. data/lib/chef/provider/chef_user.rb +6 -1
  9. data/lib/chef/provider/public_key.rb +0 -1
  10. data/lib/chef/resource/chef_acl.rb +38 -44
  11. data/lib/chef/resource/chef_container.rb +18 -0
  12. data/lib/chef/resource/chef_group.rb +49 -0
  13. data/lib/chef/resource/chef_mirror.rb +47 -0
  14. data/lib/chef/resource/chef_organization.rb +64 -0
  15. data/lib/chef/resource/private_key.rb +6 -1
  16. data/lib/chef/resource/public_key.rb +5 -0
  17. data/lib/cheffish/actor_provider_base.rb +14 -9
  18. data/lib/cheffish/basic_chef_client.rb +18 -2
  19. data/lib/cheffish/chef_provider_base.rb +7 -0
  20. data/lib/cheffish/merged_config.rb +10 -2
  21. data/lib/cheffish/recipe_dsl.rb +34 -8
  22. data/lib/cheffish/server_api.rb +12 -2
  23. data/lib/cheffish/version.rb +1 -1
  24. data/lib/cheffish.rb +2 -2
  25. data/spec/functional/merged_config_spec.rb +20 -0
  26. data/spec/integration/chef_acl_spec.rb +914 -0
  27. data/spec/integration/chef_client_spec.rb +78 -44
  28. data/spec/integration/chef_container_spec.rb +34 -0
  29. data/spec/integration/chef_group_spec.rb +324 -0
  30. data/spec/integration/chef_mirror_spec.rb +244 -0
  31. data/spec/integration/chef_node_spec.rb +115 -93
  32. data/spec/integration/chef_organization_spec.rb +244 -0
  33. data/spec/integration/chef_user_spec.rb +51 -9
  34. data/spec/support/repository_support.rb +103 -0
  35. data/spec/support/spec_support.rb +55 -2
  36. metadata +23 -9
  37. data/lib/chef/resource/in_parallel.rb +0 -6
@@ -8,67 +8,101 @@ repo_path = Dir.mktmpdir('chef_repo')
8
8
  describe Chef::Resource::ChefClient do
9
9
  extend SpecSupport
10
10
 
11
- when_the_chef_server 'is empty' do
12
- context 'and we have a private key with a path' do
13
- with_recipe do
14
- private_key "#{repo_path}/blah.pem"
15
- end
11
+ when_the_chef_server 'is in multi-org mode', :osc_compat => false, :single_org => false do
12
+ organization 'foo'
13
+
14
+ before :each do
15
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
16
+ end
17
+
18
+ context 'and is empty' do
19
+ context 'and we have a private key with a path' do
20
+ with_recipe do
21
+ private_key "#{repo_path}/blah.pem"
22
+ end
23
+
24
+ context 'and we run a recipe that creates client "blah"' do
25
+ with_converge do
26
+ chef_client 'blah' do
27
+ source_key_path "#{repo_path}/blah.pem"
28
+ end
29
+ end
16
30
 
17
- context 'and we run a recipe that creates client "blah"' do
18
- with_converge do
19
- chef_client 'blah' do
20
- source_key_path "#{repo_path}/blah.pem"
31
+ it 'the client gets created' do
32
+ expect(chef_run).to have_updated 'chef_client[blah]', :create
33
+ client = get('clients/blah')
34
+ expect(client['name']).to eq('blah')
35
+ key, format = Cheffish::KeyFormatter.decode(client['public_key'])
36
+ expect(key).to be_public_key_for("#{repo_path}/blah.pem")
21
37
  end
22
38
  end
23
39
 
24
- it 'the client gets created' do
25
- expect(chef_run).to have_updated 'chef_client[blah]', :create
26
- client = get('/clients/blah')
27
- expect(client['name']).to eq('blah')
28
- key, format = Cheffish::KeyFormatter.decode(client['public_key'])
29
- expect(key).to be_public_key_for("#{repo_path}/blah.pem")
40
+ context 'and we run a recipe that creates client "blah" with output_key_path' do
41
+ with_converge do
42
+ chef_client 'blah' do
43
+ source_key_path "#{repo_path}/blah.pem"
44
+ output_key_path "#{repo_path}/blah.pub"
45
+ end
46
+ end
47
+
48
+ it 'the output public key gets created' do
49
+ expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
50
+ expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah.pem")
51
+ end
30
52
  end
31
53
  end
32
54
 
33
- context 'and we run a recipe that creates client "blah" with output_key_path' do
34
- with_converge do
35
- chef_client 'blah' do
36
- source_key_path "#{repo_path}/blah.pem"
37
- output_key_path "#{repo_path}/blah.pub"
38
- end
55
+ context "and a private_key 'blah' resource" do
56
+ before :each do
57
+ Chef::Config.private_key_paths = [ repo_path ]
39
58
  end
40
59
 
41
- it 'the output public key gets created' do
42
- expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
43
- expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah.pem")
60
+ with_recipe do
61
+ private_key 'blah'
44
62
  end
45
- end
46
- end
47
63
 
48
- context "and a private_key 'blah' resource" do
49
- before :each do
50
- Chef::Config.private_key_paths = [ repo_path ]
51
- end
64
+ context "and a chef_client 'foobar' resource with source_key_path 'blah'" do
65
+ with_converge do
66
+ chef_client 'foobar' do
67
+ source_key_path 'blah'
68
+ end
69
+ end
52
70
 
53
- with_recipe do
54
- private_key 'blah'
55
- end
71
+ it 'the client is accessible via the given private key' do
72
+ expect(chef_run).to have_updated 'chef_client[foobar]', :create
73
+ client = get('clients/foobar')
74
+ key, format = Cheffish::KeyFormatter.decode(client['public_key'])
75
+ expect(key).to be_public_key_for("#{repo_path}/blah.pem")
56
76
 
57
- context "and a chef_client 'foobar' resource with source_key_path 'blah'" do
58
- with_converge do
59
- chef_client 'foobar' do
60
- source_key_path 'blah'
77
+ private_key = Cheffish::KeyFormatter.decode(Cheffish.get_private_key('blah'))
78
+ expect(key).to be_public_key_for(private_key)
61
79
  end
62
80
  end
81
+ end
82
+ end
83
+ end
63
84
 
64
- it 'the client is accessible via the given private key' do
65
- expect(chef_run).to have_updated 'chef_client[foobar]', :create
66
- client = get('/clients/foobar')
67
- key, format = Cheffish::KeyFormatter.decode(client['public_key'])
68
- expect(key).to be_public_key_for("#{repo_path}/blah.pem")
85
+ when_the_chef_server 'is in OSC mode' do
86
+ context 'and is empty' do
87
+ context 'and we have a private key with a path' do
88
+ with_recipe do
89
+ private_key "#{repo_path}/blah.pem"
90
+ end
69
91
 
70
- private_key = Cheffish::KeyFormatter.decode(Cheffish.get_private_key('blah'))
71
- expect(key).to be_public_key_for(private_key)
92
+ context 'and we run a recipe that creates client "blah"' do
93
+ with_converge do
94
+ chef_client 'blah' do
95
+ source_key_path "#{repo_path}/blah.pem"
96
+ end
97
+ end
98
+
99
+ it 'the client gets created' do
100
+ expect(chef_run).to have_updated 'chef_client[blah]', :create
101
+ client = get('clients/blah')
102
+ expect(client['name']).to eq('blah')
103
+ key, format = Cheffish::KeyFormatter.decode(client['public_key'])
104
+ expect(key).to be_public_key_for("#{repo_path}/blah.pem")
105
+ end
72
106
  end
73
107
  end
74
108
  end
@@ -0,0 +1,34 @@
1
+ require 'support/spec_support'
2
+ require 'chef/resource/chef_container'
3
+ require 'chef/provider/chef_container'
4
+
5
+ describe Chef::Resource::ChefContainer do
6
+ extend SpecSupport
7
+
8
+ when_the_chef_server 'is in multi-org mode', :osc_compat => false, :single_org => false do
9
+ organization 'foo'
10
+
11
+ before :each do
12
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
13
+ end
14
+
15
+ it 'Converging chef_container "x" creates the container' do
16
+ run_recipe do
17
+ chef_container 'x'
18
+ end
19
+ expect(chef_run).to have_updated('chef_container[x]', :create)
20
+ expect { get('containers/x') }.not_to raise_error
21
+ end
22
+
23
+ context 'and already has a container named x' do
24
+ container 'x', {}
25
+
26
+ it 'Converging chef_container "x" changes nothing' do
27
+ run_recipe do
28
+ chef_container 'x'
29
+ end
30
+ expect(chef_run).not_to have_updated('chef_container[x]', :create)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,324 @@
1
+ require 'support/spec_support'
2
+ require 'chef/resource/chef_group'
3
+ require 'chef/provider/chef_group'
4
+
5
+ describe Chef::Resource::ChefGroup do
6
+ extend SpecSupport
7
+
8
+ when_the_chef_server 'is in multi-org mode', :osc_compat => false, :single_org => false do
9
+ organization 'foo'
10
+
11
+ before :each do
12
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
13
+ end
14
+
15
+ context 'and is empty' do
16
+ group 'g', {}
17
+ user 'u', {}
18
+ client 'c', {}
19
+
20
+ it 'Converging chef_group "x" creates the group with no members' do
21
+ run_recipe do
22
+ chef_group 'x'
23
+ end
24
+ expect(chef_run).to have_updated('chef_group[x]', :create)
25
+ expect(get('groups/x')).to eq({
26
+ 'name' => 'x',
27
+ 'groupname' => 'x',
28
+ 'orgname' => 'foo',
29
+ 'actors' => [],
30
+ 'groups' => [],
31
+ 'users' => [],
32
+ 'clients' => []
33
+ })
34
+ end
35
+
36
+ it 'chef_group "x" action :delete does nothing' do
37
+ run_recipe do
38
+ chef_group 'x' do
39
+ action :delete
40
+ end
41
+ end
42
+ expect(chef_run).not_to have_updated('chef_group[x]', :delete)
43
+ expect(chef_run).not_to have_updated('chef_group[x]', :create)
44
+ expect { get('groups/x') }.to raise_error(Net::HTTPServerException)
45
+ end
46
+
47
+ it 'Converging chef_group "x" creates the group with the given members' do
48
+ run_recipe do
49
+ chef_group 'x' do
50
+ groups 'g'
51
+ users 'u'
52
+ clients 'c'
53
+ end
54
+ end
55
+ expect(chef_run).to have_updated('chef_group[x]', :create)
56
+ expect(get('groups/x')).to eq({
57
+ 'name' => 'x',
58
+ 'groupname' => 'x',
59
+ 'orgname' => 'foo',
60
+ 'actors' => %w(c u),
61
+ 'groups' => %w(g),
62
+ 'users' => %w(u),
63
+ 'clients' => %w(c)
64
+ })
65
+ end
66
+ end
67
+
68
+ context 'and has a group named x' do
69
+ group 'g', {}
70
+ group 'g2', {}
71
+ group 'g3', {}
72
+ group 'g4', {}
73
+ user 'u', {}
74
+ user 'u2', {}
75
+ user 'u3', {}
76
+ user 'u4', {}
77
+ client 'c', {}
78
+ client 'c2', {}
79
+ client 'c3', {}
80
+ client 'c4', {}
81
+
82
+ group 'x', {
83
+ 'users' => %w(u u2),
84
+ 'clients' => %w(c c2),
85
+ 'groups' => %w(g g2)
86
+ }
87
+
88
+ it 'Converging chef_group "x" changes nothing' do
89
+ run_recipe do
90
+ chef_group 'x'
91
+ end
92
+ expect(chef_run).not_to have_updated('chef_group[x]', :create)
93
+ expect(get('groups/x')).to eq({
94
+ 'name' => 'x',
95
+ 'groupname' => 'x',
96
+ 'orgname' => 'foo',
97
+ 'actors' => %w(c c2 u u2),
98
+ 'groups' => %w(g g2),
99
+ 'users' => %w(u u2),
100
+ 'clients' => %w(c c2)
101
+ })
102
+ end
103
+
104
+ it 'chef_group "x" action :delete deletes the group' do
105
+ run_recipe do
106
+ chef_group 'x' do
107
+ action :delete
108
+ end
109
+ end
110
+ expect(chef_run).to have_updated('chef_group[x]', :delete)
111
+ expect { get('groups/x') }.to raise_error(Net::HTTPServerException)
112
+ end
113
+
114
+ it 'Converging chef_group "x" with existing users changes nothing' do
115
+ run_recipe do
116
+ chef_group 'x' do
117
+ users 'u'
118
+ clients 'c'
119
+ groups 'g'
120
+ end
121
+ end
122
+ expect(chef_run).not_to have_updated('chef_group[x]', :create)
123
+ expect(get('groups/x')).to eq({
124
+ 'name' => 'x',
125
+ 'groupname' => 'x',
126
+ 'orgname' => 'foo',
127
+ 'actors' => %w(c c2 u u2),
128
+ 'groups' => %w(g g2),
129
+ 'users' => %w(u u2),
130
+ 'clients' => %w(c c2)
131
+ })
132
+ end
133
+
134
+ it 'Converging chef_group "x" adds new users' do
135
+ run_recipe do
136
+ chef_group 'x' do
137
+ users 'u3'
138
+ clients 'c3'
139
+ groups 'g3'
140
+ end
141
+ end
142
+ expect(chef_run).to have_updated('chef_group[x]', :create)
143
+ expect(get('groups/x')).to eq({
144
+ 'name' => 'x',
145
+ 'groupname' => 'x',
146
+ 'orgname' => 'foo',
147
+ 'actors' => %w(c c2 c3 u u2 u3),
148
+ 'groups' => %w(g g2 g3),
149
+ 'users' => %w(u u2 u3),
150
+ 'clients' => %w(c c2 c3)
151
+ })
152
+ end
153
+
154
+ it 'Converging chef_group "x" with multiple users adds new users' do
155
+ run_recipe do
156
+ chef_group 'x' do
157
+ users 'u3', 'u4'
158
+ clients 'c3', 'c4'
159
+ groups 'g3', 'g4'
160
+ end
161
+ end
162
+ expect(chef_run).to have_updated('chef_group[x]', :create)
163
+ expect(get('groups/x')).to eq({
164
+ 'name' => 'x',
165
+ 'groupname' => 'x',
166
+ 'orgname' => 'foo',
167
+ 'actors' => %w(c c2 c3 c4 u u2 u3 u4),
168
+ 'groups' => %w(g g2 g3 g4),
169
+ 'users' => %w(u u2 u3 u4),
170
+ 'clients' => %w(c c2 c3 c4)
171
+ })
172
+ end
173
+
174
+ it 'Converging chef_group "x" with multiple users in an array adds new users' do
175
+ run_recipe do
176
+ chef_group 'x' do
177
+ users [ 'u3', 'u4' ]
178
+ clients [ 'c3', 'c4' ]
179
+ groups [ 'g3', 'g4' ]
180
+ end
181
+ end
182
+ expect(chef_run).to have_updated('chef_group[x]', :create)
183
+ expect(get('groups/x')).to eq({
184
+ 'name' => 'x',
185
+ 'groupname' => 'x',
186
+ 'orgname' => 'foo',
187
+ 'actors' => %w(c c2 c3 c4 u u2 u3 u4),
188
+ 'groups' => %w(g g2 g3 g4),
189
+ 'users' => %w(u u2 u3 u4),
190
+ 'clients' => %w(c c2 c3 c4)
191
+ })
192
+ end
193
+
194
+ it 'Converging chef_group "x" with multiple users declarations adds new users' do
195
+ run_recipe do
196
+ chef_group 'x' do
197
+ users 'u3'
198
+ users 'u4'
199
+ clients 'c3'
200
+ clients 'c4'
201
+ groups 'g3'
202
+ groups 'g4'
203
+ end
204
+ end
205
+ expect(chef_run).to have_updated('chef_group[x]', :create)
206
+ expect(get('groups/x')).to eq({
207
+ 'name' => 'x',
208
+ 'groupname' => 'x',
209
+ 'orgname' => 'foo',
210
+ 'actors' => %w(c c2 c3 c4 u u2 u3 u4),
211
+ 'groups' => %w(g g2 g3 g4),
212
+ 'users' => %w(u u2 u3 u4),
213
+ 'clients' => %w(c c2 c3 c4)
214
+ })
215
+ end
216
+
217
+ it 'Converging chef_group "x" removes desired users' do
218
+ run_recipe do
219
+ chef_group 'x' do
220
+ remove_users 'u2'
221
+ remove_clients 'c2'
222
+ remove_groups 'g2'
223
+ end
224
+ end
225
+ expect(chef_run).to have_updated('chef_group[x]', :create)
226
+ expect(get('groups/x')).to eq({
227
+ 'name' => 'x',
228
+ 'groupname' => 'x',
229
+ 'orgname' => 'foo',
230
+ 'actors' => %w(c u),
231
+ 'groups' => %w(g),
232
+ 'users' => %w(u),
233
+ 'clients' => %w(c)
234
+ })
235
+ end
236
+
237
+ it 'Converging chef_group "x" with multiple users removes desired users' do
238
+ run_recipe do
239
+ chef_group 'x' do
240
+ remove_users 'u', 'u2'
241
+ remove_clients 'c', 'c2'
242
+ remove_groups 'g', 'g2'
243
+ end
244
+ end
245
+ expect(chef_run).to have_updated('chef_group[x]', :create)
246
+ expect(get('groups/x')).to eq({
247
+ 'name' => 'x',
248
+ 'groupname' => 'x',
249
+ 'orgname' => 'foo',
250
+ 'actors' => [],
251
+ 'groups' => [],
252
+ 'users' => [],
253
+ 'clients' => []
254
+ })
255
+ end
256
+
257
+ it 'Converging chef_group "x" with multiple users in an array removes desired users' do
258
+ run_recipe do
259
+ chef_group 'x' do
260
+ remove_users [ 'u', 'u2' ]
261
+ remove_clients [ 'c', 'c2' ]
262
+ remove_groups [ 'g', 'g2' ]
263
+ end
264
+ end
265
+ expect(chef_run).to have_updated('chef_group[x]', :create)
266
+ expect(get('groups/x')).to eq({
267
+ 'name' => 'x',
268
+ 'groupname' => 'x',
269
+ 'orgname' => 'foo',
270
+ 'actors' => [],
271
+ 'groups' => [],
272
+ 'users' => [],
273
+ 'clients' => []
274
+ })
275
+ end
276
+
277
+ it 'Converging chef_group "x" with multiple remove_ declarations removes desired users' do
278
+ run_recipe do
279
+ chef_group 'x' do
280
+ remove_users 'u'
281
+ remove_users 'u2'
282
+ remove_clients 'c'
283
+ remove_clients 'c2'
284
+ remove_groups 'g'
285
+ remove_groups 'g2'
286
+ end
287
+ end
288
+ expect(chef_run).to have_updated('chef_group[x]', :create)
289
+ expect(get('groups/x')).to eq({
290
+ 'name' => 'x',
291
+ 'groupname' => 'x',
292
+ 'orgname' => 'foo',
293
+ 'actors' => [],
294
+ 'groups' => [],
295
+ 'users' => [],
296
+ 'clients' => []
297
+ })
298
+ end
299
+
300
+ it 'Converging chef_group "x" adds and removes desired users' do
301
+ run_recipe do
302
+ chef_group 'x' do
303
+ users 'u3'
304
+ clients 'c3'
305
+ groups 'g3'
306
+ remove_users 'u'
307
+ remove_clients 'c'
308
+ remove_groups 'g'
309
+ end
310
+ end
311
+ expect(chef_run).to have_updated('chef_group[x]', :create)
312
+ expect(get('groups/x')).to eq({
313
+ 'name' => 'x',
314
+ 'groupname' => 'x',
315
+ 'orgname' => 'foo',
316
+ 'actors' => %w(c2 c3 u2 u3),
317
+ 'groups' => %w(g2 g3),
318
+ 'users' => %w(u2 u3),
319
+ 'clients' => %w(c2 c3)
320
+ })
321
+ end
322
+ end
323
+ end
324
+ end