From 9729a655eadca6123763a1c28e147bcf882b815d Mon Sep 17 00:00:00 2001 From: Will Thames Date: Fri, 28 Sep 2018 02:03:54 +1000 Subject: [PATCH] Add validate helper function (#199) * Add validate method to dynamic client Uses kubernetes-validate to validate resource definitions * Ignore B306 for ValidationError ValidationError provides its own e.message * Fix validate parameter name Rename `resource` to `definition` and remove legacy `client` parameter from docs (cherry picked from commit 44fdf7a9615b5682e72a26ed60436335964e633c) --- openshift/dynamic/client.py | 40 ++++++++++++++++++++++++++++++++- openshift/dynamic/exceptions.py | 4 ++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/openshift/dynamic/client.py b/openshift/dynamic/client.py index 6bc70ca2..e66a7bb6 100755 --- a/openshift/dynamic/client.py +++ b/openshift/dynamic/client.py @@ -11,7 +11,14 @@ from kubernetes.client.api_client import ApiClient from kubernetes.client.rest import ApiException -from openshift.dynamic.exceptions import ResourceNotFoundError, ResourceNotUniqueError, api_exception +from openshift.dynamic.exceptions import ResourceNotFoundError, ResourceNotUniqueError, api_exception, KubernetesValidateMissing + +try: + import kubernetes_validate + HAS_KUBERNETES_VALIDATE = True +except ImportError: + HAS_KUBERNETES_VALIDATE = False + __all__ = [ 'DynamicClient', @@ -256,6 +263,37 @@ def request(self, method, path, body=None, **params): ) + def validate(self, definition, version=None, strict=False): + """validate checks a kubernetes resource definition + + Args: + definition (dict): resource definition + version (str): version of kubernetes to validate against + strict (bool): whether unexpected additional properties should be considered errors + + Returns: + warnings (list), errors (list): warnings are missing validations, errors are validation failures + """ + if not HAS_KUBERNETES_VALIDATE: + raise KubernetesValidateMissing() + + errors = list() + warnings = list() + try: + if version is None: + try: + version = self.version['kubernetes']['gitVersion'] + except KeyError: + version = kubernetes_validate.latest_version() + kubernetes_validate.validate(definition, version, strict) + except kubernetes_validate.utils.ValidationError as e: + errors.append("resource definition validation error at %s: %s" % ('.'.join([str(item) for item in e.path]), e.message)) # noqa: B306 + except kubernetes_validate.utils.SchemaNotFoundError as e: + warnings.append("Could not find schema for object kind %s with API version %s in Kubernetes version %s (possibly Custom Resource?)" % + (e.kind, e.api_version, e.version)) + return warnings, errors + + class Resource(object): """ Represents an API resource type, containing the information required to build urls for requests """ diff --git a/openshift/dynamic/exceptions.py b/openshift/dynamic/exceptions.py index c01e2d56..9e3948e5 100644 --- a/openshift/dynamic/exceptions.py +++ b/openshift/dynamic/exceptions.py @@ -54,6 +54,9 @@ class ResourceNotFoundError(Exception): class ResourceNotUniqueError(Exception): """ Parameters given matched multiple API resources """ +class KubernetesValidateMissing(Exception): + """ kubernetes-validate is not installed """ + # HTTP Errors class BadRequestError(DynamicApiError): """ 400: StatusBadRequest """ @@ -79,3 +82,4 @@ class ServiceUnavailableError(DynamicApiError): """ 503: StatusServiceUnavailable """ class ServerTimeoutError(DynamicApiError): """ 504: StatusServerTimeout """ +