From ce0fc0ad292144355567e267faf54b84c8a9104b Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 7 Apr 2022 10:09:38 -0400 Subject: [PATCH] Deprecate API version 1.0 Adding new capability to mark API versions as "deprecated" which will be displayed when verifier and registrar start and a warning is issued anytime a client (agent or tenant) uses a deprecated API. This will allow us to mark APIs as deprecated before they are fully removed. Signed-off-by: Michael Peters --- keylime/api_version.py | 7 +++++++ keylime/cloud_verifier_tornado.py | 21 +++++++-------------- keylime/registrar_common.py | 12 ++++-------- keylime/web_util.py | 10 ++++++++++ 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/keylime/api_version.py b/keylime/api_version.py index e20b01f96..6beaf9927 100644 --- a/keylime/api_version.py +++ b/keylime/api_version.py @@ -15,6 +15,7 @@ "1": "1.0", "2": "2.0" } +DEPRECATED_VERSIONS = ["1.0"] def current_version(): return CURRENT_VERSION @@ -36,6 +37,10 @@ def is_supported_version(v): v_obj = version.parse(str(v)) return v_obj.base_version in VERSIONS +def is_deprecated_version(v): + v_obj = version.parse(str(v)) + return is_supported_version(v) and v_obj.base_version in DEPRECATED_VERSIONS + def normalize_version(v): v = str(v) v = v.strip('/') @@ -59,6 +64,8 @@ def log_api_versions(logger): versions.remove(CURRENT_VERSION) if versions: logger.info('Supported older API versions: ' + ", ".join(versions)) + if DEPRECATED_VERSIONS: + logger.info("Deprecated API versions (soon to be removed): " + ", ".join(DEPRECATED_VERSIONS)) def validate_version(v: str) -> bool: diff --git a/keylime/cloud_verifier_tornado.py b/keylime/cloud_verifier_tornado.py index a14a10dbc..fa68454f6 100644 --- a/keylime/cloud_verifier_tornado.py +++ b/keylime/cloud_verifier_tornado.py @@ -259,8 +259,7 @@ def get(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -329,8 +328,7 @@ def delete(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -405,8 +403,7 @@ def post(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -547,8 +544,7 @@ def put(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -633,8 +629,7 @@ def get(self): web_util.echo_json_response(self, 400, "Invalid URL") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return allowlist_name = rest_params['allowlists'] @@ -672,8 +667,7 @@ def delete(self): web_util.echo_json_response(self, 400, "Invalid URL") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return allowlist_name = rest_params['allowlists'] @@ -724,8 +718,7 @@ def post(self): web_util.echo_json_response(self, 400, "Invalid URL") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return allowlist_name = rest_params['allowlists'] diff --git a/keylime/registrar_common.py b/keylime/registrar_common.py index f46252ed4..4f2466cc6 100644 --- a/keylime/registrar_common.py +++ b/keylime/registrar_common.py @@ -63,8 +63,7 @@ def do_GET(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -146,8 +145,7 @@ def do_DELETE(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -232,8 +230,7 @@ def do_POST(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: @@ -419,8 +416,7 @@ def do_PUT(self): self, 405, "Not Implemented: Use /agents/ interface") return - if not rest_params["api_version"]: - web_util.echo_json_response(self, 400, "API Version not supported") + if not web_util.validate_api_version(self, rest_params["api_version"], logger): return if "agents" not in rest_params: diff --git a/keylime/web_util.py b/keylime/web_util.py index 5021676de..15987731f 100644 --- a/keylime/web_util.py +++ b/keylime/web_util.py @@ -190,6 +190,16 @@ def get_restful_params(urlstring): return path_params +def validate_api_version(handler, version, logger): + if not version or not keylime_api_version.is_supported_version(version): + echo_json_response(handler, 400, "API Version not supported") + return False + + if keylime_api_version.is_deprecated_version(version): + logger.warning('Client request to API version %s is deprecated and will be removed in future versions.', version) + return True + + def _list_to_dict(alist): """Convert list into dictionary via grouping [k0,v0,k1,v1,...]""" params = {}