clc-cheffish 0.8.clc

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 (63) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +4 -0
  4. data/Rakefile +23 -0
  5. data/lib/chef/provider/chef_acl.rb +434 -0
  6. data/lib/chef/provider/chef_client.rb +48 -0
  7. data/lib/chef/provider/chef_container.rb +50 -0
  8. data/lib/chef/provider/chef_data_bag.rb +50 -0
  9. data/lib/chef/provider/chef_data_bag_item.rb +273 -0
  10. data/lib/chef/provider/chef_environment.rb +78 -0
  11. data/lib/chef/provider/chef_group.rb +78 -0
  12. data/lib/chef/provider/chef_mirror.rb +138 -0
  13. data/lib/chef/provider/chef_node.rb +82 -0
  14. data/lib/chef/provider/chef_organization.rb +150 -0
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +41 -0
  16. data/lib/chef/provider/chef_role.rb +79 -0
  17. data/lib/chef/provider/chef_user.rb +53 -0
  18. data/lib/chef/provider/private_key.rb +219 -0
  19. data/lib/chef/provider/public_key.rb +82 -0
  20. data/lib/chef/resource/chef_acl.rb +65 -0
  21. data/lib/chef/resource/chef_client.rb +44 -0
  22. data/lib/chef/resource/chef_container.rb +18 -0
  23. data/lib/chef/resource/chef_data_bag.rb +18 -0
  24. data/lib/chef/resource/chef_data_bag_item.rb +114 -0
  25. data/lib/chef/resource/chef_environment.rb +71 -0
  26. data/lib/chef/resource/chef_group.rb +49 -0
  27. data/lib/chef/resource/chef_mirror.rb +47 -0
  28. data/lib/chef/resource/chef_node.rb +18 -0
  29. data/lib/chef/resource/chef_organization.rb +64 -0
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +31 -0
  31. data/lib/chef/resource/chef_role.rb +104 -0
  32. data/lib/chef/resource/chef_user.rb +51 -0
  33. data/lib/chef/resource/private_key.rb +44 -0
  34. data/lib/chef/resource/public_key.rb +21 -0
  35. data/lib/cheffish.rb +222 -0
  36. data/lib/cheffish/actor_provider_base.rb +131 -0
  37. data/lib/cheffish/basic_chef_client.rb +115 -0
  38. data/lib/cheffish/chef_provider_base.rb +231 -0
  39. data/lib/cheffish/chef_run_data.rb +19 -0
  40. data/lib/cheffish/chef_run_listener.rb +28 -0
  41. data/lib/cheffish/key_formatter.rb +109 -0
  42. data/lib/cheffish/merged_config.rb +94 -0
  43. data/lib/cheffish/recipe_dsl.rb +147 -0
  44. data/lib/cheffish/server_api.rb +52 -0
  45. data/lib/cheffish/version.rb +3 -0
  46. data/lib/cheffish/with_pattern.rb +21 -0
  47. data/spec/functional/fingerprint_spec.rb +64 -0
  48. data/spec/functional/merged_config_spec.rb +20 -0
  49. data/spec/integration/chef_acl_spec.rb +914 -0
  50. data/spec/integration/chef_client_spec.rb +110 -0
  51. data/spec/integration/chef_container_spec.rb +34 -0
  52. data/spec/integration/chef_group_spec.rb +324 -0
  53. data/spec/integration/chef_mirror_spec.rb +244 -0
  54. data/spec/integration/chef_node_spec.rb +211 -0
  55. data/spec/integration/chef_organization_spec.rb +244 -0
  56. data/spec/integration/chef_user_spec.rb +90 -0
  57. data/spec/integration/private_key_spec.rb +446 -0
  58. data/spec/integration/recipe_dsl_spec.rb +29 -0
  59. data/spec/support/key_support.rb +29 -0
  60. data/spec/support/repository_support.rb +103 -0
  61. data/spec/support/spec_support.rb +176 -0
  62. data/spec/unit/get_private_key_spec.rb +93 -0
  63. metadata +162 -0
@@ -0,0 +1,110 @@
1
+ require 'support/spec_support'
2
+ require 'support/key_support'
3
+ require 'chef/resource/chef_client'
4
+ require 'chef/provider/chef_client'
5
+
6
+ repo_path = Dir.mktmpdir('chef_repo')
7
+
8
+ describe Chef::Resource::ChefClient do
9
+ extend SpecSupport
10
+
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
30
+
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")
37
+ end
38
+ end
39
+
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
52
+ end
53
+ end
54
+
55
+ context "and a private_key 'blah' resource" do
56
+ before :each do
57
+ Chef::Config.private_key_paths = [ repo_path ]
58
+ end
59
+
60
+ with_recipe do
61
+ private_key 'blah'
62
+ end
63
+
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
70
+
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")
76
+
77
+ private_key = Cheffish::KeyFormatter.decode(Cheffish.get_private_key('blah'))
78
+ expect(key).to be_public_key_for(private_key)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
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
91
+
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
106
+ end
107
+ end
108
+ end
109
+ end
110
+ 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