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.
- checksums.yaml +4 -4
- data/lib/chef/provider/chef_acl.rb +434 -0
- data/lib/chef/provider/chef_client.rb +5 -1
- data/lib/chef/provider/chef_container.rb +50 -0
- data/lib/chef/provider/chef_group.rb +78 -0
- data/lib/chef/provider/chef_mirror.rb +138 -0
- data/lib/chef/provider/chef_organization.rb +150 -0
- data/lib/chef/provider/chef_user.rb +6 -1
- data/lib/chef/provider/public_key.rb +0 -1
- data/lib/chef/resource/chef_acl.rb +38 -44
- data/lib/chef/resource/chef_container.rb +18 -0
- data/lib/chef/resource/chef_group.rb +49 -0
- data/lib/chef/resource/chef_mirror.rb +47 -0
- data/lib/chef/resource/chef_organization.rb +64 -0
- data/lib/chef/resource/private_key.rb +6 -1
- data/lib/chef/resource/public_key.rb +5 -0
- data/lib/cheffish/actor_provider_base.rb +14 -9
- data/lib/cheffish/basic_chef_client.rb +18 -2
- data/lib/cheffish/chef_provider_base.rb +7 -0
- data/lib/cheffish/merged_config.rb +10 -2
- data/lib/cheffish/recipe_dsl.rb +34 -8
- data/lib/cheffish/server_api.rb +12 -2
- data/lib/cheffish/version.rb +1 -1
- data/lib/cheffish.rb +2 -2
- data/spec/functional/merged_config_spec.rb +20 -0
- data/spec/integration/chef_acl_spec.rb +914 -0
- data/spec/integration/chef_client_spec.rb +78 -44
- data/spec/integration/chef_container_spec.rb +34 -0
- data/spec/integration/chef_group_spec.rb +324 -0
- data/spec/integration/chef_mirror_spec.rb +244 -0
- data/spec/integration/chef_node_spec.rb +115 -93
- data/spec/integration/chef_organization_spec.rb +244 -0
- data/spec/integration/chef_user_spec.rb +51 -9
- data/spec/support/repository_support.rb +103 -0
- data/spec/support/spec_support.rb +55 -2
- metadata +23 -9
- data/lib/chef/resource/in_parallel.rb +0 -6
@@ -0,0 +1,244 @@
|
|
1
|
+
require 'support/spec_support'
|
2
|
+
require 'chef/resource/chef_organization'
|
3
|
+
require 'chef/provider/chef_organization'
|
4
|
+
|
5
|
+
describe Chef::Resource::ChefOrganization do
|
6
|
+
extend SpecSupport
|
7
|
+
|
8
|
+
when_the_chef_server 'is in multi-org mode', :osc_compat => false, :single_org => false do
|
9
|
+
context 'and chef_server_url is pointed at the top level' do
|
10
|
+
user 'u', {}
|
11
|
+
user 'u2', {}
|
12
|
+
|
13
|
+
it 'chef_organization "x" creates the organization' do
|
14
|
+
run_recipe do
|
15
|
+
chef_organization 'x'
|
16
|
+
end
|
17
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
18
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'and chef_server_url is pointed at /organizations/foo' do
|
23
|
+
organization 'foo'
|
24
|
+
|
25
|
+
before :each do
|
26
|
+
Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'and is empty' do
|
30
|
+
user 'u', {}
|
31
|
+
user 'u2', {}
|
32
|
+
|
33
|
+
it 'chef_organization "x" creates the organization' do
|
34
|
+
run_recipe do
|
35
|
+
chef_organization 'x'
|
36
|
+
end
|
37
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
38
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'chef_organization "x" with full_name creates the organization' do
|
42
|
+
run_recipe do
|
43
|
+
chef_organization 'x' do
|
44
|
+
full_name 'Hi'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
48
|
+
expect(get('/organizations/x')['full_name']).to eq('Hi')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'chef_organization "x" and inviting users creates the invites' do
|
52
|
+
run_recipe do
|
53
|
+
chef_organization 'x' do
|
54
|
+
invites 'u', 'u2'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
58
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(u u2))
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'chef_organization "x" adds members' do
|
62
|
+
run_recipe do
|
63
|
+
chef_organization 'x' do
|
64
|
+
members 'u', 'u2'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
68
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(u u2))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'and already has an organization named x' do
|
73
|
+
user 'u', {}
|
74
|
+
user 'u2', {}
|
75
|
+
user 'u3', {}
|
76
|
+
user 'member', {}
|
77
|
+
user 'member2', {}
|
78
|
+
user 'invited', {}
|
79
|
+
user 'invited2', {}
|
80
|
+
organization 'x', { 'full_name' => 'Lo' } do
|
81
|
+
org_member 'member', 'member2'
|
82
|
+
org_invite 'invited', 'invited2'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'chef_organization "x" changes nothing' do
|
86
|
+
run_recipe do
|
87
|
+
chef_organization 'x'
|
88
|
+
end
|
89
|
+
expect(chef_run).not_to have_updated('chef_organization[x]', :create)
|
90
|
+
expect(get('/organizations/x')['full_name']).to eq('Lo')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'chef_organization "x" with "complete true" reverts the full_name' do
|
94
|
+
run_recipe do
|
95
|
+
chef_organization 'x' do
|
96
|
+
complete true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
100
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'chef_organization "x" with new full_name updates the organization' do
|
104
|
+
run_recipe do
|
105
|
+
chef_organization 'x' do
|
106
|
+
full_name 'Hi'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
110
|
+
expect(get('/organizations/x')['full_name']).to eq('Hi')
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'invites and membership tests' do
|
114
|
+
it 'chef_organization "x" and inviting users creates the invites' do
|
115
|
+
run_recipe do
|
116
|
+
chef_organization 'x' do
|
117
|
+
invites 'u', 'u2'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
121
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited invited2 u u2))
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'chef_organization "x" adds members' do
|
125
|
+
run_recipe do
|
126
|
+
chef_organization 'x' do
|
127
|
+
members 'u', 'u2'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
131
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member member2 u u2))
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'chef_organization "x" does nothing when inviting already-invited users and members' do
|
135
|
+
run_recipe do
|
136
|
+
chef_organization 'x' do
|
137
|
+
invites 'invited', 'member'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
expect(chef_run).not_to have_updated('chef_organization[x]', :create)
|
141
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited invited2))
|
142
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member member2))
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'chef_organization "x" does nothing when adding members who are already members' do
|
146
|
+
run_recipe do
|
147
|
+
chef_organization 'x' do
|
148
|
+
members 'member'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
expect(chef_run).not_to have_updated('chef_organization[x]', :create)
|
152
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited invited2))
|
153
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member member2))
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'chef_organization "x" upgrades invites to members when asked' do
|
157
|
+
run_recipe do
|
158
|
+
chef_organization 'x' do
|
159
|
+
members 'invited'
|
160
|
+
end
|
161
|
+
end
|
162
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
163
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(invited member member2))
|
164
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited2))
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'chef_organization "x" removes members and invites when asked' do
|
168
|
+
run_recipe do
|
169
|
+
chef_organization 'x' do
|
170
|
+
remove_members 'invited', 'member'
|
171
|
+
end
|
172
|
+
end
|
173
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
174
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited2))
|
175
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member2))
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'chef_organization "x" does nothing when asked to remove non-members' do
|
179
|
+
run_recipe do
|
180
|
+
chef_organization 'x' do
|
181
|
+
remove_members 'u', 'u2'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
expect(chef_run).not_to have_updated('chef_organization[x]', :create)
|
185
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited invited2))
|
186
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member member2))
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'chef_organization "x" with "complete true" reverts the full_name but does not remove invites or members' do
|
190
|
+
run_recipe do
|
191
|
+
chef_organization 'x' do
|
192
|
+
complete true
|
193
|
+
end
|
194
|
+
end
|
195
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
196
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
197
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited invited2))
|
198
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member member2))
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'chef_organization "x" with members [] and "complete true" removes invites and members' do
|
202
|
+
run_recipe do
|
203
|
+
chef_organization 'x' do
|
204
|
+
members []
|
205
|
+
complete true
|
206
|
+
end
|
207
|
+
end
|
208
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
209
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
210
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq([])
|
211
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq([])
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'chef_organization "x" with members [] and "complete true" removes invites but not members' do
|
215
|
+
run_recipe do
|
216
|
+
chef_organization 'x' do
|
217
|
+
invites []
|
218
|
+
complete true
|
219
|
+
end
|
220
|
+
end
|
221
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
222
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
223
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq([])
|
224
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member member2))
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'chef_organization "x" with invites, members and "complete true" removes all non-specified invites and members' do
|
228
|
+
run_recipe do
|
229
|
+
chef_organization 'x' do
|
230
|
+
invites 'invited', 'u'
|
231
|
+
members 'member', 'u2'
|
232
|
+
complete true
|
233
|
+
end
|
234
|
+
end
|
235
|
+
expect(chef_run).to have_updated('chef_organization[x]', :create)
|
236
|
+
expect(get('/organizations/x')['full_name']).to eq('x')
|
237
|
+
expect(get('/organizations/x/association_requests').map { |u| u['username'] }).to eq(%w(invited u))
|
238
|
+
expect(get('/organizations/x/users').map { |u| u['user']['username'] }).to eq(%w(member u2))
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
@@ -8,12 +8,44 @@ repo_path = Dir.mktmpdir('chef_repo')
|
|
8
8
|
describe Chef::Resource::ChefUser do
|
9
9
|
extend SpecSupport
|
10
10
|
|
11
|
+
with_recipe do
|
12
|
+
private_key "#{repo_path}/blah.pem"
|
13
|
+
end
|
14
|
+
|
11
15
|
when_the_chef_server 'is empty' do
|
12
|
-
context 'and we
|
13
|
-
|
14
|
-
|
16
|
+
context 'and we run a recipe that creates user "blah"'do
|
17
|
+
with_converge do
|
18
|
+
chef_user 'blah' do
|
19
|
+
source_key_path "#{repo_path}/blah.pem"
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
23
|
+
it 'the user gets created' do
|
24
|
+
expect(chef_run).to have_updated 'chef_user[blah]', :create
|
25
|
+
user = get('/users/blah')
|
26
|
+
expect(user['name']).to eq('blah')
|
27
|
+
key, format = Cheffish::KeyFormatter.decode(user['public_key'])
|
28
|
+
expect(key).to be_public_key_for("#{repo_path}/blah.pem")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'and we run a recipe that creates user "blah" with output_key_path' do
|
33
|
+
with_converge do
|
34
|
+
chef_user 'blah' do
|
35
|
+
source_key_path "#{repo_path}/blah.pem"
|
36
|
+
output_key_path "#{repo_path}/blah.pub"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'the output public key gets created' do
|
41
|
+
expect(IO.read("#{repo_path}/blah.pub")).to start_with('ssh-rsa ')
|
42
|
+
expect("#{repo_path}/blah.pub").to be_public_key_for("#{repo_path}/blah.pem")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
when_the_chef_server 'is multitenant', :osc_compat => false, :single_org => false do
|
48
|
+
context 'and chef_server_url is pointed at the top level' do
|
17
49
|
context 'and we run a recipe that creates user "blah"'do
|
18
50
|
with_converge do
|
19
51
|
chef_user 'blah' do
|
@@ -29,18 +61,28 @@ describe Chef::Resource::ChefUser do
|
|
29
61
|
expect(key).to be_public_key_for("#{repo_path}/blah.pem")
|
30
62
|
end
|
31
63
|
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'and chef_server_url is pointed at /organizations/foo' do
|
67
|
+
organization 'foo'
|
68
|
+
|
69
|
+
before :each do
|
70
|
+
Chef::Config.chef_server_url = URI.join(Chef::Config.chef_server_url, '/organizations/foo').to_s
|
71
|
+
end
|
32
72
|
|
33
|
-
context 'and we run a recipe that creates
|
73
|
+
context 'and we run a recipe that creates user "blah"'do
|
34
74
|
with_converge do
|
35
|
-
|
75
|
+
chef_user 'blah' do
|
36
76
|
source_key_path "#{repo_path}/blah.pem"
|
37
|
-
output_key_path "#{repo_path}/blah.pub"
|
38
77
|
end
|
39
78
|
end
|
40
79
|
|
41
|
-
it 'the
|
42
|
-
expect(
|
43
|
-
|
80
|
+
it 'the user gets created' do
|
81
|
+
expect(chef_run).to have_updated 'chef_user[blah]', :create
|
82
|
+
user = get('/users/blah')
|
83
|
+
expect(user['name']).to eq('blah')
|
84
|
+
key, format = Cheffish::KeyFormatter.decode(user['public_key'])
|
85
|
+
expect(key).to be_public_key_for("#{repo_path}/blah.pem")
|
44
86
|
end
|
45
87
|
end
|
46
88
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module RepositorySupport
|
2
|
+
def when_the_repository(desc, *tags, &block)
|
3
|
+
context("when the chef repo #{desc}", *tags) do
|
4
|
+
include_context "with a chef repo"
|
5
|
+
extend WhenTheRepositoryClassMethods
|
6
|
+
module_eval(&block)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.shared_context "with a chef repo" do
|
11
|
+
before :each do
|
12
|
+
raise "Can only create one directory per test" if @repository_dir
|
13
|
+
@repository_dir = Dir.mktmpdir('chef_repo')
|
14
|
+
Chef::Config.chef_repo_path = @repository_dir
|
15
|
+
%w(client cookbook data_bag environment node role user).each do |object_name|
|
16
|
+
Chef::Config.delete("#{object_name}_path".to_sym)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
after :each do
|
21
|
+
if @repository_dir
|
22
|
+
begin
|
23
|
+
%w(client cookbook data_bag environment node role user).each do |object_name|
|
24
|
+
Chef::Config.delete("#{object_name}_path".to_sym)
|
25
|
+
end
|
26
|
+
Chef::Config.delete(:chef_repo_path)
|
27
|
+
FileUtils.remove_entry_secure(@repository_dir)
|
28
|
+
ensure
|
29
|
+
@repository_dir = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
Dir.chdir(@old_cwd) if @old_cwd
|
33
|
+
end
|
34
|
+
|
35
|
+
def directory(relative_path, &block)
|
36
|
+
old_parent_path = @parent_path
|
37
|
+
@parent_path = path_to(relative_path)
|
38
|
+
FileUtils.mkdir_p(@parent_path)
|
39
|
+
instance_eval(&block) if block
|
40
|
+
@parent_path = old_parent_path
|
41
|
+
end
|
42
|
+
|
43
|
+
def file(relative_path, contents)
|
44
|
+
filename = path_to(relative_path)
|
45
|
+
dir = File.dirname(filename)
|
46
|
+
FileUtils.mkdir_p(dir) unless dir == '.'
|
47
|
+
File.open(filename, 'w') do |file|
|
48
|
+
raw = case contents
|
49
|
+
when Hash
|
50
|
+
JSON.pretty_generate(contents)
|
51
|
+
when Array
|
52
|
+
contents.join("\n")
|
53
|
+
else
|
54
|
+
contents
|
55
|
+
end
|
56
|
+
file.write(raw)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def symlink(relative_path, relative_dest)
|
61
|
+
filename = path_to(relative_path)
|
62
|
+
dir = File.dirname(filename)
|
63
|
+
FileUtils.mkdir_p(dir) unless dir == '.'
|
64
|
+
dest_filename = path_to(relative_dest)
|
65
|
+
File.symlink(dest_filename, filename)
|
66
|
+
end
|
67
|
+
|
68
|
+
def path_to(relative_path)
|
69
|
+
File.expand_path(relative_path, (@parent_path || @repository_dir))
|
70
|
+
end
|
71
|
+
|
72
|
+
def cwd(relative_path)
|
73
|
+
@old_cwd = Dir.pwd
|
74
|
+
Dir.chdir(path_to(relative_path))
|
75
|
+
end
|
76
|
+
|
77
|
+
module WhenTheRepositoryClassMethods
|
78
|
+
def directory(*args, &block)
|
79
|
+
before :each do
|
80
|
+
directory(*args, &block)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def file(*args, &block)
|
85
|
+
before :each do
|
86
|
+
file(*args, &block)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def symlink(*args, &block)
|
91
|
+
before :each do
|
92
|
+
symlink(*args, &block)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def path_to(*args, &block)
|
97
|
+
before :each do
|
98
|
+
file(*args, &block)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -2,14 +2,26 @@ require 'chef_zero/rspec'
|
|
2
2
|
require 'chef/server_api'
|
3
3
|
require 'cheffish'
|
4
4
|
require 'cheffish/basic_chef_client'
|
5
|
+
require 'chef/provider/chef_acl'
|
6
|
+
require 'uri'
|
7
|
+
require 'support/repository_support'
|
5
8
|
|
6
9
|
module SpecSupport
|
7
10
|
include ChefZero::RSpec
|
8
11
|
|
9
12
|
def self.extended(klass)
|
10
13
|
klass.class_eval do
|
11
|
-
|
12
|
-
|
14
|
+
extend RepositorySupport
|
15
|
+
|
16
|
+
def rest
|
17
|
+
Chef::ServerAPI.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(path, *args)
|
21
|
+
if path[0] == '/'
|
22
|
+
path = URI.join(rest.url, path)
|
23
|
+
end
|
24
|
+
rest.get(path, *args)
|
13
25
|
end
|
14
26
|
|
15
27
|
def chef_run
|
@@ -111,6 +123,47 @@ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
|
|
111
123
|
end
|
112
124
|
end
|
113
125
|
|
126
|
+
RSpec::Matchers.define :update_acls do |acl_paths, expected_acls|
|
127
|
+
|
128
|
+
errors = []
|
129
|
+
|
130
|
+
match do |block|
|
131
|
+
orig_json = {}
|
132
|
+
Array(acl_paths).each do |acl_path|
|
133
|
+
orig_json[acl_path] = get(acl_path)
|
134
|
+
end
|
135
|
+
|
136
|
+
block.call
|
137
|
+
|
138
|
+
orig_json.each_pair do |acl_path, orig|
|
139
|
+
changed = get(acl_path)
|
140
|
+
expected_acls.each do |permission, hash|
|
141
|
+
hash.each do |type, actors|
|
142
|
+
actors.each do |actor|
|
143
|
+
if actor[0] == '-'
|
144
|
+
actor = actor[1..-1]
|
145
|
+
errors << "#{acl_path} expected to remove #{type} #{actor} from #{permission} permissions" if changed[permission][type].include?(actor)
|
146
|
+
orig[permission][type].delete(actor)
|
147
|
+
else
|
148
|
+
errors << "#{acl_path} expected to add #{type} #{actor} to #{permission} permissions" if !changed[permission][type].include?(actor)
|
149
|
+
changed[permission][type].delete(actor)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
# After checking everything, see if the remaining acl is the same as before
|
155
|
+
errors << "#{acl_path} updated more than expected!\nActual:\n#{changed}\nExpected:\n#{orig}" if changed != orig
|
156
|
+
end
|
157
|
+
errors.size == 0
|
158
|
+
end
|
159
|
+
|
160
|
+
failure_message do |block|
|
161
|
+
errors.join("\n")
|
162
|
+
end
|
163
|
+
|
164
|
+
supports_block_expectations
|
165
|
+
end
|
166
|
+
|
114
167
|
RSpec.configure do |config|
|
115
168
|
config.filter_run :focus => true
|
116
169
|
config.run_all_when_everything_filtered = true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheffish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.8'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '11.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '11.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: chef-zero
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,10 +79,14 @@ files:
|
|
79
79
|
- Rakefile
|
80
80
|
- lib/chef/provider/chef_acl.rb
|
81
81
|
- lib/chef/provider/chef_client.rb
|
82
|
+
- lib/chef/provider/chef_container.rb
|
82
83
|
- lib/chef/provider/chef_data_bag.rb
|
83
84
|
- lib/chef/provider/chef_data_bag_item.rb
|
84
85
|
- lib/chef/provider/chef_environment.rb
|
86
|
+
- lib/chef/provider/chef_group.rb
|
87
|
+
- lib/chef/provider/chef_mirror.rb
|
85
88
|
- lib/chef/provider/chef_node.rb
|
89
|
+
- lib/chef/provider/chef_organization.rb
|
86
90
|
- lib/chef/provider/chef_resolved_cookbooks.rb
|
87
91
|
- lib/chef/provider/chef_role.rb
|
88
92
|
- lib/chef/provider/chef_user.rb
|
@@ -90,14 +94,17 @@ files:
|
|
90
94
|
- lib/chef/provider/public_key.rb
|
91
95
|
- lib/chef/resource/chef_acl.rb
|
92
96
|
- lib/chef/resource/chef_client.rb
|
97
|
+
- lib/chef/resource/chef_container.rb
|
93
98
|
- lib/chef/resource/chef_data_bag.rb
|
94
99
|
- lib/chef/resource/chef_data_bag_item.rb
|
95
100
|
- lib/chef/resource/chef_environment.rb
|
101
|
+
- lib/chef/resource/chef_group.rb
|
102
|
+
- lib/chef/resource/chef_mirror.rb
|
96
103
|
- lib/chef/resource/chef_node.rb
|
104
|
+
- lib/chef/resource/chef_organization.rb
|
97
105
|
- lib/chef/resource/chef_resolved_cookbooks.rb
|
98
106
|
- lib/chef/resource/chef_role.rb
|
99
107
|
- lib/chef/resource/chef_user.rb
|
100
|
-
- lib/chef/resource/in_parallel.rb
|
101
108
|
- lib/chef/resource/private_key.rb
|
102
109
|
- lib/chef/resource/public_key.rb
|
103
110
|
- lib/cheffish.rb
|
@@ -113,12 +120,19 @@ files:
|
|
113
120
|
- lib/cheffish/version.rb
|
114
121
|
- lib/cheffish/with_pattern.rb
|
115
122
|
- spec/functional/fingerprint_spec.rb
|
123
|
+
- spec/functional/merged_config_spec.rb
|
124
|
+
- spec/integration/chef_acl_spec.rb
|
116
125
|
- spec/integration/chef_client_spec.rb
|
126
|
+
- spec/integration/chef_container_spec.rb
|
127
|
+
- spec/integration/chef_group_spec.rb
|
128
|
+
- spec/integration/chef_mirror_spec.rb
|
117
129
|
- spec/integration/chef_node_spec.rb
|
130
|
+
- spec/integration/chef_organization_spec.rb
|
118
131
|
- spec/integration/chef_user_spec.rb
|
119
132
|
- spec/integration/private_key_spec.rb
|
120
133
|
- spec/integration/recipe_dsl_spec.rb
|
121
134
|
- spec/support/key_support.rb
|
135
|
+
- spec/support/repository_support.rb
|
122
136
|
- spec/support/spec_support.rb
|
123
137
|
- spec/unit/get_private_key_spec.rb
|
124
138
|
homepage: http://wiki.opscode.com/display/chef
|