clc-cheffish 0.8.clc

Sign up to get free protection for your applications and to get access to all the features.
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,244 @@
1
+ require 'support/spec_support'
2
+ require 'chef/resource/chef_mirror'
3
+ require 'chef/provider/chef_mirror'
4
+
5
+ describe Chef::Resource::ChefMirror 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
+ when_the_repository 'is full of stuff' do
17
+ file 'nodes/x.json', {}
18
+ file 'roles/x.json', {}
19
+
20
+ it "Download grabs defaults" do
21
+ run_recipe do
22
+ chef_mirror '' do
23
+ action :download
24
+ end
25
+ end
26
+ expect(chef_run).to have_updated('chef_mirror[]', :download)
27
+ expect(File.exist?(path_to('groups/admins.json'))).to be true
28
+ expect(File.exist?(path_to('environments/_default.json'))).to be true
29
+ end
30
+
31
+ it "Upload uploads everything" do
32
+ run_recipe do
33
+ chef_mirror '' do
34
+ action :upload
35
+ end
36
+ end
37
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
38
+ expect { get('nodes/x') }.not_to raise_error
39
+ expect { get('roles/x') }.not_to raise_error
40
+ end
41
+
42
+ it 'chef_mirror with concurrency 0 fails with a reasonable message' do
43
+ expect {
44
+ run_recipe do
45
+ chef_mirror '' do
46
+ concurrency 0
47
+ action :download
48
+ end
49
+ end
50
+ }.to raise_error /chef_mirror.concurrency must be above 0/
51
+ end
52
+ end
53
+
54
+ when_the_repository 'has stuff but no chef_repo_path' do
55
+ file 'repo/nodes/x.json', {}
56
+ file 'repo/roles/x.json', {}
57
+ file 'repo2/nodes/y.json', {}
58
+ file 'repo2/roles/y.json', {}
59
+
60
+ before do
61
+ Chef::Config.delete(:chef_repo_path)
62
+ Chef::Config.delete(:node_path)
63
+ Chef::Config.delete(:cookbook_path)
64
+ Chef::Config.delete(:role_path)
65
+ end
66
+
67
+ it "Upload with chef_repo_path('repo') uploads everything" do
68
+ repo_path = path_to('repo')
69
+ run_recipe do
70
+ chef_mirror '' do
71
+ chef_repo_path repo_path
72
+ action :upload
73
+ end
74
+ end
75
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
76
+ expect { get('nodes/x') }.not_to raise_error
77
+ expect { get('roles/x') }.not_to raise_error
78
+ expect { get('nodes/y') }.to raise_error
79
+ expect { get('roles/y') }.to raise_error
80
+ end
81
+
82
+ it "Upload with chef_repo_path(:chef_repo_path) with multiple paths uploads everything" do
83
+ repo_path = path_to('repo')
84
+ repo2_path = path_to('repo2')
85
+ run_recipe do
86
+ chef_mirror '' do
87
+ chef_repo_path :chef_repo_path => [ repo_path, repo2_path ]
88
+ action :upload
89
+ end
90
+ end
91
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
92
+ expect { get('nodes/x') }.not_to raise_error
93
+ expect { get('roles/x') }.not_to raise_error
94
+ expect { get('nodes/y') }.not_to raise_error
95
+ expect { get('roles/y') }.not_to raise_error
96
+ end
97
+
98
+ it "Upload with chef_repo_path(:node_path, :role_path) uploads everything" do
99
+ repo_path = path_to('repo')
100
+ repo2_path = path_to('repo2')
101
+
102
+ run_recipe do
103
+ chef_mirror '' do
104
+ chef_repo_path :chef_repo_path => '/blahblah',
105
+ :node_path => "#{repo_path}/nodes",
106
+ :role_path => "#{repo2_path}/roles"
107
+ action :upload
108
+ end
109
+ end
110
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
111
+ expect { get('nodes/x') }.not_to raise_error
112
+ expect { get('roles/x') }.to raise_error
113
+ expect { get('nodes/y') }.to raise_error
114
+ expect { get('roles/y') }.not_to raise_error
115
+ end
116
+
117
+ it "Upload with chef_repo_path(:chef_repo_path, :role_path) uploads everything" do
118
+ repo_path = path_to('repo')
119
+ repo2_path = path_to('repo2')
120
+
121
+ run_recipe do
122
+ chef_mirror '' do
123
+ chef_repo_path :chef_repo_path => repo_path,
124
+ :role_path => "#{repo2_path}/roles"
125
+ action :upload
126
+ end
127
+ end
128
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
129
+ expect { get('nodes/x') }.not_to raise_error
130
+ expect { get('roles/x') }.to raise_error
131
+ expect { get('nodes/y') }.to raise_error
132
+ expect { get('roles/y') }.not_to raise_error
133
+ end
134
+
135
+ it "Upload with chef_repo_path(:node_path, :role_path) with multiple paths uploads everything" do
136
+ repo_path = path_to('repo')
137
+ repo2_path = path_to('repo2')
138
+
139
+ run_recipe do
140
+ chef_mirror '' do
141
+ chef_repo_path :chef_repo_path => [ 'foo', 'bar' ],
142
+ :node_path => [ "#{repo_path}/nodes", "#{repo2_path}/nodes" ],
143
+ :role_path => [ "#{repo_path}/roles", "#{repo2_path}/roles" ]
144
+ action :upload
145
+ end
146
+ end
147
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
148
+ expect { get('nodes/x') }.not_to raise_error
149
+ expect { get('roles/x') }.not_to raise_error
150
+ expect { get('nodes/y') }.not_to raise_error
151
+ expect { get('roles/y') }.not_to raise_error
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'and has stuff' do
157
+ node 'x', {}
158
+ role 'x', {}
159
+
160
+ when_the_repository 'is empty' do
161
+ it "Download grabs stuff" do
162
+ run_recipe do
163
+ chef_mirror '' do
164
+ action :download
165
+ end
166
+ end
167
+ expect(chef_run).to have_updated('chef_mirror[]', :download)
168
+ expect(File.exist?(path_to('nodes/x.json'))).to be true
169
+ expect(File.exist?(path_to('roles/x.json'))).to be true
170
+ end
171
+
172
+ it "Upload uploads nothing" do
173
+ run_recipe do
174
+ chef_mirror '' do
175
+ action :upload
176
+ end
177
+ end
178
+ expect(chef_run).not_to have_updated('chef_mirror[]', :upload)
179
+ end
180
+ end
181
+ end
182
+
183
+ context 'and has nodes and roles named x' do
184
+ node 'x', {}
185
+ role 'x', {}
186
+
187
+ when_the_repository 'has nodes and roles named y' do
188
+ file 'nodes/y.json', {}
189
+ file 'roles/y.json', {}
190
+
191
+ it "Download grabs the x's" do
192
+ run_recipe do
193
+ chef_mirror '' do
194
+ action :download
195
+ end
196
+ end
197
+ expect(chef_run).to have_updated('chef_mirror[]', :download)
198
+ expect(File.exist?(path_to('nodes/x.json'))).to be true
199
+ expect(File.exist?(path_to('roles/x.json'))).to be true
200
+ expect(File.exist?(path_to('nodes/y.json'))).to be true
201
+ expect(File.exist?(path_to('roles/y.json'))).to be true
202
+ end
203
+
204
+ it "Upload uploads the y's" do
205
+ run_recipe do
206
+ chef_mirror '' do
207
+ action :upload
208
+ end
209
+ end
210
+ expect(chef_run).to have_updated('chef_mirror[]', :upload)
211
+ expect { get('nodes/x') }.not_to raise_error
212
+ expect { get('roles/x') }.not_to raise_error
213
+ expect { get('nodes/y') }.not_to raise_error
214
+ expect { get('roles/y') }.not_to raise_error
215
+ end
216
+
217
+ it "Download with purge grabs the x's and deletes the y's" do
218
+ run_recipe do
219
+ chef_mirror '' do
220
+ purge true
221
+ action :download
222
+ end
223
+ end
224
+ expect(chef_run).to have_updated('chef_mirror[]', :download)
225
+ expect(File.exist?(path_to('nodes/x.json'))).to be true
226
+ expect(File.exist?(path_to('roles/x.json'))).to be true
227
+ end
228
+
229
+ it "Upload with :purge uploads the y's and deletes the x's" do
230
+ run_recipe do
231
+ chef_mirror '*/*.json' do
232
+ purge true
233
+ action :upload
234
+ end
235
+ end
236
+ expect(chef_run).to have_updated('chef_mirror[*/*.json]', :upload)
237
+ expect { get('nodes/y') }.not_to raise_error
238
+ expect { get('roles/y') }.not_to raise_error
239
+ end
240
+ end
241
+ end
242
+
243
+ end
244
+ end
@@ -0,0 +1,211 @@
1
+ require 'support/spec_support'
2
+ require 'chef/resource/chef_node'
3
+ require 'chef/provider/chef_node'
4
+
5
+ describe Chef::Resource::ChefNode 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
+ context 'and we run a recipe that creates node "blah"' do
17
+ with_converge do
18
+ chef_node 'blah'
19
+ end
20
+
21
+ it 'the node gets created' do
22
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
23
+ expect(get('nodes/blah')['name']).to eq('blah')
24
+ end
25
+ end
26
+
27
+ # TODO why-run mode
28
+
29
+ context 'and another chef server is running on port 8899' do
30
+ before :each do
31
+ @server = ChefZero::Server.new(:port => 8899)
32
+ @server.start_background
33
+ end
34
+
35
+ after :each do
36
+ @server.stop
37
+ end
38
+
39
+ context 'and a recipe is run that creates node "blah" on the second chef server using with_chef_server' do
40
+
41
+ with_converge do
42
+ with_chef_server 'http://127.0.0.1:8899'
43
+ chef_node 'blah'
44
+ end
45
+
46
+ it 'the node is created on the second chef server but not the first' do
47
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
48
+ expect { get('nodes/blah') }.to raise_error(Net::HTTPServerException)
49
+ expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
50
+ end
51
+ end
52
+
53
+ context 'and a recipe is run that creates node "blah" on the second chef server using chef_server' do
54
+
55
+ with_converge do
56
+ chef_node 'blah' do
57
+ chef_server({ :chef_server_url => 'http://127.0.0.1:8899' })
58
+ end
59
+ end
60
+
61
+ it 'the node is created on the second chef server but not the first' do
62
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
63
+ expect { get('nodes/blah') }.to raise_error(Net::HTTPServerException)
64
+ expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'and has a node named "blah"' do
71
+ node 'blah', {}
72
+
73
+ with_converge do
74
+ chef_node 'blah'
75
+ end
76
+
77
+ it 'chef_node "blah" does not get created or updated' do
78
+ expect(chef_run).not_to have_updated 'chef_node[blah]', :create
79
+ end
80
+ end
81
+
82
+ context 'and has a node named "blah" with tags' do
83
+ node 'blah', {
84
+ 'normal' => { 'tags' => [ 'a', 'b' ] }
85
+ }
86
+
87
+ context 'with chef_node "blah" that sets attributes' do
88
+ with_converge do
89
+ chef_node 'blah' do
90
+ attributes({})
91
+ end
92
+ end
93
+
94
+ it 'the tags in attributes are used' do
95
+ expect(get('nodes/blah')['normal']['tags']).to eq([ 'a', 'b' ])
96
+ end
97
+ end
98
+
99
+ context 'with chef_node "blah" that sets attributes with tags in them' do
100
+ with_converge do
101
+ chef_node 'blah' do
102
+ attributes 'tags' => [ 'c', 'd' ]
103
+ end
104
+ end
105
+
106
+ it 'the tags in attributes are used' do
107
+ expect(get('nodes/blah')['normal']['tags']).to eq([ 'c', 'd' ])
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'has a node named "blah" with everything in it' do
113
+ node 'blah', {
114
+ 'chef_environment' => 'blah',
115
+ 'run_list' => [ 'recipe[bjork]' ],
116
+ 'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
117
+ 'default' => { 'foo2' => 'bar2' },
118
+ 'automatic' => { 'foo3' => 'bar3' },
119
+ 'override' => { 'foo4' => 'bar4' }
120
+ }
121
+
122
+ context 'with chef_node "blah"' do
123
+ with_converge do
124
+ chef_node 'blah'
125
+ end
126
+
127
+ it 'nothing gets updated' do
128
+ expect(chef_run).not_to have_updated 'chef_node[blah]', :create
129
+ end
130
+ end
131
+
132
+ context 'with chef_node "blah" and an updated normal attribute value' do
133
+ with_converge do
134
+ chef_node 'blah' do
135
+ attributes 'foo' => 'fum'
136
+ end
137
+ end
138
+
139
+ it 'new normal attribute is added' do
140
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
141
+ node = get('nodes/blah')
142
+ expect(node['normal']).to eq({ 'foo' => 'fum', 'tags' => [ 'a', 'b' ] })
143
+ end
144
+ end
145
+
146
+ context 'with chef_node "blah" and a new normal attribute' do
147
+ with_converge do
148
+ chef_node 'blah' do
149
+ attributes 'foe' => 'fum'
150
+ end
151
+ end
152
+
153
+ it 'new normal attribute is added' do
154
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
155
+ node = get('nodes/blah')
156
+ expect(node['normal']).to eq({ 'foe' => 'fum', 'foo' => 'bar', 'tags' => [ 'a', 'b' ] })
157
+ end
158
+ end
159
+
160
+ context 'with chef_node "blah" with complete true' do
161
+ with_converge do
162
+ chef_node 'blah' do
163
+ complete true
164
+ end
165
+ end
166
+
167
+ it 'default, automatic and override attributes are left alone' do
168
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
169
+ node = get('nodes/blah')
170
+ expect(node['chef_environment']).to eq('_default')
171
+ expect(node['run_list']).to eq([])
172
+ expect(node['normal']).to eq({ 'tags' => [ 'a', 'b' ] })
173
+ expect(node['default']).to eq({ 'foo2' => 'bar2' })
174
+ expect(node['automatic']).to eq({ 'foo3' => 'bar3' })
175
+ expect(node['override']).to eq({ 'foo4' => 'bar4' })
176
+ end
177
+ end
178
+
179
+ context 'with chef_node "blah", complete true and a new normal attribute' do
180
+ with_converge do
181
+ chef_node 'blah' do
182
+ attributes 'foe' => 'fum'
183
+ complete true
184
+ end
185
+ end
186
+
187
+ it 'normal foo attribute is replaced with new attribute' do
188
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
189
+ node = get('nodes/blah')
190
+ expect(node['normal']).to eq({ 'foe' => 'fum', 'tags' => [ 'a', 'b' ] })
191
+ end
192
+ end
193
+
194
+ end
195
+ end
196
+
197
+ when_the_chef_server 'is in OSC mode' do
198
+ context 'and is empty' do
199
+ context 'and we run a recipe that creates node "blah"' do
200
+ with_converge do
201
+ chef_node 'blah'
202
+ end
203
+
204
+ it 'the node gets created' do
205
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
206
+ expect(get('nodes/blah')['name']).to eq('blah')
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end