knife-essentials 1.5.3 → 1.5.4
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.
- data/lib/chef/knife/raw_essentials.rb +7 -1
- data/lib/chef_fs/file_system.rb +2 -2
- data/lib/chef_fs/file_system/chef_repository_file_system_root_dir.rb +1 -1
- data/lib/chef_fs/file_system/cookbooks_dir.rb +1 -0
- data/lib/chef_fs/file_system/data_bags_dir.rb +1 -0
- data/lib/chef_fs/file_system/file_system_entry.rb +5 -4
- data/lib/chef_fs/file_system/multiplexed_dir.rb +1 -0
- data/lib/chef_fs/file_system/operation_failed_error.rb +8 -0
- data/lib/chef_fs/file_system/rest_list_dir.rb +2 -0
- data/lib/chef_fs/raw_request.rb +12 -8
- data/lib/chef_fs/version.rb +1 -1
- data/spec/chef_fs/file_system/operation_failed_error_spec.rb +47 -0
- data/spec/integration/download_spec.rb +9 -0
- data/spec/integration/raw_spec.rb +63 -0
- data/spec/integration/upload_spec.rb +11 -4
- metadata +3 -3
- data/spec/integration/converge_spec.rb +0 -75
@@ -48,7 +48,13 @@ class Chef
|
|
48
48
|
end
|
49
49
|
chef_rest = Chef::REST.new(Chef::Config[:chef_server_url])
|
50
50
|
begin
|
51
|
-
|
51
|
+
method = config[:method].to_sym
|
52
|
+
url = chef_rest.create_url(name_args[0])
|
53
|
+
result = ::ChefFS::RawRequest.api_request(chef_rest, method, url, {}, data, :parse_json => config[:pretty])
|
54
|
+
if result.is_a?(Hash) || result.is_a?(Array)
|
55
|
+
result = Chef::JSONCompat.to_json_pretty(result)
|
56
|
+
end
|
57
|
+
output result
|
52
58
|
rescue Timeout::Error => e
|
53
59
|
ui.error "Server timeout"
|
54
60
|
exit 1
|
data/lib/chef_fs/file_system.rb
CHANGED
@@ -288,7 +288,7 @@ module ChefFS
|
|
288
288
|
ui.output "Deleted extra entry #{dest_path} (purge is on)" if ui
|
289
289
|
end
|
290
290
|
else
|
291
|
-
|
291
|
+
ui.output ("Not deleting extra entry #{dest_path} (purge is off)") if ui
|
292
292
|
end
|
293
293
|
end
|
294
294
|
|
@@ -406,7 +406,7 @@ module ChefFS
|
|
406
406
|
parent = entry.parent
|
407
407
|
if parent && !parent.exists?
|
408
408
|
parent_path = format_path.call(parent) if ui
|
409
|
-
parent_parent = get_or_create_parent(
|
409
|
+
parent_parent = get_or_create_parent(parent, options, ui, format_path)
|
410
410
|
if options[:dry_run]
|
411
411
|
ui.output "Would create #{parent_path}" if ui
|
412
412
|
else
|
@@ -46,13 +46,14 @@ module ChefFS
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def create_child(child_name, file_contents=nil)
|
49
|
-
|
49
|
+
child = FileSystemEntry.new(child_name, self)
|
50
50
|
if file_contents
|
51
|
-
|
51
|
+
child.write(file_contents)
|
52
52
|
else
|
53
|
-
Dir.mkdir(
|
53
|
+
Dir.mkdir(child.file_path)
|
54
54
|
end
|
55
|
-
|
55
|
+
@children = nil
|
56
|
+
child
|
56
57
|
end
|
57
58
|
|
58
59
|
def dir?
|
@@ -26,6 +26,14 @@ module ChefFS
|
|
26
26
|
@operation = operation
|
27
27
|
end
|
28
28
|
|
29
|
+
def message
|
30
|
+
if cause && cause.is_a?(Net::HTTPExceptions) && cause.response.code == "400"
|
31
|
+
"#{super} cause: #{cause.response.body}"
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
29
37
|
attr_reader :operation
|
30
38
|
end
|
31
39
|
end
|
data/lib/chef_fs/raw_request.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module ChefFS
|
2
2
|
module RawRequest
|
3
3
|
def self.raw_json(chef_rest, api_path)
|
4
|
-
|
4
|
+
api_request(chef_rest, :GET, chef_rest.create_url(api_path), {}, nil, :parse_json => true)
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.raw_request(chef_rest, api_path)
|
8
|
-
api_request(chef_rest, :GET, chef_rest.create_url(api_path)
|
8
|
+
api_request(chef_rest, :GET, chef_rest.create_url(api_path))
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.api_request(chef_rest, method, url, headers={}, data=
|
12
|
-
json_body = data
|
11
|
+
def self.api_request(chef_rest, method, url, headers={}, data=nil, options = {})
|
12
|
+
json_body = data || nil
|
13
13
|
# json_body = data ? Chef::JSONCompat.to_json(data) : nil
|
14
14
|
# Force encoding to binary to fix SSL related EOFErrors
|
15
15
|
# cf. http://tickets.opscode.com/browse/CHEF-2363
|
@@ -23,11 +23,15 @@ module ChefFS
|
|
23
23
|
response_body = chef_rest.decompress_body(response)
|
24
24
|
|
25
25
|
if response.kind_of?(Net::HTTPSuccess)
|
26
|
-
|
26
|
+
if options[:parse_json] && response['content-type'] =~ /json/
|
27
|
+
JSON.parse(response_body, :create_additions => false)
|
28
|
+
else
|
29
|
+
response_body
|
30
|
+
end
|
27
31
|
elsif redirect_location = redirected_to(response)
|
28
32
|
if [:GET, :HEAD].include?(method)
|
29
33
|
chef_rest.follow_redirect do
|
30
|
-
api_request(chef_rest, method, chef_rest.create_url(redirect_location))
|
34
|
+
api_request(chef_rest, method, chef_rest.create_url(redirect_location), headers, nil, options)
|
31
35
|
end
|
32
36
|
else
|
33
37
|
raise Exceptions::InvalidRedirect, "#{method} request was redirected from #{url} to #{redirect_location}. Only GET and HEAD support redirects."
|
@@ -62,11 +66,11 @@ module ChefFS
|
|
62
66
|
response['location']
|
63
67
|
end
|
64
68
|
|
65
|
-
def self.build_headers(chef_rest, method, url, headers={}, json_body=
|
69
|
+
def self.build_headers(chef_rest, method, url, headers={}, json_body=nil, raw=nil)
|
66
70
|
# headers = @default_headers.merge(headers)
|
67
71
|
#headers['Accept'] = "application/json" unless raw
|
68
72
|
headers['Accept'] = "application/json" unless raw
|
69
|
-
headers[
|
73
|
+
headers['Content-Type'] = 'application/json' if json_body
|
70
74
|
headers['Content-Length'] = json_body.bytesize.to_s if json_body
|
71
75
|
headers[Chef::REST::RESTRequest::ACCEPT_ENCODING] = Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE
|
72
76
|
headers.merge!(chef_rest.authentication_headers(method, url, json_body)) if chef_rest.sign_requests?
|
data/lib/chef_fs/version.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Author:: John Keiser (<jkeiser@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2012 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'support/spec_helper'
|
20
|
+
require 'chef_fs/file_system/operation_failed_error'
|
21
|
+
|
22
|
+
describe ChefFS::FileSystem::OperationFailedError do
|
23
|
+
context 'message' do
|
24
|
+
let(:error_message) { 'HTTP error writing: 400 "Bad Request"' }
|
25
|
+
|
26
|
+
context 'has a cause attribute and HTTP result code is 400' do
|
27
|
+
it 'include error cause' do
|
28
|
+
allow_message_expectations_on_nil
|
29
|
+
response_body = '{"error":["Invalid key test in request body"]}'
|
30
|
+
@response.stub(:code).and_return("400")
|
31
|
+
@response.stub(:body).and_return(response_body)
|
32
|
+
exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
|
33
|
+
proc {
|
34
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:write, self, exception), error_message
|
35
|
+
}.should raise_error(ChefFS::FileSystem::OperationFailedError, "#{error_message} cause: #{response_body}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'does not have a cause attribute' do
|
40
|
+
it 'does not include error cause' do
|
41
|
+
proc {
|
42
|
+
raise ChefFS::FileSystem::OperationFailedError.new(:write, self), error_message
|
43
|
+
}.should raise_error(ChefFS::FileSystem::OperationFailedError, error_message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -239,6 +239,15 @@ Created /data_bags/x/y.json
|
|
239
239
|
EOM
|
240
240
|
knife('diff --name-status /data_bags').should_succeed <<EOM
|
241
241
|
D\t/data_bags/x/z.json
|
242
|
+
EOM
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'knife download /data_bags/x /data_bags/x/y.json downloads x once' do
|
246
|
+
knife('download /data_bags/x /data_bags/x/y.json').should_succeed <<EOM
|
247
|
+
Created /data_bags
|
248
|
+
Created /data_bags/x
|
249
|
+
Created /data_bags/x/y.json
|
250
|
+
Created /data_bags/x/z.json
|
242
251
|
EOM
|
243
252
|
end
|
244
253
|
end
|
@@ -142,6 +142,69 @@ EOM
|
|
142
142
|
"name": "y",
|
143
143
|
"description": "eek"
|
144
144
|
}
|
145
|
+
EOM
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'When a server returns raw json' do
|
150
|
+
before :each do
|
151
|
+
@real_chef_server_url = Chef::Config.chef_server_url
|
152
|
+
Chef::Config.chef_server_url = "http://127.0.0.1:9018"
|
153
|
+
app = lambda do |env|
|
154
|
+
[200, {'Content-Type' => 'application/json' }, ['{ "x": "y", "a": "b" }'] ]
|
155
|
+
end
|
156
|
+
@raw_server = Puma::Server.new(app, Puma::Events.new(STDERR, STDOUT))
|
157
|
+
@raw_server.add_tcp_listener("127.0.0.1", 9018)
|
158
|
+
@raw_server.run
|
159
|
+
end
|
160
|
+
|
161
|
+
after :each do
|
162
|
+
Chef::Config.chef_server_url = @real_chef_server_url
|
163
|
+
@raw_server.stop(true)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'knife raw /blah returns the prettified json', :pending => (RUBY_VERSION < "1.9") do
|
167
|
+
knife('raw /blah').should_succeed <<EOM
|
168
|
+
{
|
169
|
+
"x": "y",
|
170
|
+
"a": "b"
|
171
|
+
}
|
172
|
+
EOM
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'knife raw --no-pretty /blah returns the raw json' do
|
176
|
+
knife('raw --no-pretty /blah').should_succeed <<EOM
|
177
|
+
{ "x": "y", "a": "b" }
|
178
|
+
EOM
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'When a server returns text' do
|
183
|
+
before :each do
|
184
|
+
@real_chef_server_url = Chef::Config.chef_server_url
|
185
|
+
Chef::Config.chef_server_url = "http://127.0.0.1:9018"
|
186
|
+
app = lambda do |env|
|
187
|
+
[200, {'Content-Type' => 'text' }, ['{ "x": "y", "a": "b" }'] ]
|
188
|
+
end
|
189
|
+
@raw_server = Puma::Server.new(app, Puma::Events.new(STDERR, STDOUT))
|
190
|
+
@raw_server.add_tcp_listener("127.0.0.1", 9018)
|
191
|
+
@raw_server.run
|
192
|
+
end
|
193
|
+
|
194
|
+
after :each do
|
195
|
+
Chef::Config.chef_server_url = @real_chef_server_url
|
196
|
+
@raw_server.stop(true)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'knife raw /blah returns the raw text' do
|
200
|
+
knife('raw /blah').should_succeed <<EOM
|
201
|
+
{ "x": "y", "a": "b" }
|
202
|
+
EOM
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'knife raw --no-pretty /blah returns the raw text' do
|
206
|
+
knife('raw --no-pretty /blah').should_succeed <<EOM
|
207
|
+
{ "x": "y", "a": "b" }
|
145
208
|
EOM
|
146
209
|
end
|
147
210
|
end
|
@@ -41,10 +41,10 @@ D\t/roles/x.json
|
|
41
41
|
D\t/users/admin.json
|
42
42
|
D\t/users/x.json
|
43
43
|
EOM
|
44
|
-
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
it 'knife upload --purge deletes everything' do
|
47
|
+
knife('upload --purge /').should_succeed(<<EOM, :stderr => "WARNING: /environments/_default.json cannot be deleted (default environment cannot be modified).\n")
|
48
48
|
Deleted extra entry /clients/chef-validator.json (purge is on)
|
49
49
|
Deleted extra entry /clients/chef-webui.json (purge is on)
|
50
50
|
Deleted extra entry /clients/x.json (purge is on)
|
@@ -59,7 +59,7 @@ EOM
|
|
59
59
|
knife('diff --name-status /').should_succeed <<EOM
|
60
60
|
D\t/environments/_default.json
|
61
61
|
EOM
|
62
|
-
|
62
|
+
end
|
63
63
|
end
|
64
64
|
|
65
65
|
when_the_repository 'has an identical copy of each thing' do
|
@@ -222,6 +222,13 @@ EOM
|
|
222
222
|
EOM
|
223
223
|
JSON.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort.should == [ 'foo', 'id' ]
|
224
224
|
end
|
225
|
+
|
226
|
+
it 'knife upload /data_bags/x /data_bags/x/y.json uploads x once' do
|
227
|
+
knife('upload /data_bags/x /data_bags/x/y.json').should_succeed <<EOM
|
228
|
+
Created /data_bags/x
|
229
|
+
Created /data_bags/x/y.json
|
230
|
+
EOM
|
231
|
+
end
|
225
232
|
end
|
226
233
|
|
227
234
|
when_the_repository 'has a data bag item with keys chef_type and data_bag' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-essentials
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chef
|
@@ -192,12 +192,12 @@ files:
|
|
192
192
|
- lib/chef_fs.rb
|
193
193
|
- spec/chef_fs/diff_spec.rb
|
194
194
|
- spec/chef_fs/file_pattern_spec.rb
|
195
|
+
- spec/chef_fs/file_system/operation_failed_error_spec.rb
|
195
196
|
- spec/chef_fs/file_system_spec.rb
|
196
197
|
- spec/data/null_config.rb
|
197
198
|
- spec/integration/chef_repo_path_spec.rb
|
198
199
|
- spec/integration/chef_repository_file_system_spec.rb
|
199
200
|
- spec/integration/chefignore_spec.rb
|
200
|
-
- spec/integration/converge_spec.rb
|
201
201
|
- spec/integration/delete_spec.rb
|
202
202
|
- spec/integration/deps_spec.rb
|
203
203
|
- spec/integration/diff_spec.rb
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'support/integration_helper'
|
2
|
-
require 'chef/knife/converge_essentials'
|
3
|
-
|
4
|
-
describe 'knife converge' do
|
5
|
-
let(:sample_cookbook) do
|
6
|
-
return
|
7
|
-
end
|
8
|
-
|
9
|
-
when_the_repository 'has a cookbook' do
|
10
|
-
file 'cookbooks/x/recipes/default.rb', <<EOM
|
11
|
-
file #{path_to('x.txt')} do
|
12
|
-
content 'x::default'
|
13
|
-
end
|
14
|
-
EOM
|
15
|
-
file 'cookbooks/x/recipes/y.rb', <<EOM
|
16
|
-
file #{path_to('x.txt')} do
|
17
|
-
content 'x::y'
|
18
|
-
end
|
19
|
-
EOM
|
20
|
-
file 'cookbooks/x/recipes/fromrole.rb', <<EOM
|
21
|
-
file #{path_to('x.txt')} do
|
22
|
-
content 'x::fromrole'
|
23
|
-
end
|
24
|
-
EOM
|
25
|
-
file 'roles/r.json', { 'run_list' => [ 'recipe[x::r]' ] }
|
26
|
-
|
27
|
-
context 'and current directory is at the top of the repository' do
|
28
|
-
cwd '.'
|
29
|
-
it 'knife converge creates .chef/knife.rb' do
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'knife converge /cookbooks/x converges x::default' do
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'knife converge recipe[x] converges x::default' do
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'knife converge /cookbooks/x/recipes/y.rb converges x::y' do
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'knife converge recipe[x::y] converges x::y' do
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'knife converge /roles/ converges x::fromrole' do
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'knife converge role[r] converges x::fromrole' do
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'and current directory is cookbooks/x/default' do
|
52
|
-
cwd 'cookbooks/x/default'
|
53
|
-
|
54
|
-
it 'knife converge creates .chef/knife.rb' do
|
55
|
-
end
|
56
|
-
it 'knife converge y.rb converges x::y' do
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'and a .chef/knife.rb' do
|
61
|
-
it 'knife converge converges' do
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
when_the_repository 'has a cookbook' do
|
67
|
-
it 'knife converge with no arguments runs the node\'s run list' do
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
when_the_chef_server 'has cookbooks' do
|
72
|
-
it 'knife converge converges them' do
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|