summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2018-03-12 12:36:14 -0700
committerGitHub <noreply@github.com>2018-03-12 12:36:14 -0700
commit797fe20ea3b529a36dc6a88e6101d3544b9ecb70 (patch)
tree23213fffe8302dda586746fc2c16412bfc3193b0
parentde0ed26e4b0a42f3af827912339ecae65253b52b (diff)
parent2e94dd8d733b9bae92228f4eca2dcdb0c58594c3 (diff)
downloadchef-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--.gitignore2
-rw-r--r--lib/chef/exceptions.rb2
-rw-r--r--lib/chef/knife.rb2
-rw-r--r--lib/chef/server_api.rb16
-rw-r--r--spec/unit/server_api_spec.rb30
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