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
@@ -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
@@ -5,140 +5,162 @@ require 'chef/provider/chef_node'
5
5
  describe Chef::Resource::ChefNode do
6
6
  extend SpecSupport
7
7
 
8
- when_the_chef_server 'is empty' do
9
- context 'and we run a recipe that creates node "blah"' do
10
- with_converge do
11
- chef_node 'blah'
12
- end
8
+ when_the_chef_server 'is in multi-org mode', :osc_compat => false, :single_org => false do
9
+ organization 'foo'
13
10
 
14
- it 'the node gets created' do
15
- expect(chef_run).to have_updated 'chef_node[blah]', :create
16
- expect(get('/nodes/blah')['name']).to eq('blah')
17
- end
11
+ before :each do
12
+ Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
18
13
  end
19
14
 
20
- # TODO why-run mode
21
-
22
- context 'and another chef server is running on port 8899' do
23
- before :each do
24
- @server = ChefZero::Server.new(:port => 8899)
25
- @server.start_background
26
- end
27
-
28
- after :each do
29
- @server.stop
30
- end
31
-
32
- context 'and a recipe is run that creates node "blah" on the second chef server using with_chef_server' do
33
-
15
+ context 'and is empty' do
16
+ context 'and we run a recipe that creates node "blah"' do
34
17
  with_converge do
35
- with_chef_server 'http://127.0.0.1:8899'
36
18
  chef_node 'blah'
37
19
  end
38
20
 
39
- it 'the node is created on the second chef server but not the first' do
21
+ it 'the node gets created' do
40
22
  expect(chef_run).to have_updated 'chef_node[blah]', :create
41
- expect { get('/nodes/blah') }.to raise_error(Net::HTTPServerException)
42
- expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
23
+ expect(get('nodes/blah')['name']).to eq('blah')
43
24
  end
44
25
  end
45
26
 
46
- context 'and a recipe is run that creates node "blah" on the second chef server using chef_server' do
27
+ # TODO why-run mode
47
28
 
48
- with_converge do
49
- chef_node 'blah' do
50
- chef_server({ :chef_server_url => 'http://127.0.0.1:8899' })
51
- end
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
52
33
  end
53
34
 
54
- it 'the node is created on the second chef server but not the first' do
55
- expect(chef_run).to have_updated 'chef_node[blah]', :create
56
- expect { get('/nodes/blah') }.to raise_error(Net::HTTPServerException)
57
- expect(get('http://127.0.0.1:8899/nodes/blah')['name']).to eq('blah')
35
+ after :each do
36
+ @server.stop
58
37
  end
59
- end
60
38
 
61
- end
62
- end
39
+ context 'and a recipe is run that creates node "blah" on the second chef server using with_chef_server' do
63
40
 
64
- when_the_chef_server 'has a node named "blah"' do
65
- node 'blah', {}
41
+ with_converge do
42
+ with_chef_server 'http://127.0.0.1:8899'
43
+ chef_node 'blah'
44
+ end
66
45
 
67
- with_converge do
68
- chef_node 'blah'
69
- end
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
70
54
 
71
- it 'chef_node "blah" does not get created or updated' do
72
- expect(chef_run).not_to have_updated 'chef_node[blah]', :create
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
73
68
  end
74
- end
75
69
 
76
- when_the_chef_server 'has a node named "blah" with tags' do
77
- node 'blah', {
78
- 'normal' => { 'tags' => [ 'a', 'b' ] }
79
- }
70
+ context 'and has a node named "blah"' do
71
+ node 'blah', {}
80
72
 
81
- context 'with chef_node "blah" that sets attributes' do
82
73
  with_converge do
83
- chef_node 'blah' do
84
- attributes({})
85
- end
74
+ chef_node 'blah'
86
75
  end
87
76
 
88
- it 'the tags in attributes are used' do
89
- expect(get('/nodes/blah')['normal']['tags']).to eq([ 'a', 'b' ])
77
+ it 'chef_node "blah" does not get created or updated' do
78
+ expect(chef_run).not_to have_updated 'chef_node[blah]', :create
90
79
  end
91
80
  end
92
81
 
93
- context 'with chef_node "blah" that sets attributes with tags in them' do
94
- with_converge do
95
- chef_node 'blah' do
96
- attributes 'tags' => [ 'c', 'd' ]
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' ])
97
96
  end
98
97
  end
99
98
 
100
- it 'the tags in attributes are used' do
101
- expect(get('/nodes/blah')['normal']['tags']).to eq([ 'c', 'd' ])
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
102
109
  end
103
110
  end
104
- end
105
111
 
106
- when_the_chef_server 'has a node named "blah" with everything in it' do
107
- node 'blah', {
108
- 'chef_environment' => 'blah',
109
- 'run_list' => [ 'recipe[bjork]' ],
110
- 'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
111
- 'default' => { 'foo2' => 'bar2' },
112
- 'automatic' => { 'foo3' => 'bar3' },
113
- 'override' => { 'foo4' => 'bar4' }
114
- }
115
-
116
- context 'with chef_node "blah"' do
117
- with_converge do
118
- chef_node 'blah'
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
119
130
  end
120
131
 
121
- it 'nothing gets updated' do
122
- expect(chef_run).not_to have_updated 'chef_node[blah]', :create
132
+ context 'with chef_node "blah" with complete true' do
133
+ with_converge do
134
+ chef_node 'blah' do
135
+ complete true
136
+ end
137
+ end
138
+
139
+ it 'default, automatic and override attributes are left alone' do
140
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
141
+ node = get('nodes/blah')
142
+ expect(node['chef_environment']).to eq('_default')
143
+ expect(node['run_list']).to eq([])
144
+ expect(node['normal']).to eq({ 'tags' => [ 'a', 'b' ] })
145
+ expect(node['default']).to eq({ 'foo2' => 'bar2' })
146
+ expect(node['automatic']).to eq({ 'foo3' => 'bar3' })
147
+ expect(node['override']).to eq({ 'foo4' => 'bar4' })
148
+ end
123
149
  end
124
150
  end
151
+ end
125
152
 
126
- context 'with chef_node "blah" with complete true' do
127
- with_converge do
128
- chef_node 'blah' do
129
- complete true
153
+ when_the_chef_server 'is in OSC mode' do
154
+ context 'and is empty' do
155
+ context 'and we run a recipe that creates node "blah"' do
156
+ with_converge do
157
+ chef_node 'blah'
130
158
  end
131
- end
132
159
 
133
- it 'default, automatic and override attributes are left alone' do
134
- expect(chef_run).to have_updated 'chef_node[blah]', :create
135
- node = get('/nodes/blah')
136
- expect(node['chef_environment']).to eq('_default')
137
- expect(node['run_list']).to eq([])
138
- expect(node['normal']).to eq({ 'tags' => [ 'a', 'b' ] })
139
- expect(node['default']).to eq({ 'foo2' => 'bar2' })
140
- expect(node['automatic']).to eq({ 'foo3' => 'bar3' })
141
- expect(node['override']).to eq({ 'foo4' => 'bar4' })
160
+ it 'the node gets created' do
161
+ expect(chef_run).to have_updated 'chef_node[blah]', :create
162
+ expect(get('nodes/blah')['name']).to eq('blah')
163
+ end
142
164
  end
143
165
  end
144
166
  end