diff options
-rw-r--r-- | lib/chef/api_client.rb | 161 | ||||
-rw-r--r-- | lib/chef/api_client_v1.rb | 339 | ||||
-rw-r--r-- | lib/chef/json_compat.rb | 3 | ||||
-rw-r--r-- | lib/chef/knife/client_bulk_delete.rb | 4 | ||||
-rw-r--r-- | lib/chef/knife/client_create.rb | 4 | ||||
-rw-r--r-- | lib/chef/knife/client_delete.rb | 6 | ||||
-rw-r--r-- | lib/chef/knife/client_edit.rb | 4 | ||||
-rw-r--r-- | lib/chef/knife/client_list.rb | 4 | ||||
-rw-r--r-- | lib/chef/knife/client_reregister.rb | 4 | ||||
-rw-r--r-- | lib/chef/knife/client_show.rb | 4 | ||||
-rw-r--r-- | spec/unit/api_client_spec.rb | 212 | ||||
-rw-r--r-- | spec/unit/api_client_v1_spec.rb | 523 | ||||
-rw-r--r-- | spec/unit/knife/client_bulk_delete_spec.rb | 8 | ||||
-rw-r--r-- | spec/unit/knife/client_create_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/knife/client_delete_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/knife/client_edit_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/knife/client_list_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/knife/client_reregister_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/knife/client_show_spec.rb | 4 |
19 files changed, 944 insertions, 352 deletions
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb index ad31fb7d7b..6fee78225f 100644 --- a/lib/chef/api_client.rb +++ b/lib/chef/api_client.rb @@ -1,7 +1,7 @@ # -# Author:: Adam Jacob (<adam@chef.io>) -# Author:: Nuo Yan (<nuo@chef.io>) -# Copyright:: Copyright (c) 2008, 2015 Chef Software, Inc. +# Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Nuo Yan (<nuo@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,18 +23,17 @@ require 'chef/mixin/from_file' require 'chef/mash' require 'chef/json_compat' require 'chef/search/query' -require 'chef/exceptions' -require 'chef/mixin/api_version_request_handling' -require 'chef/server_api' +# DEPRECATION NOTE +# +# This code will be removed in Chef 13 in favor of the code in Chef::ApiClientV1, +# which will be moved to this namespace. New development should occur in +# Chef::ApiClientV1 until the time before Chef 13. class Chef class ApiClient include Chef::Mixin::FromFile include Chef::Mixin::ParamsValidate - include Chef::Mixin::ApiVersionRequestHandling - - SUPPORTED_API_VERSIONS = [0,1] # Create a new Chef::ApiClient object. def initialize @@ -43,25 +42,6 @@ class Chef @private_key = nil @admin = false @validator = false - @create_key = nil - end - - def chef_rest_v0 - @chef_rest_v0 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "0"}) - end - - def chef_rest_v1 - @chef_rest_v1 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "1"}) - end - - # will default to the current version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION) - def http_api - @http_api ||= Chef::REST.new(Chef::Config[:chef_server_url]) - end - - # will default to the current version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION) - def self.http_api - Chef::REST.new(Chef::Config[:chef_server_url]) end # Gets or sets the client name. @@ -113,8 +93,7 @@ class Chef ) end - # Private key. The server will return it as a string. - # Set to true under API V0 to have the server regenerate the default key. + # Gets or sets the private key. # # @params [Optional String] The string representation of the private key. # @return [String] The current value. @@ -122,19 +101,7 @@ class Chef set_or_return( :private_key, arg, - :kind_of => [String, TrueClass, FalseClass] - ) - end - - # Used to ask server to generate key pair under api V1 - # - # @params [Optional True/False] Should be true or false - default is false. - # @return [True/False] The current value - def create_key(arg=nil) - set_or_return( - :create_key, - arg, - :kind_of => [ TrueClass, FalseClass ] + :kind_of => [String, FalseClass] ) end @@ -145,14 +112,13 @@ class Chef def to_hash result = { "name" => @name, + "public_key" => @public_key, "validator" => @validator, "admin" => @admin, 'json_class' => self.class.name, "chef_type" => "client" } - result["private_key"] = @private_key unless @private_key.nil? - result["public_key"] = @public_key unless @public_key.nil? - result["create_key"] = @create_key unless @create_key.nil? + result["private_key"] = @private_key if @private_key result end @@ -166,11 +132,10 @@ class Chef def self.from_hash(o) client = Chef::ApiClient.new client.name(o["name"] || o["clientname"]) + client.private_key(o["private_key"]) if o.key?("private_key") + client.public_key(o["public_key"]) client.admin(o["admin"]) client.validator(o["validator"]) - client.private_key(o["private_key"]) if o.key?("private_key") - client.public_key(o["public_key"]) if o.key?("public_key") - client.create_key(o["create_key"]) if o.key?("create_key") client end @@ -182,6 +147,10 @@ class Chef from_hash(Chef::JSONCompat.parse(j)) end + def self.http_api + Chef::REST.new(Chef::Config[:chef_server_url]) + end + def self.reregister(name) api_client = load(name) api_client.reregister @@ -218,11 +187,11 @@ class Chef # Save this client via the REST API, returns a hash including the private key def save begin - update + http_api.put("clients/#{name}", { :name => self.name, :admin => self.admin, :validator => self.validator}) rescue Net::HTTPServerException => e # If that fails, go ahead and try and update it if e.response.code == "404" - create + http_api.post("clients", {:name => self.name, :admin => self.admin, :validator => self.validator }) else raise e end @@ -230,95 +199,18 @@ class Chef end def reregister - # Try API V0 and if it fails due to V0 not being supported, raise the proper error message. - # reregister only supported in API V0 or lesser. - reregistered_self = chef_rest_v0.put("clients/#{name}", { :name => name, :admin => admin, :validator => validator, :private_key => true }) + reregistered_self = http_api.put("clients/#{name}", { :name => name, :admin => admin, :validator => validator, :private_key => true }) if reregistered_self.respond_to?(:[]) private_key(reregistered_self["private_key"]) else private_key(reregistered_self.private_key) end self - rescue Net::HTTPServerException => e - # if there was a 406 related to versioning, give error explaining that - # only API version 0 is supported for reregister command - if e.response.code == "406" && e.response["x-ops-server-api-version"] - version_header = Chef::JSONCompat.from_json(e.response["x-ops-server-api-version"]) - min_version = version_header["min_version"] - max_version = version_header["max_version"] - error_msg = reregister_only_v0_supported_error_msg(max_version, min_version) - raise Chef::Exceptions::OnlyApiVersion0SupportedForAction.new(error_msg) - else - raise e - end - end - - # Updates the client via the REST API - def update - # NOTE: API V1 dropped support for updating client keys via update (aka PUT), - # but this code never supported key updating in the first place. Since - # it was never implemented, we will simply ignore that functionality - # as it is being deprecated. - # Delete this comment after V0 support is dropped. - payload = { :name => name } - payload[:validator] = validator unless validator.nil? - - # DEPRECATION - # This field is ignored in API V1, but left for backwards-compat, - # can remove after API V0 is no longer supported. - payload[:admin] = admin unless admin.nil? - - begin - new_client = chef_rest_v1.put("clients/#{name}", payload) - rescue Net::HTTPServerException => e - # rescue API V0 if 406 and the server supports V0 - supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS) - raise e unless supported_versions && supported_versions.include?(0) - new_client = chef_rest_v0.put("clients/#{name}", payload) - end - - new_client end # Create the client via the REST API def create - payload = { - :name => name, - :validator => validator, - # this field is ignored in API V1, but left for backwards-compat, - # can remove after OSC 11 support is finished? - :admin => admin - } - begin - # try API V1 - raise Chef::Exceptions::InvalidClientAttribute, "You cannot set both public_key and create_key for create." if !create_key.nil? && !public_key.nil? - - payload[:public_key] = public_key unless public_key.nil? - payload[:create_key] = create_key unless create_key.nil? - - new_client = chef_rest_v1.post("clients", payload) - - # get the private_key out of the chef_key hash if it exists - if new_client['chef_key'] - if new_client['chef_key']['private_key'] - new_client['private_key'] = new_client['chef_key']['private_key'] - end - new_client['public_key'] = new_client['chef_key']['public_key'] - new_client.delete('chef_key') - end - - rescue Net::HTTPServerException => e - # rescue API V0 if 406 and the server supports V0 - supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS) - raise e unless supported_versions && supported_versions.include?(0) - - # under API V0, a key pair will always be created unless public_key is - # passed on initial POST - payload[:public_key] = public_key unless public_key.nil? - - new_client = chef_rest_v0.post("clients", payload) - end - Chef::ApiClient.from_hash(self.to_hash.merge(new_client)) + http_api.post("clients", self) end # As a string @@ -326,5 +218,14 @@ class Chef "client[#{@name}]" end + def inspect + "Chef::ApiClient name:'#{name}' admin:'#{admin.inspect}' validator:'#{validator}' " + + "public_key:'#{public_key}' private_key:'#{private_key}'" + end + + def http_api + @http_api ||= Chef::REST.new(Chef::Config[:chef_server_url]) + end + end end diff --git a/lib/chef/api_client_v1.rb b/lib/chef/api_client_v1.rb new file mode 100644 index 0000000000..25c40df7f0 --- /dev/null +++ b/lib/chef/api_client_v1.rb @@ -0,0 +1,339 @@ +# +# Author:: Adam Jacob (<adam@chef.io>) +# Author:: Nuo Yan (<nuo@chef.io>) +# Copyright:: Copyright (c) 2008, 2015 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef/config' +require 'chef/mixin/params_validate' +require 'chef/mixin/from_file' +require 'chef/mash' +require 'chef/json_compat' +require 'chef/search/query' +require 'chef/exceptions' +require 'chef/mixin/api_version_request_handling' +require 'chef/server_api' + +# COMPATIBILITY NOTE +# +# This ApiClientV1 code attempts to make API V1 requests and falls back to +# API V0 requests when it fails. New development should occur here instead +# of Chef::ApiClient as this will replace that namespace when Chef 13 is released. +# +# If you need to default to API V0 behavior (i.e. you need GET client to return +# a public key, etc), please use Chef::ApiClient and update your code to support +# API V1 before you pull in Chef 13. +class Chef + class ApiClientV1 + + include Chef::Mixin::FromFile + include Chef::Mixin::ParamsValidate + include Chef::Mixin::ApiVersionRequestHandling + + SUPPORTED_API_VERSIONS = [0,1] + + # Create a new Chef::ApiClientV1 object. + def initialize + @name = '' + @public_key = nil + @private_key = nil + @admin = false + @validator = false + @create_key = nil + end + + def chef_rest_v0 + @chef_rest_v0 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "0"}) + end + + def chef_rest_v1 + @chef_rest_v1 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "1"}) + end + + # will default to the current version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION) + def http_api + @http_api ||= Chef::REST.new(Chef::Config[:chef_server_url]) + end + + # will default to the current version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION) + def self.http_api + Chef::REST.new(Chef::Config[:chef_server_url]) + end + + # Gets or sets the client name. + # + # @params [Optional String] The name must be alpha-numeric plus - and _. + # @return [String] The current value of the name. + def name(arg=nil) + set_or_return( + :name, + arg, + :regex => /^[\-[:alnum:]_\.]+$/ + ) + end + + # Gets or sets whether this client is an admin. + # + # @params [Optional True/False] Should be true or false - default is false. + # @return [True/False] The current value + def admin(arg=nil) + set_or_return( + :admin, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + # Gets or sets the public key. + # + # @params [Optional String] The string representation of the public key. + # @return [String] The current value. + def public_key(arg=nil) + set_or_return( + :public_key, + arg, + :kind_of => String + ) + end + + # Gets or sets whether this client is a validator. + # + # @params [Boolean] whether or not the client is a validator. If + # `nil`, retrieves the already-set value. + # @return [Boolean] The current value + def validator(arg=nil) + set_or_return( + :validator, + arg, + :kind_of => [TrueClass, FalseClass] + ) + end + + # Private key. The server will return it as a string. + # Set to true under API V0 to have the server regenerate the default key. + # + # @params [Optional String] The string representation of the private key. + # @return [String] The current value. + def private_key(arg=nil) + set_or_return( + :private_key, + arg, + :kind_of => [String, TrueClass, FalseClass] + ) + end + + # Used to ask server to generate key pair under api V1 + # + # @params [Optional True/False] Should be true or false - default is false. + # @return [True/False] The current value + def create_key(arg=nil) + set_or_return( + :create_key, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + # The hash representation of the object. Includes the name and public_key. + # Private key is included if available. + # + # @return [Hash] + def to_hash + result = { + "name" => @name, + "validator" => @validator, + "admin" => @admin, + 'json_class' => self.class.name, + "chef_type" => "client" + } + result["private_key"] = @private_key unless @private_key.nil? + result["public_key"] = @public_key unless @public_key.nil? + result["create_key"] = @create_key unless @create_key.nil? + result + end + + # The JSON representation of the object. + # + # @return [String] the JSON string. + def to_json(*a) + Chef::JSONCompat.to_json(to_hash, *a) + end + + def self.from_hash(o) + client = Chef::ApiClientV1.new + client.name(o["name"] || o["clientname"]) + client.admin(o["admin"]) + client.validator(o["validator"]) + client.private_key(o["private_key"]) if o.key?("private_key") + client.public_key(o["public_key"]) if o.key?("public_key") + client.create_key(o["create_key"]) if o.key?("create_key") + client + end + + def self.json_create(data) + from_hash(data) + end + + def self.from_json(j) + from_hash(Chef::JSONCompat.parse(j)) + end + + def self.reregister(name) + api_client = load(name) + api_client.reregister + end + + def self.list(inflate=false) + if inflate + response = Hash.new + Chef::Search::Query.new.search(:client) do |n| + n = self.json_create(n) if n.instance_of?(Hash) + response[n.name] = n + end + response + else + http_api.get("clients") + end + end + + # Load a client by name via the API + def self.load(name) + response = http_api.get("clients/#{name}") + if response.kind_of?(Chef::ApiClientV1) + response + else + json_create(response) + end + end + + # Remove this client via the REST API + def destroy + http_api.delete("clients/#{@name}") + end + + # Save this client via the REST API, returns a hash including the private key + def save + begin + update + rescue Net::HTTPServerException => e + # If that fails, go ahead and try and update it + if e.response.code == "404" + create + else + raise e + end + end + end + + def reregister + # Try API V0 and if it fails due to V0 not being supported, raise the proper error message. + # reregister only supported in API V0 or lesser. + reregistered_self = chef_rest_v0.put("clients/#{name}", { :name => name, :admin => admin, :validator => validator, :private_key => true }) + if reregistered_self.respond_to?(:[]) + private_key(reregistered_self["private_key"]) + else + private_key(reregistered_self.private_key) + end + self + rescue Net::HTTPServerException => e + # if there was a 406 related to versioning, give error explaining that + # only API version 0 is supported for reregister command + if e.response.code == "406" && e.response["x-ops-server-api-version"] + version_header = Chef::JSONCompat.from_json(e.response["x-ops-server-api-version"]) + min_version = version_header["min_version"] + max_version = version_header["max_version"] + error_msg = reregister_only_v0_supported_error_msg(max_version, min_version) + raise Chef::Exceptions::OnlyApiVersion0SupportedForAction.new(error_msg) + else + raise e + end + end + + # Updates the client via the REST API + def update + # NOTE: API V1 dropped support for updating client keys via update (aka PUT), + # but this code never supported key updating in the first place. Since + # it was never implemented, we will simply ignore that functionality + # as it is being deprecated. + # Delete this comment after V0 support is dropped. + payload = { :name => name } + payload[:validator] = validator unless validator.nil? + + # DEPRECATION + # This field is ignored in API V1, but left for backwards-compat, + # can remove after API V0 is no longer supported. + payload[:admin] = admin unless admin.nil? + + begin + new_client = chef_rest_v1.put("clients/#{name}", payload) + rescue Net::HTTPServerException => e + # rescue API V0 if 406 and the server supports V0 + supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS) + raise e unless supported_versions && supported_versions.include?(0) + new_client = chef_rest_v0.put("clients/#{name}", payload) + end + + new_client + end + + # Create the client via the REST API + def create + payload = { + :name => name, + :validator => validator, + # this field is ignored in API V1, but left for backwards-compat, + # can remove after OSC 11 support is finished? + :admin => admin + } + begin + # try API V1 + raise Chef::Exceptions::InvalidClientAttribute, "You cannot set both public_key and create_key for create." if !create_key.nil? && !public_key.nil? + + payload[:public_key] = public_key unless public_key.nil? + payload[:create_key] = create_key unless create_key.nil? + + new_client = chef_rest_v1.post("clients", payload) + + # get the private_key out of the chef_key hash if it exists + if new_client['chef_key'] + if new_client['chef_key']['private_key'] + new_client['private_key'] = new_client['chef_key']['private_key'] + end + new_client['public_key'] = new_client['chef_key']['public_key'] + new_client.delete('chef_key') + end + + rescue Net::HTTPServerException => e + # rescue API V0 if 406 and the server supports V0 + supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS) + raise e unless supported_versions && supported_versions.include?(0) + + # under API V0, a key pair will always be created unless public_key is + # passed on initial POST + payload[:public_key] = public_key unless public_key.nil? + + new_client = chef_rest_v0.post("clients", payload) + end + Chef::ApiClientV1.from_hash(self.to_hash.merge(new_client)) + end + + # As a string + def to_s + "client[#{@name}]" + end + + end +end diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb index d0b3b4c7f8..e8053d12f1 100644 --- a/lib/chef/json_compat.rb +++ b/lib/chef/json_compat.rb @@ -29,6 +29,7 @@ class Chef JSON_CLASS = "json_class".freeze CHEF_APICLIENT = "Chef::ApiClient".freeze + CHEF_APICLIENTV1 = "Chef::ApiClientV1".freeze CHEF_CHECKSUM = "Chef::Checksum".freeze CHEF_COOKBOOKVERSION = "Chef::CookbookVersion".freeze CHEF_DATABAG = "Chef::DataBag".freeze @@ -124,6 +125,8 @@ class Chef case json_class when CHEF_APICLIENT Chef::ApiClient + when CHEF_APICLIENTV1 + Chef::ApiClientV1 when CHEF_CHECKSUM Chef::Checksum when CHEF_COOKBOOKVERSION diff --git a/lib/chef/knife/client_bulk_delete.rb b/lib/chef/knife/client_bulk_delete.rb index f2be772759..b439e6f995 100644 --- a/lib/chef/knife/client_bulk_delete.rb +++ b/lib/chef/knife/client_bulk_delete.rb @@ -23,7 +23,7 @@ class Chef class ClientBulkDelete < Knife deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -39,7 +39,7 @@ class Chef ui.fatal("You must supply a regular expression to match the results against") exit 42 end - all_clients = Chef::ApiClient.list(true) + all_clients = Chef::ApiClientV1.list(true) matcher = /#{name_args[0]}/ clients_to_delete = {} diff --git a/lib/chef/knife/client_create.rb b/lib/chef/knife/client_create.rb index 570c1ee950..951457db28 100644 --- a/lib/chef/knife/client_create.rb +++ b/lib/chef/knife/client_create.rb @@ -23,7 +23,7 @@ class Chef class ClientCreate < Knife deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -57,7 +57,7 @@ class Chef banner "knife client create CLIENTNAME (options)" def client - @client_field ||= Chef::ApiClient.new + @client_field ||= Chef::ApiClientV1.new end def create_client(client) diff --git a/lib/chef/knife/client_delete.rb b/lib/chef/knife/client_delete.rb index d7d302ee1d..a49c0867a8 100644 --- a/lib/chef/knife/client_delete.rb +++ b/lib/chef/knife/client_delete.rb @@ -23,7 +23,7 @@ class Chef class ClientDelete < Knife deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -43,8 +43,8 @@ class Chef exit 1 end - delete_object(Chef::ApiClient, @client_name, 'client') { - object = Chef::ApiClient.load(@client_name) + delete_object(Chef::ApiClientV1, @client_name, 'client') { + object = Chef::ApiClientV1.load(@client_name) if object.validator unless config[:delete_validators] ui.fatal("You must specify --delete-validators to delete the validator client #{@client_name}") diff --git a/lib/chef/knife/client_edit.rb b/lib/chef/knife/client_edit.rb index c81bce902a..a243129979 100644 --- a/lib/chef/knife/client_edit.rb +++ b/lib/chef/knife/client_edit.rb @@ -23,7 +23,7 @@ class Chef class ClientEdit < Knife deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -38,7 +38,7 @@ class Chef exit 1 end - edit_object(Chef::ApiClient, @client_name) + edit_object(Chef::ApiClientV1, @client_name) end end end diff --git a/lib/chef/knife/client_list.rb b/lib/chef/knife/client_list.rb index da0bf12dc3..d8a3698b6a 100644 --- a/lib/chef/knife/client_list.rb +++ b/lib/chef/knife/client_list.rb @@ -23,7 +23,7 @@ class Chef class ClientList < Knife deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -35,7 +35,7 @@ class Chef :description => "Show corresponding URIs" def run - output(format_list_for_display(Chef::ApiClient.list)) + output(format_list_for_display(Chef::ApiClientV1.list)) end end end diff --git a/lib/chef/knife/client_reregister.rb b/lib/chef/knife/client_reregister.rb index 666fd09fd2..b94761e718 100644 --- a/lib/chef/knife/client_reregister.rb +++ b/lib/chef/knife/client_reregister.rb @@ -23,7 +23,7 @@ class Chef class ClientReregister < Knife deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -43,7 +43,7 @@ class Chef exit 1 end - client = Chef::ApiClient.reregister(@client_name) + client = Chef::ApiClientV1.reregister(@client_name) Chef::Log.debug("Updated client data: #{client.inspect}") key = client.private_key if config[:file] diff --git a/lib/chef/knife/client_show.rb b/lib/chef/knife/client_show.rb index 822848fdc2..bdac3f9758 100644 --- a/lib/chef/knife/client_show.rb +++ b/lib/chef/knife/client_show.rb @@ -25,7 +25,7 @@ class Chef include Knife::Core::MultiAttributeReturnOption deps do - require 'chef/api_client' + require 'chef/api_client_v1' require 'chef/json_compat' end @@ -40,7 +40,7 @@ class Chef exit 1 end - client = Chef::ApiClient.load(@client_name) + client = Chef::ApiClientV1.load(@client_name) output(format_for_display(client)) end diff --git a/spec/unit/api_client_spec.rb b/spec/unit/api_client_spec.rb index bc4b38848b..860eeacb4f 100644 --- a/spec/unit/api_client_spec.rb +++ b/spec/unit/api_client_spec.rb @@ -21,6 +21,11 @@ require 'spec_helper' require 'chef/api_client' require 'tempfile' +# DEPRECATION NOTE +# +# This code will be removed in Chef 13 in favor of the code in Chef::ApiClientV1, +# which will be moved to this namespace. New development should occur in +# Chef::ApiClientV1 until the time before Chef 13. describe Chef::ApiClient do before(:each) do @client = Chef::ApiClient.new @@ -53,20 +58,6 @@ describe Chef::ApiClient do expect { @client.admin(Hash.new) }.to raise_error(ArgumentError) end - it "has an create_key flag attribute" do - @client.create_key(true) - expect(@client.create_key).to be_truthy - end - - it "create_key defaults to false" do - expect(@client.create_key).to be_falsey - end - - it "allows only boolean values for the create_key flag" do - expect { @client.create_key(false) }.not_to raise_error - expect { @client.create_key(Hash.new) }.to raise_error(ArgumentError) - end - it "has a 'validator' flag attribute" do @client.validator(true) expect(@client.validator).to be_truthy @@ -129,12 +120,6 @@ describe Chef::ApiClient do expect(@json).to include(%q{"validator":false}) end - it "includes the 'create_key' flag when present" do - @client.create_key(true) - @json = @client.to_json - expect(@json).to include(%q{"create_key":true}) - end - it "includes the private key when present" do @client.private_key("monkeypants") expect(@client.to_json).to include(%q{"private_key":"monkeypants"}) @@ -143,15 +128,11 @@ describe Chef::ApiClient do it "does not include the private key if not present" do expect(@json).not_to include("private_key") end - - include_examples "to_json equivalent to Chef::JSONCompat.to_json" do - let(:jsonable) { @client } - end end describe "when deserializing from JSON (string) using ApiClient#from_json" do let(:client_string) do - "{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true,\"create_key\":true}" + "{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true}" end let(:client) do @@ -178,10 +159,6 @@ describe Chef::ApiClient do expect(client.admin).to be_truthy end - it "preserves the create_key status" do - expect(client.create_key).to be_truthy - end - it "preserves the 'validator' status" do expect(client.validator).to be_truthy end @@ -199,7 +176,6 @@ describe Chef::ApiClient do "private_key" => "monkeypants", "admin" => true, "validator" => true, - "create_key" => true, "json_class" => "Chef::ApiClient" } end @@ -224,10 +200,6 @@ describe Chef::ApiClient do expect(client.admin).to be_truthy end - it "preserves the create_key status" do - expect(client.create_key).to be_truthy - end - it "preserves the 'validator' status" do expect(client.validator).to be_truthy end @@ -243,16 +215,14 @@ describe Chef::ApiClient do before(:each) do client = { - "name" => "black", - "clientname" => "black", - "public_key" => "crowes", - "private_key" => "monkeypants", - "admin" => true, - "create_key" => true, - "validator" => true, - "json_class" => "Chef::ApiClient" + "name" => "black", + "clientname" => "black", + "public_key" => "crowes", + "private_key" => "monkeypants", + "admin" => true, + "validator" => true, + "json_class" => "Chef::ApiClient" } - @http_client = double("Chef::REST mock") allow(Chef::REST).to receive(:new).and_return(@http_client) expect(@http_client).to receive(:get).with("clients/black").and_return(client) @@ -275,10 +245,6 @@ describe Chef::ApiClient do expect(@client.admin).to be_a_kind_of(TrueClass) end - it "preserves the create_key status" do - expect(@client.create_key).to be_a_kind_of(TrueClass) - end - it "preserves the 'validator' status" do expect(@client.validator).to be_a_kind_of(TrueClass) end @@ -332,34 +298,24 @@ describe Chef::ApiClient do end context "and the client exists" do - let(:chef_rest_v0_mock) { double('chef rest root v0 object') } - let(:payload) { - {:name => "lost-my-key", :admin => false, :validator => false, :private_key => true} - } - before do @api_client_without_key = Chef::ApiClient.new @api_client_without_key.name("lost-my-key") - allow(@api_client_without_key).to receive(:chef_rest_v0).and_return(chef_rest_v0_mock) - #allow(@api_client_with_key).to receive(:http_api).and_return(_api_mock) - - allow(chef_rest_v0_mock).to receive(:put).with("clients/lost-my-key", payload).and_return(@api_client_with_key) - allow(chef_rest_v0_mock).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key) - allow(@http_client).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key) + expect(@http_client).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key) end + context "and the client exists on a Chef 11-like server" do before do @api_client_with_key = Chef::ApiClient.new @api_client_with_key.name("lost-my-key") @api_client_with_key.private_key("the new private key") - allow(@api_client_with_key).to receive(:chef_rest_v0).and_return(chef_rest_v0_mock) + expect(@http_client).to receive(:put). + with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true). + and_return(@api_client_with_key) end it "returns an ApiClient with a private key" do - expect(chef_rest_v0_mock).to receive(:put).with("clients/lost-my-key", payload). - and_return(@api_client_with_key) - response = Chef::ApiClient.reregister("lost-my-key") # no sane == method for ApiClient :'( expect(response).to eq(@api_client_without_key) @@ -372,7 +328,7 @@ describe Chef::ApiClient do context "and the client exists on a Chef 10-like server" do before do @api_client_with_key = {"name" => "lost-my-key", "private_key" => "the new private key"} - expect(chef_rest_v0_mock).to receive(:put). + expect(@http_client).to receive(:put). with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true). and_return(@api_client_with_key) end @@ -390,134 +346,4 @@ describe Chef::ApiClient do end end - - describe "Versioned API Interactions" do - let(:response_406) { OpenStruct.new(:code => '406') } - let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) } - let(:payload) { - { - :name => "some_name", - :validator => true, - :admin => true - } - } - - before do - @client = Chef::ApiClient.new - allow(@client).to receive(:chef_rest_v0).and_return(double('chef rest root v0 object')) - allow(@client).to receive(:chef_rest_v1).and_return(double('chef rest root v1 object')) - @client.name "some_name" - @client.validator true - @client.admin true - end - - describe "create" do - - # from spec/support/shared/unit/user_and_client_shared.rb - it_should_behave_like "user or client create" do - let(:object) { @client } - let(:error) { Chef::Exceptions::InvalidClientAttribute } - let(:rest_v0) { @client.chef_rest_v0 } - let(:rest_v1) { @client.chef_rest_v1 } - let(:url) { "clients" } - end - - context "when API V1 is not supported by the server" do - # from spec/support/shared/unit/api_versioning.rb - it_should_behave_like "version handling" do - let(:object) { @client } - let(:method) { :create } - let(:http_verb) { :post } - let(:rest_v1) { @client.chef_rest_v1 } - end - end - - end # create - - describe "update" do - context "when a valid client is defined" do - - shared_examples_for "client updating" do - it "updates the client" do - expect(rest). to receive(:put).with("clients/some_name", payload) - @client.update - end - - context "when only the name field exists" do - - before do - # needed since there is no way to set to nil via code - @client.instance_variable_set(:@validator, nil) - @client.instance_variable_set(:@admin, nil) - end - - after do - @client.validator true - @client.admin true - end - - it "updates the client with only the name" do - expect(rest). to receive(:put).with("clients/some_name", {:name => "some_name"}) - @client.update - end - end - - end - - context "when API V1 is supported by the server" do - - it_should_behave_like "client updating" do - let(:rest) { @client.chef_rest_v1 } - end - - end # when API V1 is supported by the server - - context "when API V1 is not supported by the server" do - context "when no version is supported" do - # from spec/support/shared/unit/api_versioning.rb - it_should_behave_like "version handling" do - let(:object) { @client } - let(:method) { :create } - let(:http_verb) { :post } - let(:rest_v1) { @client.chef_rest_v1 } - end - end # when no version is supported - - context "when API V0 is supported" do - - before do - allow(@client.chef_rest_v1).to receive(:put).and_raise(exception_406) - allow(@client).to receive(:server_client_api_version_intersection).and_return([0]) - end - - it_should_behave_like "client updating" do - let(:rest) { @client.chef_rest_v0 } - end - - end - - end # when API V1 is not supported by the server - end # when a valid client is defined - end # update - - # DEPRECATION - # This can be removed after API V0 support is gone - describe "reregister" do - context "when server API V0 is valid on the Chef Server receiving the request" do - it "creates a new object via the API" do - expect(@client.chef_rest_v0).to receive(:put).with("clients/#{@client.name}", payload.merge({:private_key => true})).and_return({}) - @client.reregister - end - end # when server API V0 is valid on the Chef Server receiving the request - - context "when server API V0 is not supported by the Chef Server" do - # from spec/support/shared/unit/api_versioning.rb - it_should_behave_like "user and client reregister" do - let(:object) { @client } - let(:rest_v0) { @client.chef_rest_v0 } - end - end # when server API V0 is not supported by the Chef Server - end # reregister - - end end diff --git a/spec/unit/api_client_v1_spec.rb b/spec/unit/api_client_v1_spec.rb new file mode 100644 index 0000000000..4227185742 --- /dev/null +++ b/spec/unit/api_client_v1_spec.rb @@ -0,0 +1,523 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'spec_helper' + +require 'chef/api_client_v1' +require 'tempfile' + +describe Chef::ApiClientV1 do + before(:each) do + @client = Chef::ApiClientV1.new + end + + it "has a name attribute" do + @client.name("ops_master") + expect(@client.name).to eq("ops_master") + end + + it "does not allow spaces in the name" do + expect { @client.name "ops master" }.to raise_error(ArgumentError) + end + + it "only allows string values for the name" do + expect { @client.name Hash.new }.to raise_error(ArgumentError) + end + + it "has an admin flag attribute" do + @client.admin(true) + expect(@client.admin).to be_truthy + end + + it "defaults to non-admin" do + expect(@client.admin).to be_falsey + end + + it "allows only boolean values for the admin flag" do + expect { @client.admin(false) }.not_to raise_error + expect { @client.admin(Hash.new) }.to raise_error(ArgumentError) + end + + it "has an create_key flag attribute" do + @client.create_key(true) + expect(@client.create_key).to be_truthy + end + + it "create_key defaults to false" do + expect(@client.create_key).to be_falsey + end + + it "allows only boolean values for the create_key flag" do + expect { @client.create_key(false) }.not_to raise_error + expect { @client.create_key(Hash.new) }.to raise_error(ArgumentError) + end + + it "has a 'validator' flag attribute" do + @client.validator(true) + expect(@client.validator).to be_truthy + end + + it "defaults to non-validator" do + expect(@client.validator).to be_falsey + end + + it "allows only boolean values for the 'validator' flag" do + expect { @client.validator(false) }.not_to raise_error + expect { @client.validator(Hash.new) }.to raise_error(ArgumentError) + end + + it "has a public key attribute" do + @client.public_key("super public") + expect(@client.public_key).to eq("super public") + end + + it "accepts only String values for the public key" do + expect { @client.public_key "" }.not_to raise_error + expect { @client.public_key Hash.new }.to raise_error(ArgumentError) + end + + + it "has a private key attribute" do + @client.private_key("super private") + expect(@client.private_key).to eq("super private") + end + + it "accepts only String values for the private key" do + expect { @client.private_key "" }.not_to raise_error + expect { @client.private_key Hash.new }.to raise_error(ArgumentError) + end + + describe "when serializing to JSON" do + before(:each) do + @client.name("black") + @client.public_key("crowes") + @json = @client.to_json + end + + it "serializes as a JSON object" do + expect(@json).to match(/^\{.+\}$/) + end + + it "includes the name value" do + expect(@json).to include(%q{"name":"black"}) + end + + it "includes the public key value" do + expect(@json).to include(%{"public_key":"crowes"}) + end + + it "includes the 'admin' flag" do + expect(@json).to include(%q{"admin":false}) + end + + it "includes the 'validator' flag" do + expect(@json).to include(%q{"validator":false}) + end + + it "includes the 'create_key' flag when present" do + @client.create_key(true) + @json = @client.to_json + expect(@json).to include(%q{"create_key":true}) + end + + it "includes the private key when present" do + @client.private_key("monkeypants") + expect(@client.to_json).to include(%q{"private_key":"monkeypants"}) + end + + it "does not include the private key if not present" do + expect(@json).not_to include("private_key") + end + + include_examples "to_json equivalent to Chef::JSONCompat.to_json" do + let(:jsonable) { @client } + end + end + + describe "when deserializing from JSON (string) using ApiClient#from_json" do + let(:client_string) do + "{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true,\"create_key\":true}" + end + + let(:client) do + Chef::ApiClientV1.from_json(client_string) + end + + it "does not require a 'json_class' string" do + expect(Chef::JSONCompat.parse(client_string)["json_class"]).to eq(nil) + end + + it "should deserialize to a Chef::ApiClientV1 object" do + expect(client).to be_a_kind_of(Chef::ApiClientV1) + end + + it "preserves the name" do + expect(client.name).to eq("black") + end + + it "preserves the public key" do + expect(client.public_key).to eq("crowes") + end + + it "preserves the admin status" do + expect(client.admin).to be_truthy + end + + it "preserves the create_key status" do + expect(client.create_key).to be_truthy + end + + it "preserves the 'validator' status" do + expect(client.validator).to be_truthy + end + + it "includes the private key if present" do + expect(client.private_key).to eq("monkeypants") + end + end + + describe "when deserializing from JSON (hash) using JSONCompat#from_json" do + let(:client_hash) do + { + "name" => "black", + "public_key" => "crowes", + "private_key" => "monkeypants", + "admin" => true, + "validator" => true, + "create_key" => true, + "json_class" => "Chef::ApiClientV1" + } + end + + let(:client) do + Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(client_hash)) + end + + it "should deserialize to a Chef::ApiClientV1 object" do + expect(client).to be_a_kind_of(Chef::ApiClientV1) + end + + it "preserves the name" do + expect(client.name).to eq("black") + end + + it "preserves the public key" do + expect(client.public_key).to eq("crowes") + end + + it "preserves the admin status" do + expect(client.admin).to be_truthy + end + + it "preserves the create_key status" do + expect(client.create_key).to be_truthy + end + + it "preserves the 'validator' status" do + expect(client.validator).to be_truthy + end + + it "includes the private key if present" do + expect(client.private_key).to eq("monkeypants") + end + end + + describe "when loading from JSON" do + before do + end + + before(:each) do + client = { + "name" => "black", + "clientname" => "black", + "public_key" => "crowes", + "private_key" => "monkeypants", + "admin" => true, + "create_key" => true, + "validator" => true, + "json_class" => "Chef::ApiClientV1" + } + + @http_client = double("Chef::REST mock") + allow(Chef::REST).to receive(:new).and_return(@http_client) + expect(@http_client).to receive(:get).with("clients/black").and_return(client) + @client = Chef::ApiClientV1.load(client['name']) + end + + it "should deserialize to a Chef::ApiClientV1 object" do + expect(@client).to be_a_kind_of(Chef::ApiClientV1) + end + + it "preserves the name" do + expect(@client.name).to eq("black") + end + + it "preserves the public key" do + expect(@client.public_key).to eq("crowes") + end + + it "preserves the admin status" do + expect(@client.admin).to be_a_kind_of(TrueClass) + end + + it "preserves the create_key status" do + expect(@client.create_key).to be_a_kind_of(TrueClass) + end + + it "preserves the 'validator' status" do + expect(@client.validator).to be_a_kind_of(TrueClass) + end + + it "includes the private key if present" do + expect(@client.private_key).to eq("monkeypants") + end + + end + + describe "with correctly configured API credentials" do + before do + Chef::Config[:node_name] = "silent-bob" + Chef::Config[:client_key] = File.expand_path('ssl/private_key.pem', CHEF_SPEC_DATA) + end + + after do + Chef::Config[:node_name] = nil + Chef::Config[:client_key] = nil + end + + let :private_key_data do + File.open(Chef::Config[:client_key], "r") {|f| f.read.chomp } + end + + it "has an HTTP client configured with default credentials" do + expect(@client.http_api).to be_a_kind_of(Chef::REST) + expect(@client.http_api.client_name).to eq("silent-bob") + expect(@client.http_api.signing_key.to_s).to eq(private_key_data) + end + end + + + describe "when requesting a new key" do + before do + @http_client = double("Chef::REST mock") + allow(Chef::REST).to receive(:new).and_return(@http_client) + end + + context "and the client does not exist on the server" do + before do + @a_404_response = Net::HTTPNotFound.new("404 not found and such", nil, nil) + @a_404_exception = Net::HTTPServerException.new("404 not found exception", @a_404_response) + + expect(@http_client).to receive(:get).with("clients/lost-my-key").and_raise(@a_404_exception) + end + + it "raises a 404 error" do + expect { Chef::ApiClientV1.reregister("lost-my-key") }.to raise_error(Net::HTTPServerException) + end + end + + context "and the client exists" do + let(:chef_rest_v0_mock) { double('chef rest root v0 object') } + let(:payload) { + {:name => "lost-my-key", :admin => false, :validator => false, :private_key => true} + } + + before do + @api_client_without_key = Chef::ApiClientV1.new + @api_client_without_key.name("lost-my-key") + allow(@api_client_without_key).to receive(:chef_rest_v0).and_return(chef_rest_v0_mock) + #allow(@api_client_with_key).to receive(:http_api).and_return(_api_mock) + + allow(chef_rest_v0_mock).to receive(:put).with("clients/lost-my-key", payload).and_return(@api_client_with_key) + allow(chef_rest_v0_mock).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key) + allow(@http_client).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key) + end + + context "and the client exists on a Chef 11-like server" do + before do + @api_client_with_key = Chef::ApiClientV1.new + @api_client_with_key.name("lost-my-key") + @api_client_with_key.private_key("the new private key") + allow(@api_client_with_key).to receive(:chef_rest_v0).and_return(chef_rest_v0_mock) + end + + it "returns an ApiClient with a private key" do + expect(chef_rest_v0_mock).to receive(:put).with("clients/lost-my-key", payload). + and_return(@api_client_with_key) + + response = Chef::ApiClientV1.reregister("lost-my-key") + # no sane == method for ApiClient :'( + expect(response).to eq(@api_client_without_key) + expect(response.private_key).to eq("the new private key") + expect(response.name).to eq("lost-my-key") + expect(response.admin).to be_falsey + end + end + + context "and the client exists on a Chef 10-like server" do + before do + @api_client_with_key = {"name" => "lost-my-key", "private_key" => "the new private key"} + expect(chef_rest_v0_mock).to receive(:put). + with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true). + and_return(@api_client_with_key) + end + + it "returns an ApiClient with a private key" do + response = Chef::ApiClientV1.reregister("lost-my-key") + # no sane == method for ApiClient :'( + expect(response).to eq(@api_client_without_key) + expect(response.private_key).to eq("the new private key") + expect(response.name).to eq("lost-my-key") + expect(response.admin).to be_falsey + expect(response.validator).to be_falsey + end + end + + end + end + + describe "Versioned API Interactions" do + let(:response_406) { OpenStruct.new(:code => '406') } + let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) } + let(:payload) { + { + :name => "some_name", + :validator => true, + :admin => true + } + } + + before do + @client = Chef::ApiClientV1.new + allow(@client).to receive(:chef_rest_v0).and_return(double('chef rest root v0 object')) + allow(@client).to receive(:chef_rest_v1).and_return(double('chef rest root v1 object')) + @client.name "some_name" + @client.validator true + @client.admin true + end + + describe "create" do + + # from spec/support/shared/unit/user_and_client_shared.rb + it_should_behave_like "user or client create" do + let(:object) { @client } + let(:error) { Chef::Exceptions::InvalidClientAttribute } + let(:rest_v0) { @client.chef_rest_v0 } + let(:rest_v1) { @client.chef_rest_v1 } + let(:url) { "clients" } + end + + context "when API V1 is not supported by the server" do + # from spec/support/shared/unit/api_versioning.rb + it_should_behave_like "version handling" do + let(:object) { @client } + let(:method) { :create } + let(:http_verb) { :post } + let(:rest_v1) { @client.chef_rest_v1 } + end + end + + end # create + + describe "update" do + context "when a valid client is defined" do + + shared_examples_for "client updating" do + it "updates the client" do + expect(rest). to receive(:put).with("clients/some_name", payload) + @client.update + end + + context "when only the name field exists" do + + before do + # needed since there is no way to set to nil via code + @client.instance_variable_set(:@validator, nil) + @client.instance_variable_set(:@admin, nil) + end + + after do + @client.validator true + @client.admin true + end + + it "updates the client with only the name" do + expect(rest). to receive(:put).with("clients/some_name", {:name => "some_name"}) + @client.update + end + end + + end + + context "when API V1 is supported by the server" do + + it_should_behave_like "client updating" do + let(:rest) { @client.chef_rest_v1 } + end + + end # when API V1 is supported by the server + + context "when API V1 is not supported by the server" do + context "when no version is supported" do + # from spec/support/shared/unit/api_versioning.rb + it_should_behave_like "version handling" do + let(:object) { @client } + let(:method) { :create } + let(:http_verb) { :post } + let(:rest_v1) { @client.chef_rest_v1 } + end + end # when no version is supported + + context "when API V0 is supported" do + + before do + allow(@client.chef_rest_v1).to receive(:put).and_raise(exception_406) + allow(@client).to receive(:server_client_api_version_intersection).and_return([0]) + end + + it_should_behave_like "client updating" do + let(:rest) { @client.chef_rest_v0 } + end + + end + + end # when API V1 is not supported by the server + end # when a valid client is defined + end # update + + # DEPRECATION + # This can be removed after API V0 support is gone + describe "reregister" do + context "when server API V0 is valid on the Chef Server receiving the request" do + it "creates a new object via the API" do + expect(@client.chef_rest_v0).to receive(:put).with("clients/#{@client.name}", payload.merge({:private_key => true})).and_return({}) + @client.reregister + end + end # when server API V0 is valid on the Chef Server receiving the request + + context "when server API V0 is not supported by the Chef Server" do + # from spec/support/shared/unit/api_versioning.rb + it_should_behave_like "user and client reregister" do + let(:object) { @client } + let(:rest_v0) { @client.chef_rest_v0 } + end + end # when server API V0 is not supported by the Chef Server + end # reregister + + end +end diff --git a/spec/unit/knife/client_bulk_delete_spec.rb b/spec/unit/knife/client_bulk_delete_spec.rb index 45bb4dd16c..1a6317ac00 100644 --- a/spec/unit/knife/client_bulk_delete_spec.rb +++ b/spec/unit/knife/client_bulk_delete_spec.rb @@ -45,7 +45,7 @@ describe Chef::Knife::ClientBulkDelete do clients = Hash.new nonvalidator_client_names.each do |client_name| - client = Chef::ApiClient.new() + client = Chef::ApiClientV1.new() client.name(client_name) allow(client).to receive(:destroy).and_return(true) clients[client_name] = client @@ -59,7 +59,7 @@ describe Chef::Knife::ClientBulkDelete do clients = Hash.new validator_client_names.each do |validator_client_name| - validator_client = Chef::ApiClient.new() + validator_client = Chef::ApiClientV1.new() validator_client.name(validator_client_name) allow(validator_client).to receive(:validator).and_return(true) allow(validator_client).to receive(:destroy).and_return(true) @@ -75,7 +75,7 @@ describe Chef::Knife::ClientBulkDelete do } before(:each) do - allow(Chef::ApiClient).to receive(:list).and_return(clients) + allow(Chef::ApiClientV1).to receive(:list).and_return(clients) end describe "run" do @@ -89,7 +89,7 @@ describe Chef::Knife::ClientBulkDelete do describe "with any clients" do it "should get the list of the clients" do - expect(Chef::ApiClient).to receive(:list) + expect(Chef::ApiClientV1).to receive(:list) knife.run end diff --git a/spec/unit/knife/client_create_spec.rb b/spec/unit/knife/client_create_spec.rb index 8fecfc885f..a1dcc564e2 100644 --- a/spec/unit/knife/client_create_spec.rb +++ b/spec/unit/knife/client_create_spec.rb @@ -34,7 +34,7 @@ describe Chef::Knife::ClientCreate do end let(:client) do - Chef::ApiClient.new + Chef::ApiClientV1.new end let(:knife) do diff --git a/spec/unit/knife/client_delete_spec.rb b/spec/unit/knife/client_delete_spec.rb index 0fb5e0bab7..619009979b 100644 --- a/spec/unit/knife/client_delete_spec.rb +++ b/spec/unit/knife/client_delete_spec.rb @@ -30,7 +30,7 @@ describe Chef::Knife::ClientDelete do describe 'run' do it 'should delete the client' do - expect(@knife).to receive(:delete_object).with(Chef::ApiClient, 'adam', 'client') + expect(@knife).to receive(:delete_object).with(Chef::ApiClientV1, 'adam', 'client') @knife.run end @@ -46,8 +46,8 @@ describe Chef::Knife::ClientDelete do before(:each) do allow(Chef::Knife::UI).to receive(:confirm).and_return(true) allow(@knife).to receive(:confirm).and_return(true) - @client = Chef::ApiClient.new - expect(Chef::ApiClient).to receive(:load).and_return(@client) + @client = Chef::ApiClientV1.new + expect(Chef::ApiClientV1).to receive(:load).and_return(@client) end it 'should delete non-validator client if --delete-validators is not set' do diff --git a/spec/unit/knife/client_edit_spec.rb b/spec/unit/knife/client_edit_spec.rb index c040c5e2f2..6a5549e28c 100644 --- a/spec/unit/knife/client_edit_spec.rb +++ b/spec/unit/knife/client_edit_spec.rb @@ -26,7 +26,7 @@ describe Chef::Knife::ClientEdit do describe 'run' do it 'should edit the client' do - expect(@knife).to receive(:edit_object).with(Chef::ApiClient, 'adam') + expect(@knife).to receive(:edit_object).with(Chef::ApiClientV1, 'adam') @knife.run end diff --git a/spec/unit/knife/client_list_spec.rb b/spec/unit/knife/client_list_spec.rb index eff01da4e9..ce0fa4f5e8 100644 --- a/spec/unit/knife/client_list_spec.rb +++ b/spec/unit/knife/client_list_spec.rb @@ -26,7 +26,7 @@ describe Chef::Knife::ClientList do describe 'run' do it 'should list the clients' do - expect(Chef::ApiClient).to receive(:list) + expect(Chef::ApiClientV1).to receive(:list) expect(@knife).to receive(:format_list_for_display) @knife.run end diff --git a/spec/unit/knife/client_reregister_spec.rb b/spec/unit/knife/client_reregister_spec.rb index f1be4ed570..7e763242e4 100644 --- a/spec/unit/knife/client_reregister_spec.rb +++ b/spec/unit/knife/client_reregister_spec.rb @@ -41,7 +41,7 @@ describe Chef::Knife::ClientReregister do context 'when not configured for file output' do it 'reregisters the client and prints the key' do - expect(Chef::ApiClient).to receive(:reregister).with('adam').and_return(@client_mock) + expect(Chef::ApiClientV1).to receive(:reregister).with('adam').and_return(@client_mock) @knife.run expect(@stdout.string).to match( /foo_key/ ) end @@ -49,7 +49,7 @@ describe Chef::Knife::ClientReregister do context 'when configured for file output' do it 'should write the private key to a file' do - expect(Chef::ApiClient).to receive(:reregister).with('adam').and_return(@client_mock) + expect(Chef::ApiClientV1).to receive(:reregister).with('adam').and_return(@client_mock) @knife.config[:file] = '/tmp/monkeypants' filehandle = StringIO.new diff --git a/spec/unit/knife/client_show_spec.rb b/spec/unit/knife/client_show_spec.rb index 8404e8d019..73a876cee0 100644 --- a/spec/unit/knife/client_show_spec.rb +++ b/spec/unit/knife/client_show_spec.rb @@ -27,7 +27,7 @@ describe Chef::Knife::ClientShow do describe 'run' do it 'should list the client' do - expect(Chef::ApiClient).to receive(:load).with('adam').and_return(@client_mock) + expect(Chef::ApiClientV1).to receive(:load).with('adam').and_return(@client_mock) expect(@knife).to receive(:format_for_display).with(@client_mock) @knife.run end @@ -37,7 +37,7 @@ describe Chef::Knife::ClientShow do @stdout = StringIO.new allow(@knife.ui).to receive(:stdout).and_return(@stdout) fake_client_contents = {"foo"=>"bar", "baz"=>"qux"} - expect(Chef::ApiClient).to receive(:load).with('adam').and_return(fake_client_contents) + expect(Chef::ApiClientV1).to receive(:load).with('adam').and_return(fake_client_contents) @knife.run expect(@stdout.string).to eql("{\n \"foo\": \"bar\",\n \"baz\": \"qux\"\n}\n") end |