cheffish 0.7.1 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
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