diff --git a/kubernetes/e2e_test/test_utils.py b/kubernetes/e2e_test/test_utils.py index 6c40361ff8..ddb41dad13 100644 --- a/kubernetes/e2e_test/test_utils.py +++ b/kubernetes/e2e_test/test_utils.py @@ -24,7 +24,17 @@ class TestUtils(unittest.TestCase): def setUpClass(cls): cls.config = base.get_e2e_configuration() cls.path_prefix = "kubernetes/e2e_test/test_yaml/" + cls.test_namespace = "e2e-test-utils" + k8s_client = client.api_client.ApiClient(configuration=cls.config) + core_v1 = client.CoreV1Api(api_client=k8s_client) + body = client.V1Namespace(metadata=client.V1ObjectMeta(name=cls.test_namespace)) + core_v1.create_namespace(body=body) + @classmethod + def tearDownClass(cls): + k8s_client = client.api_client.ApiClient(configuration=cls.config) + core_v1 = client.CoreV1Api(api_client=k8s_client) + core_v1.delete_namespace(name=cls.test_namespace) # Tests for creating individual API objects def test_create_apps_deployment_from_yaml(self): @@ -317,3 +327,44 @@ def test_create_from_multi_resource_yaml_with_multi_conflicts(self): ext_api.delete_namespaced_deployment( name="triple-nginx", namespace="default", body={}) + + def test_create_namespaces_apps_deployment_from_yaml(self): + """ + Should be able to create an apps/v1beta1 deployment. + """ + k8s_client = client.api_client.ApiClient(configuration=self.config) + utils.create_namespaced_from_yaml( + k8s_client, self.path_prefix + "apps-deployment.yaml", namespace=self.test_namespace) + app_api = client.AppsV1beta1Api(k8s_client) + dep = app_api.read_namespaced_deployment(name="nginx-app", + namespace=self.test_namespace) + self.assertIsNotNone(dep) + app_api.delete_namespaced_deployment( + name="nginx-app", namespace=self.test_namespace, + body={}) + + def test_create_from_list_in_multi_resource_yaml(self): + """ + Should be able to create the items in the PodList and a deployment + specified in the multi-resource file + """ + k8s_client = client.api_client.ApiClient(configuration=self.config) + utils.create_namespaced_from_yaml( + k8s_client, self.path_prefix + "multi-resource-with-list.yaml", namespace=self.test_namespace) + core_api = client.CoreV1Api(k8s_client) + app_api = client.AppsV1beta1Api(k8s_client) + pod_0 = core_api.read_namespaced_pod( + name="mock-pod-0", namespace=self.test_namespace) + self.assertIsNotNone(pod_0) + pod_1 = core_api.read_namespaced_pod( + name="mock-pod-1", namespace=self.test_namespace) + self.assertIsNotNone(pod_1) + dep = app_api.read_namespaced_deployment( + name="mock", namespace=self.test_namespace) + self.assertIsNotNone(dep) + core_api.delete_namespaced_pod( + name="mock-pod-0", namespace=self.test_namespace, body={}) + core_api.delete_namespaced_pod( + name="mock-pod-1", namespace=self.test_namespace, body={}) + app_api.delete_namespaced_deployment( + name="mock", namespace=self.test_namespace, body={}) diff --git a/kubernetes/utils/__init__.py b/kubernetes/utils/__init__.py index 2b8597c2fb..dee72861e2 100644 --- a/kubernetes/utils/__init__.py +++ b/kubernetes/utils/__init__.py @@ -14,4 +14,5 @@ from __future__ import absolute_import -from .create_from_yaml import FailToCreateError, create_from_yaml +from .create_from_yaml import (FailToCreateError, create_from_yaml, + create_namespaced_from_yaml) diff --git a/kubernetes/utils/create_from_yaml.py b/kubernetes/utils/create_from_yaml.py index 29be813b1f..fce1b939c1 100644 --- a/kubernetes/utils/create_from_yaml.py +++ b/kubernetes/utils/create_from_yaml.py @@ -55,6 +55,52 @@ def create_from_yaml( Valid values are: - All: all dry run stages will be processed """ + create_namespaced_from_yaml( + k8s_client, + yaml_file, + verbose, + namespace="default", + **kwargs + ) + + +def create_namespaced_from_yaml( + k8s_client, + yaml_file, + verbose=False, + namespace="default", + **kwargs): + """ + Perform an action from a yaml file. Pass True for verbose to + print confirmation information. + Input: + yaml_file: string. Contains the path to yaml file. + k8s_client: an ApiClient object, initialized with the client args. + verbose: If True, print confirmation from the create action. + Default is False. + namespace: string. Contains the namespace to create all + resources inside + + Returns: + An k8s api object or list of apis objects created from YAML. + When a single object is generated, return type is dependent + on output_list. + + Throws a FailToCreateError exception if creation of any object + fails with helpful messages from the server. + + Available parameters for creating : + :param async_req bool + :param bool include_uninitialized: If true, partially initialized + resources are included in the response. + :param str pretty: If 'true', then the output is pretty printed. + :param str dry_run: When present, indicates that modifications + should not be persisted. An invalid or unrecognized dryRun + directive will result in an error response and no further + processing of the request. + Valid values are: - All: all dry run stages will be processed + """ + with open(path.abspath(yaml_file)) as f: yml_document_all = yaml.safe_load_all(f) api_exceptions = [] @@ -72,15 +118,15 @@ def create_from_yaml( yml_object["apiVersion"] = yml_document["apiVersion"] yml_object["kind"] = kind try: - create_from_yaml_single_item( - k8s_client, yml_object, verbose, **kwargs) + create_namespaced_from_yaml_single_item( + k8s_client, yml_object, verbose, namespace, **kwargs) except client.rest.ApiException as api_exception: api_exceptions.append(api_exception) else: # This is a single object. Call the single item method try: - create_from_yaml_single_item( - k8s_client, yml_document, verbose, **kwargs) + create_namespaced_from_yaml_single_item( + k8s_client, yml_document, verbose, namespace, **kwargs) except client.rest.ApiException as api_exception: api_exceptions.append(api_exception) # In case we have exceptions waiting for us, raise them @@ -89,7 +135,24 @@ def create_from_yaml( def create_from_yaml_single_item( - k8s_client, yml_object, verbose=False, **kwargs): + k8s_client, + yml_object, + verbose=False, + **kwargs): + create_namespaced_from_yaml_single_item( + k8s_client, + yml_object, + verbose, + namespace="default", + **kwargs) + + +def create_namespaced_from_yaml_single_item( + k8s_client, + yml_object, + verbose=False, + namespace="default", + **kwargs): group, _, version = yml_object["apiVersion"].partition("/") if version == "": version = group @@ -108,8 +171,6 @@ def create_from_yaml_single_item( # if any if "namespace" in yml_object["metadata"]: namespace = yml_object["metadata"]["namespace"] - else: - namespace = "default" # Expect the user to create namespaced objects more often if hasattr(k8s_api, "create_namespaced_{0}".format(kind)): resp = getattr(k8s_api, "create_namespaced_{0}".format(kind))(