diff options
-rw-r--r-- | lib/chef/http/api_versions.rb | 50 | ||||
-rw-r--r-- | lib/chef/mixin/versioned_api.rb | 49 | ||||
-rw-r--r-- | lib/chef/server_api.rb | 2 | ||||
-rw-r--r-- | lib/chef/server_api_versions.rb | 36 |
4 files changed, 137 insertions, 0 deletions
diff --git a/lib/chef/http/api_versions.rb b/lib/chef/http/api_versions.rb new file mode 100644 index 0000000000..e164da262d --- /dev/null +++ b/lib/chef/http/api_versions.rb @@ -0,0 +1,50 @@ +#-- +# Copyright:: Copyright 2017, 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/server_api_versions" + +class Chef + class HTTP + # An HTTP middleware to retrieve and store the Chef Server's minimum + # and maximum supported API versions. + class APIVersions + + def initialize(options = {}) + end + + def handle_request(method, url, headers = {}, data = false) + [method, url, headers, data] + end + + def handle_response(http_response, rest_request, return_value) + if http_response.key?("x-ops-server-api-version") + ServerAPIVersions.instance.set_versions(http_response["x-ops-server-api-version"]) + end + [http_response, rest_request, return_value] + end + + def stream_response_handler(response) + nil + end + + def handle_stream_complete(http_response, rest_request, return_value) + [http_response, rest_request, return_value] + end + + end + end +end diff --git a/lib/chef/mixin/versioned_api.rb b/lib/chef/mixin/versioned_api.rb new file mode 100644 index 0000000000..b8ec61c5f0 --- /dev/null +++ b/lib/chef/mixin/versioned_api.rb @@ -0,0 +1,49 @@ +#-- +# Copyright:: Copyright 2017, 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. +# + +class Chef + module Mixin + module VersionedAPI + + def self.included(base) + # When this file is mixed in, make sure we also add the class methods + base.send :extend, ClassMethods + end + + module ClassMethods + def versioned_interfaces + @versioned_interfaces ||= [] + end + + def add_api_version(klass) + versioned_interfaces << klass + end + end + + def select_api_version + self.class.versioned_interfaces.select do |klass| + version = klass.send(:supported_api_version) + # min and max versions will be nil if we've not made a request to the server yet, + # in which case we'll just start with the highest version and see what happens + ServerAPIVersions.instance.min_server_version.nil? || (version >= ServerAPIVersions.instance.min_server_version && version <= ServerAPIVersions.instance.max_server_version) + end + .sort { |a, b| a.send(:supported_api_version) <=> b.send(:supported_api_version) } + .last + end + end + end +end diff --git a/lib/chef/server_api.rb b/lib/chef/server_api.rb index d233d25232..2bdc5d9fe8 100644 --- a/lib/chef/server_api.rb +++ b/lib/chef/server_api.rb @@ -24,6 +24,7 @@ require "chef/http/json_input" require "chef/http/json_output" require "chef/http/remote_request_id" require "chef/http/validate_content_length" +require "chef/http/api_versions" class Chef class ServerAPI < Chef::HTTP @@ -42,6 +43,7 @@ class Chef use Chef::HTTP::Decompressor use Chef::HTTP::Authenticator use Chef::HTTP::RemoteRequestID + use Chef::HTTP::APIVersions # ValidateContentLength should come after Decompressor # because the order of middlewares is reversed when handling diff --git a/lib/chef/server_api_versions.rb b/lib/chef/server_api_versions.rb new file mode 100644 index 0000000000..91591875a4 --- /dev/null +++ b/lib/chef/server_api_versions.rb @@ -0,0 +1,36 @@ +#-- +# Copyright:: Copyright 2017, 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 "singleton" + +class Chef + class ServerAPIVersions + include Singleton + + def set_versions(versions) + @versions ||= versions + end + + def min_server_version + !@versions.nil? ? @versions["min_version"] : nil + end + + def max_server_version + !@versions.nil? ? @versions["max_version"] : nil + end + end +end |