From 666cc7fd71be3ae0fbb636dd9b2902a2617fb9cf Mon Sep 17 00:00:00 2001 From: Trung Thai Date: Tue, 11 Aug 2020 03:38:49 +0000 Subject: [PATCH] Creating deployment names mapping configuration lookup. Updating UC AVT Client allowing user to define custom mapping of deployment names in a configuration file. Real deployment name is returned whether or not the configuration is present or not. Add 2 unittest cases handling positive vs neutral conditions Change-Id: I677bd562928d64d386f3523b9525de9771506be0 --- kube_utility_container/services/dataloader.py | 91 +++++++++++++++++++ .../services/utility_container_client.py | 5 +- .../unit/services/test_utility_dataloader.py | 38 ++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 kube_utility_container/services/dataloader.py create mode 100644 kube_utility_container/tests/unit/services/test_utility_dataloader.py diff --git a/kube_utility_container/services/dataloader.py b/kube_utility_container/services/dataloader.py new file mode 100644 index 00000000..ea329279 --- /dev/null +++ b/kube_utility_container/services/dataloader.py @@ -0,0 +1,91 @@ +# Copyright 2020 AT&T Intellectual Property. All other rights reserved. +# +# 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. + +import json +import os +from pathlib import Path + +class DeploymentMapping(): + """ Class to handle custom deployment names different than the defaults + set in AVT unittests. When actual mapping file exists, it will search + and return on "real_name" defined in cfgmap variable. + """ + + def __init__(self,name): + self.raw_deployment_name = name + self.cfgmap = 'etc/deployment_name_mappings.json' + + def _get_mapping_realname(self): + """ Method to return real deployment name when a config map file is + explicitly defined. Otherwise, raw deployment name is been used. + + : param name: the actual deployment name (raw) source from + the running unittest cases + :cfgmap variable: set to the location of map configuration file in json format. + : return: return the actual/real deployment name in either case + + If the real deployment_names are different than the actual/raw deployment names, + they can be mapped by defining the entries in etc/deployment_name_mappings.json + like example below. + + Example: + { + "comments": "deployment names mapping samples. update it accordingly", + "mappings": [ + { + "raw_name": "mysqlclient-utility", + "real_name": "clcp-mysqlclient-utility" + }, + { + "raw_name": "etcdctl-utility", + "real_name": "clcp-etcdctl-utility" + } + ] + } + """ + + if os.path.exists(self.cfgmap): + fh = open(self.cfgmap, "r") + data = json.load(fh) + fh.close() + + for item in data['mappings']: + if item['raw_name'] == self.raw_deployment_name: + return item['real_name'] + break + else: + return self.raw_deployment_name + + def _is_deployment_name_consistent(self,actual_name): + """ Verify deployment names are consistent when set with configuration mapping""" + if os.path.exists(self.cfgmap): + fh = open(self.cfgmap, "r") + data = json.load(fh) + fh.close() + + for item in data['mappings']: + if item['real_name'] == actual_name: + return True + else: + continue + return False + else: + return True + + def _use_default_deployment_names(self): + """ Return default deployment names when no mapping is set""" + if os.path.exists(self.cfgmap): + return False + else: + return True \ No newline at end of file diff --git a/kube_utility_container/services/utility_container_client.py b/kube_utility_container/services/utility_container_client.py index 66f41dd8..8665d5ec 100644 --- a/kube_utility_container/services/utility_container_client.py +++ b/kube_utility_container/services/utility_container_client.py @@ -27,6 +27,8 @@ from kube_utility_container.services.exceptions import \ KubeEnvVarException from kube_utility_container.services.exceptions import \ KubePodNotFoundException +from kube_utility_container.services.dataloader import \ + DeploymentMapping from kubernetes import client as kubeclient from kubernetes import config as kubeconf @@ -39,7 +41,6 @@ from urllib3.exceptions import MaxRetryError LOG = logging.getLogger(__name__) - class UtilityContainerClient(object): """Client to execute utilscli command on utility containers""" @@ -175,6 +176,8 @@ class UtilityContainerClient(object): utility_container {V1Pod} -- Returns the first pod matched. :exception: KubePodNotFoundException -- Exception raised if not pods are found. """ + namesMapping = DeploymentMapping(deployment_name) + deployment_name = namesMapping._get_mapping_realname() deployment_selectors = self._get_deployment_selectors(deployment_name) utility_containers = self._corev1api_api_client.list_namespaced_pod( self.NAMESPACE, label_selector=deployment_selectors).items diff --git a/kube_utility_container/tests/unit/services/test_utility_dataloader.py b/kube_utility_container/tests/unit/services/test_utility_dataloader.py new file mode 100644 index 00000000..f59cf426 --- /dev/null +++ b/kube_utility_container/tests/unit/services/test_utility_dataloader.py @@ -0,0 +1,38 @@ +# Copyright 2020 AT&T Intellectual Property. All other rights reserved. +# +# 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. + +import unittest + +from kube_utility_container.services.dataloader \ + import DeploymentMapping + +class TestDeploymentNameMapping(unittest.TestCase): + """Unit tests for Utility Service Data Loader + Verify deployment name is consistent with the mapping. + Otherwise, no change. Default deployment names are used. + """ + + def setUp(self) -> None: + self.mapping = DeploymentMapping(self) + + def tearDown(self) -> None: + pass + + def test_deployment_name_is_consistent_with_name_mapping(self): + """ Verify the correct deployment names is returned when mapping is been used""" + self.assertTrue(self.mapping._is_deployment_name_consistent("clcp-etcd-utility")) + + def test_deployment_name_use_the_defaults(self): + """ Check if default deployment names are been used.""" + self.assertTrue(self.mapping._use_default_deployment_names()) \ No newline at end of file