summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Brown <anbrown@blackberry.com>2015-08-13 21:09:56 -0400
committerAndrew Brown <anbrown@blackberry.com>2015-08-13 21:09:56 -0400
commitf34c2686d2a4b7fe83f1449cc1c5cc38ac4b8a04 (patch)
tree176590a5497ff04d5efca83a837463582595a7d9
parent40216a586a0caeb1a03590f89e95bffddd4f5c5f (diff)
downloadchef-zero-f34c2686d2a4b7fe83f1449cc1c5cc38ac4b8a04.tar.gz
Further support for /server_api_version
This adds checks to ensure that the requested API version is checked early on in the request cycle, to comply with RFC041.
-rw-r--r--lib/chef_zero/rest_base.rb36
-rw-r--r--lib/chef_zero/rest_request.rb4
-rw-r--r--spec/run_oc_pedant.rb1
3 files changed, 36 insertions, 5 deletions
diff --git a/lib/chef_zero/rest_base.rb b/lib/chef_zero/rest_base.rb
index 48d423a..3036903 100644
--- a/lib/chef_zero/rest_base.rb
+++ b/lib/chef_zero/rest_base.rb
@@ -15,7 +15,29 @@ module ChefZero
server.data_store
end
+ def check_api_version(request)
+ version = request.api_version
+ return nil if version.nil? # Not present in headers
+
+ if version.to_i.to_s != version # Version is not an Integer
+ return json_response(406, { "username" => request.requestor }, -1, -1)
+ elsif version.to_i > MAX_API_VERSION or version.to_i < MIN_API_VERSION
+ response = {
+ "error" => "invalid-x-ops-server-api-version",
+ "message" => "Specified version #{version} not supported",
+ "min_api_version" => MIN_API_VERSION,
+ "max_api_version" => MAX_API_VERSION
+ }
+ return json_response(406, response, version, -1)
+ else
+ return nil
+ end
+ end
+
def call(request)
+ response = check_api_version(request)
+ return response unless response.nil?
+
method = request.method.downcase.to_sym
if !self.respond_to?(method)
accept_methods = [:get, :put, :post, :delete].select { |m| self.respond_to?(m) }
@@ -177,16 +199,22 @@ module ChefZero
json_response(response_code, {"error" => [error]})
end
- def json_response(response_code, json)
- already_json_response(response_code, FFI_Yajl::Encoder.encode(json, :pretty => true))
+ def json_response(response_code, json, request_version=0, response_version=0)
+ already_json_response(response_code, FFI_Yajl::Encoder.encode(json, :pretty => true), request_version, response_version)
end
def text_response(response_code, text)
[response_code, {"Content-Type" => "text/plain"}, text]
end
- def already_json_response(response_code, json_text)
- [response_code, {"Content-Type" => "application/json"}, json_text]
+ def already_json_response(response_code, json_text, request_version=0, response_version=0)
+ header = { "min_version" => MIN_API_VERSION, "max_version" => MAX_API_VERSION,
+ "request_version" => request_version,
+ "response_version" => response_version }
+ [ response_code,
+ { "Content-Type" => "application/json",
+ "X-Ops-Server-API-Version" => FFI_Yajl::Encoder.encode(header) },
+ json_text ]
end
# To be called from inside rest endpoints
diff --git a/lib/chef_zero/rest_request.rb b/lib/chef_zero/rest_request.rb
index e79af7f..ea96110 100644
--- a/lib/chef_zero/rest_request.rb
+++ b/lib/chef_zero/rest_request.rb
@@ -18,6 +18,10 @@ module ChefZero
@base_uri = value
end
+ def api_version
+ @env['HTTP_X_OPS_SERVER_API_VERSION']
+ end
+
def requestor
@env['HTTP_X_OPS_USERID']
end
diff --git a/spec/run_oc_pedant.rb b/spec/run_oc_pedant.rb
index c0ba702..d2d1c84 100644
--- a/spec/run_oc_pedant.rb
+++ b/spec/run_oc_pedant.rb
@@ -47,7 +47,6 @@ begin
# Chef 12 features not yet 100% supported by Chef Zero
'--skip-policies',
- '--skip-server-api-version',
'--skip-cookbook-artifacts',
'--skip-containers',
'--skip-api-v1'