summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-12-11 12:23:02 -0800
committerJohn Keiser <john@johnkeiser.com>2015-12-15 13:01:32 -0800
commitd3c9bd4ba2578c967382703b30a6e8f64afbf7e0 (patch)
tree7dd2497530e13c7e85649596a6b762e38d89aaf7
parentdeefee3fda85fff400e38e62d7e70fc4e1aee86d (diff)
downloadchef-d3c9bd4ba2578c967382703b30a6e8f64afbf7e0.tar.gz
If /policies and /policy_groups are not on this server version,
treat them like empty directories
-rw-r--r--lib/chef/chef_fs/file_system/policies_dir.rb15
-rw-r--r--lib/chef/chef_fs/file_system/rest_list_dir.rb44
2 files changed, 57 insertions, 2 deletions
diff --git a/lib/chef/chef_fs/file_system/policies_dir.rb b/lib/chef/chef_fs/file_system/policies_dir.rb
index 9edaf7cf0a..a999ca0218 100644
--- a/lib/chef/chef_fs/file_system/policies_dir.rb
+++ b/lib/chef/chef_fs/file_system/policies_dir.rb
@@ -83,7 +83,20 @@ class Chef
rescue Net::HTTPServerException => e
# 404 = NotFoundError
if $!.response.code == "404"
- raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ # GET /organizations/ORG/policies returned 404, but that just might be because
+ # we are talking to an older version of the server that doesn't support policies.
+ # Do GET /orgqanizations/ORG to find out if the org exists at all.
+ # TODO use server API version instead of a second network request.
+ begin
+ root.get_json(parent.api_path)
+ # Return empty list if the organization exists but /policies didn't work
+ []
+ rescue Net::HTTPServerException => e
+ if e.response.code == "404"
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
+ raise Chef::ChefFS::FileSystem::OperationFailedError.new(:children, self, e, "HTTP error retrieving children: #{e}")
+ end
# Anything else is unexpected (OperationFailedError)
else
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:children, self, e, "HTTP error retrieving children: #{e}")
diff --git a/lib/chef/chef_fs/file_system/rest_list_dir.rb b/lib/chef/chef_fs/file_system/rest_list_dir.rb
index 4c520aa71a..1190069035 100644
--- a/lib/chef/chef_fs/file_system/rest_list_dir.rb
+++ b/lib/chef/chef_fs/file_system/rest_list_dir.rb
@@ -38,6 +38,29 @@ class Chef
end
#
+ # When talking to a modern (12.0+) Chef server
+ # knife list /
+ # -> /nodes
+ # -> /policies
+ # -> /policy_groups
+ # -> /roles
+ #
+ # 12.0 or 12.1 will fail when you do this:
+ # knife list / --recursive
+ # Because it thinks /policies exists, and when it tries to list its children
+ # it gets a 404 (indicating it actually doesn't exist).
+ #
+ # With this change, knife list / --recursive will list /policies as a real, empty directory.
+ #
+ # Alternately, we could have done some sort of detection when we listed the top level
+ # and determined which endpoints the server would support, and returned only those.
+ # So you wouldn't see /policies in that case at all.
+ # The issue with that is there's no efficient way to do it because we can't find out
+ # the server version directly, and can't ask the server for a list of the endpoints it supports.
+ #
+
+
+ #
# Does GET /<api_path>, assumes the result is of the format:
#
# {
@@ -58,7 +81,26 @@ class Chef
rescue Net::HTTPServerException => e
# 404 = NotFoundError
if $!.response.code == "404"
- raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+
+ if parent.is_a?(ChefServerRootDir)
+ # GET /organizations/ORG/<container> returned 404, but that just might be because
+ # we are talking to an older version of the server that doesn't support policies.
+ # Do GET /orgqanizations/ORG to find out if the org exists at all.
+ # TODO use server API version instead of a second network request.
+ begin
+ root.get_json(parent.api_path)
+ # Return empty list if the organization exists but /policies didn't work
+ []
+ rescue Net::HTTPServerException => e
+ if e.response.code == "404"
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
+ raise Chef::ChefFS::FileSystem::OperationFailedError.new(:children, self, e, "HTTP error retrieving children: #{e}")
+ end
+ else
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
+
# Anything else is unexpected (OperationFailedError)
else
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:children, self, e, "HTTP error retrieving children: #{e}")