diff options
author | Tim Smith <tsmith@chef.io> | 2018-03-12 12:36:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-12 12:36:14 -0700 |
commit | 797fe20ea3b529a36dc6a88e6101d3544b9ecb70 (patch) | |
tree | 23213fffe8302dda586746fc2c16412bfc3193b0 | |
parent | de0ed26e4b0a42f3af827912339ecae65253b52b (diff) | |
parent | 2e94dd8d733b9bae92228f4eca2dcdb0c58594c3 (diff) | |
download | chef-797fe20ea3b529a36dc6a88e6101d3544b9ecb70.tar.gz |
Merge pull request #6253 from jeunito/feat/5556
Knife should give a useful error when the chef_server_url isn't a chef server API
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | lib/chef/exceptions.rb | 2 | ||||
-rw-r--r-- | lib/chef/knife.rb | 2 | ||||
-rw-r--r-- | lib/chef/server_api.rb | 16 | ||||
-rw-r--r-- | spec/unit/server_api_spec.rb | 30 |
5 files changed, 52 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index 71f9cce719..5cbf0c66eb 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,8 @@ vendor/ acceptance/vendor kitchen-tests/vendor +*.swp + # Visual Studio Code files .vscode diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index 1ed71d2a55..cd825895b0 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -521,5 +521,7 @@ This error is most often caused by network issues (proxies, etc) outside of chef # exception specific to invalid usage of 'dsc_resource' resource class DSCModuleNameMissing < ArgumentError; end + + class NotAChefServerException < ArgumentError; end end end diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb index 4e975c2b27..49b4b50cd7 100644 --- a/lib/chef/knife.rb +++ b/lib/chef/knife.rb @@ -475,6 +475,8 @@ class Chef when Chef::Exceptions::InvalidRedirect ui.error "Invalid Redirect: #{e.message}" ui.info "Change your server location in knife.rb to the server's FQDN to avoid unwanted redirections." + when Chef::Exceptions::NotAChefServerException + ui.error "#{Chef::Config[:chef_server_url]} is not a valid chef server" else ui.error "#{e.class.name}: #{e.message}" end diff --git a/lib/chef/server_api.rb b/lib/chef/server_api.rb index c501544954..d539ed5fed 100644 --- a/lib/chef/server_api.rb +++ b/lib/chef/server_api.rb @@ -25,6 +25,7 @@ require "chef/http/json_output" require "chef/http/remote_request_id" require "chef/http/validate_content_length" require "chef/http/api_versions" +require "ffi_yajl" class Chef class ServerAPI < Chef::HTTP @@ -57,6 +58,21 @@ class Chef alias :post_rest :post alias :put_rest :put + def get(path, headers = {}) + request(:GET, path, headers) + rescue Net::HTTPServerException => e + if e.response.kind_of?(Net::HTTPNotFound) + begin + FFI_Yajl::Parser.parse(e.response.body) + rescue FFI_Yajl::ParseError => e + raise Chef::Exceptions::NotAChefServerException + end + raise + else + raise + end + end + # Makes an HTTP request to +path+ with the given +method+, +headers+, and # +data+ (if applicable). Does not apply any middleware, besides that # needed for Authentication. diff --git a/spec/unit/server_api_spec.rb b/spec/unit/server_api_spec.rb index 3f1d9b0e90..c64f42d358 100644 --- a/spec/unit/server_api_spec.rb +++ b/spec/unit/server_api_spec.rb @@ -58,6 +58,36 @@ describe Chef::ServerAPI do end end + describe "#get" do + context "when response is 404" do + context "body data is not json" do + it "throws not a Chef server exception" do + net_http_not_found = double() + allow(net_http_not_found).to receive(:kind_of?).and_return(Net::HTTPNotFound) + allow(net_http_not_found).to receive(:body).and_return("Not Found") + + api = described_class.new(url, raw_key: SIGNING_KEY_DOT_PEM) + allow(api).to receive(:request).and_raise(Net::HTTPServerException.new("", net_http_not_found)) + + expect { api.get("/nodes") }.to raise_error(Chef::Exceptions::NotAChefServerException) + end + end + + context "body data is json" do + it "bubbles up Exception" do + net_http_not_found = double() + allow(net_http_not_found).to receive(:kind_of?).and_return(Net::HTTPNotFound) + allow(net_http_not_found).to receive(:body).and_return("{}") + + api = described_class.new(url, raw_key: SIGNING_KEY_DOT_PEM) + allow(api).to receive(:request).and_raise(Net::HTTPServerException.new("", net_http_not_found)) + + expect { api.get("/nodes") }.to raise_error(Net::HTTPServerException) + end + end + end + end + context "versioned apis" do class VersionedClassV0 extend Chef::Mixin::VersionedAPI |