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.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/README.md +4 -0
- data/Rakefile +23 -0
- data/lib/chef/provider/chef_acl.rb +434 -0
- data/lib/chef/provider/chef_client.rb +48 -0
- data/lib/chef/provider/chef_container.rb +50 -0
- data/lib/chef/provider/chef_data_bag.rb +50 -0
- data/lib/chef/provider/chef_data_bag_item.rb +273 -0
- data/lib/chef/provider/chef_environment.rb +78 -0
- data/lib/chef/provider/chef_group.rb +78 -0
- data/lib/chef/provider/chef_mirror.rb +138 -0
- data/lib/chef/provider/chef_node.rb +82 -0
- data/lib/chef/provider/chef_organization.rb +150 -0
- data/lib/chef/provider/chef_resolved_cookbooks.rb +41 -0
- data/lib/chef/provider/chef_role.rb +79 -0
- data/lib/chef/provider/chef_user.rb +53 -0
- data/lib/chef/provider/private_key.rb +219 -0
- data/lib/chef/provider/public_key.rb +82 -0
- data/lib/chef/resource/chef_acl.rb +65 -0
- data/lib/chef/resource/chef_client.rb +44 -0
- data/lib/chef/resource/chef_container.rb +18 -0
- data/lib/chef/resource/chef_data_bag.rb +18 -0
- data/lib/chef/resource/chef_data_bag_item.rb +114 -0
- data/lib/chef/resource/chef_environment.rb +71 -0
- data/lib/chef/resource/chef_group.rb +49 -0
- data/lib/chef/resource/chef_mirror.rb +47 -0
- data/lib/chef/resource/chef_node.rb +18 -0
- data/lib/chef/resource/chef_organization.rb +64 -0
- data/lib/chef/resource/chef_resolved_cookbooks.rb +31 -0
- data/lib/chef/resource/chef_role.rb +104 -0
- data/lib/chef/resource/chef_user.rb +51 -0
- data/lib/chef/resource/private_key.rb +44 -0
- data/lib/chef/resource/public_key.rb +21 -0
- data/lib/cheffish.rb +222 -0
- data/lib/cheffish/actor_provider_base.rb +131 -0
- data/lib/cheffish/basic_chef_client.rb +115 -0
- data/lib/cheffish/chef_provider_base.rb +231 -0
- data/lib/cheffish/chef_run_data.rb +19 -0
- data/lib/cheffish/chef_run_listener.rb +28 -0
- data/lib/cheffish/key_formatter.rb +109 -0
- data/lib/cheffish/merged_config.rb +94 -0
- data/lib/cheffish/recipe_dsl.rb +147 -0
- data/lib/cheffish/server_api.rb +52 -0
- data/lib/cheffish/version.rb +3 -0
- data/lib/cheffish/with_pattern.rb +21 -0
- data/spec/functional/fingerprint_spec.rb +64 -0
- 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 +110 -0
- 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 +211 -0
- data/spec/integration/chef_organization_spec.rb +244 -0
- data/spec/integration/chef_user_spec.rb +90 -0
- data/spec/integration/private_key_spec.rb +446 -0
- data/spec/integration/recipe_dsl_spec.rb +29 -0
- data/spec/support/key_support.rb +29 -0
- data/spec/support/repository_support.rb +103 -0
- data/spec/support/spec_support.rb +176 -0
- data/spec/unit/get_private_key_spec.rb +93 -0
- 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
|