def helm_client(self): if self._helm_client is None: self._helm_client = HelmClient( self.client_config, self.helm_version, tls=self.helm_tls, tiller_namespace=self.tiller_namespace) return self._helm_client
def setUp(self): self.client = HelmClient('kubeconfig', '3.2.4')
class KubeDeploymentLocation(KubeDeploymentLocationBase): CRD_API_VERSION_PROP = 'crdApiVersion' CRD_API_VERSION_ALT2_PROP = 'crd_api_version' DRIVER_NAMESPACE_PROP = 'driverNamespace' DRIVER_NAMESPACE_ALT2_PROP = 'driver_namespace' CM_API_VERSION_PROP = 'cmApiVersion' CM_API_VERSION_ALT2_PROP = 'cm_api_version' CM_KIND_PROP = 'cmKind' CM_KIND_ALT2_PROP = 'cm_kind' CM_DATA_FIELD_PROP = 'cmDataField' CM_DATA_FIELD_ALT2_PROP = 'cm_data_field' #Helm HELM_VERSION_PROP = 'helmVersion' HELM_VERSION_ALT2_PROP = 'helm_version' HELM_VERSION_ALT3_PROP = 'helm.version' HELM_TLS_ENABLED_PROP = 'helm.tls.enabled' HELM_TLS_CA_CERT_PROP = 'helm.tls.cacert' HELM_TLS_CA_CERT_ALT2_PROP = 'helm.tls.ca_cert' HELM_TLS_CERT_PROP = 'helm.tls.cert' HELM_TLS_KEY_PROP = 'helm.tls.key' TILLER_NAMESPACE_PROP = 'tillerNamespace' TILLER_NAMESPACE_ALT_PROP = 'tiller_namespace' @staticmethod def from_dict(dl_data): name = dl_data.get(KubeDeploymentLocationBase.NAME) if name is None: raise InvalidDeploymentLocationError( 'Deployment location missing \'{0}\' value'.format( KubeDeploymentLocationBase.NAME)) properties = dl_data.get(KubeDeploymentLocationBase.PROPERTIES) if properties is None: raise InvalidDeploymentLocationError( 'Deployment location missing \'{0}\' value'.format( KubeDeploymentLocationBase.PROPERTIES)) client_config = get_property_or_default( properties, KubeDeploymentLocationBase.CONFIG_PROP, KubeDeploymentLocationBase.CONFIG_ALT2_PROP, error_if_not_found=True) if type(client_config) is str: client_config = yaml.safe_load(client_config) kwargs = {} crd_api_version = get_property_or_default( properties, KubeDeploymentLocation.CRD_API_VERSION_PROP, KubeDeploymentLocation.CRD_API_VERSION_ALT2_PROP) if crd_api_version is not None: kwargs['crd_api_version'] = crd_api_version driver_namespace = get_property_or_default( properties, KubeDeploymentLocation.DRIVER_NAMESPACE_PROP, KubeDeploymentLocation.DRIVER_NAMESPACE_ALT2_PROP) if driver_namespace is not None: kwargs['driver_namespace'] = driver_namespace cm_api_version = get_property_or_default( properties, KubeDeploymentLocation.CM_API_VERSION_PROP, KubeDeploymentLocation.CM_API_VERSION_ALT2_PROP) if cm_api_version is not None: kwargs['cm_api_version'] = cm_api_version cm_kind = get_property_or_default( properties, KubeDeploymentLocation.CM_KIND_PROP, KubeDeploymentLocation.CM_KIND_ALT2_PROP) if cm_kind is not None: kwargs['cm_kind'] = cm_kind cm_data_field = get_property_or_default( properties, KubeDeploymentLocation.CM_DATA_FIELD_PROP, KubeDeploymentLocation.CM_DATA_FIELD_ALT2_PROP) if cm_data_field is not None: kwargs['cm_data_field'] = cm_data_field default_object_namespace = get_property_or_default( properties, KubeDeploymentLocationBase.DEFAULT_OBJECT_NAMESPACE_PROP, KubeDeploymentLocationBase.DEFAULT_OBJECT_NAMESPACE_ALT2_PROP) if default_object_namespace is not None: kwargs['default_object_namespace'] = default_object_namespace helm_version = get_property_or_default( properties, KubeDeploymentLocation.HELM_VERSION_PROP, KubeDeploymentLocation.HELM_VERSION_ALT2_PROP, KubeDeploymentLocation.HELM_VERSION_ALT3_PROP) if helm_version is not None: kwargs['helm_version'] = helm_version helm_tls_enabled = get_property_or_default( properties, KubeDeploymentLocation.HELM_TLS_ENABLED_PROP) if helm_tls_enabled is not None: if type(helm_tls_enabled) == str: helm_tls_enabled = helm_tls_enabled.lower() in [ 'True', 'true', 'yes', 't', 'y' ] if helm_tls_enabled: kwargs['helm_tls'] = HelmTls(enabled=True) kwargs['helm_tls'].ca_cert = get_property_or_default( properties, KubeDeploymentLocation.HELM_TLS_CA_CERT_PROP, KubeDeploymentLocation.HELM_TLS_CA_CERT_ALT2_PROP) kwargs['helm_tls'].cert = get_property_or_default( properties, KubeDeploymentLocation.HELM_TLS_CERT_PROP) kwargs['helm_tls'].key = get_property_or_default( properties, KubeDeploymentLocation.HELM_TLS_KEY_PROP) tiller_namespace = get_property_or_default( properties, KubeDeploymentLocation.TILLER_NAMESPACE_PROP, KubeDeploymentLocation.TILLER_NAMESPACE_ALT_PROP) if tiller_namespace is not None: kwargs['tiller_namespace'] = tiller_namespace return KubeDeploymentLocation(name, client_config, **kwargs) def __init__(self, name, client_config, default_object_namespace=DEFAULT_NAMESPACE, crd_api_version=None, driver_namespace=None, \ cm_api_version='v1', cm_kind='ConfigMap', cm_data_field='data', helm_version='2.16.9', helm_tls=None, tiller_namespace=None): super().__init__(name, client_config, default_object_namespace=default_object_namespace) self.crd_api_version = crd_api_version self.cm_api_version = cm_api_version self.cm_kind = cm_kind self.cm_data_field = cm_data_field self.driver_namespace = driver_namespace if self.driver_namespace is None: self.driver_namespace = self.default_object_namespace self.helm_version = helm_version self.helm_tls = helm_tls self._client = None self._helm_client = None self.tiller_namespace = tiller_namespace @property def client(self): if self._client is None: config_file_path = super().write_config_file() try: self._client = kubeconfig.new_client_from_config( config_file_path, persist_config=False) finally: if os.path.exists(config_file_path): os.remove(config_file_path) return self._client @property def helm_client(self): if self._helm_client is None: self._helm_client = HelmClient( self.client_config, self.helm_version, tls=self.helm_tls, tiller_namespace=self.tiller_namespace) return self._helm_client def clean(self): self.clear_config_files() if self._helm_client is not None: self._helm_client.close() self._helm_client = None def get_cm_persister_args(self): args = {} if self.cm_api_version is not None: args['cm_api_version'] = self.cm_api_version if self.cm_kind is not None: args['cm_kind'] = self.cm_kind if self.cm_data_field is not None: args['cm_data_field'] = self.cm_data_field return args def to_dict(self): data = super().to_dict() data[KubeDeploymentLocationBase.PROPERTIES].update({ KubeDeploymentLocation.CRD_API_VERSION_PROP: self.crd_api_version, KubeDeploymentLocation.DRIVER_NAMESPACE_PROP: self.driver_namespace, KubeDeploymentLocation.CM_API_VERSION_PROP: self.cm_api_version, KubeDeploymentLocation.CM_KIND_PROP: self.cm_kind, KubeDeploymentLocation.CM_DATA_FIELD_PROP: self.cm_data_field, KubeDeploymentLocation.HELM_VERSION_PROP: self.helm_version, KubeDeploymentLocation.HELM_TLS_ENABLED_PROP: self.helm_tls.enabled if self.helm_tls is not None else None, KubeDeploymentLocation.HELM_TLS_CA_CERT_PROP: self.helm_tls.ca_cert if self.helm_tls is not None else None, KubeDeploymentLocation.HELM_TLS_CERT_PROP: self.helm_tls.cert if self.helm_tls is not None else None, KubeDeploymentLocation.HELM_TLS_KEY_PROP: self.helm_tls.key if self.helm_tls is not None else None, KubeDeploymentLocation.TILLER_NAMESPACE_PROP: self.tiller_namespace if self.tiller_namespace is not None else None, }) return data
class TestHelmClient3(unittest.TestCase): """ The kubernetes driver supports multiple versions of helm that have different syntax for the helm commands. This class is to test actions using the Helm 2 syntax. """ def setUp(self): self.client = HelmClient('kubeconfig', '3.2.4') def tearDown(self): self.client.close() def __mock_subprocess_response(self, mock_subprocess, returncode, stdout): mock_subprocess.run.return_value = MagicMock(returncode=returncode, stdout=stdout) @patch('kubedriver.helmclient.client.subprocess') def test_install(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) name = self.client.install('chart', 'name', 'namespace') self.assertEqual(name, 'name') @patch('kubedriver.helmclient.client.subprocess') def test_install_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.install, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_install_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.install, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) name = self.client.upgrade('chart', 'name', 'namespace') self.assertEqual(name, 'name') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.upgrade, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.upgrade, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_delete(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) result = self.client.delete('name', 'namespace') self.assertEqual(result, None) @patch('kubedriver.helmclient.client.subprocess') def test_delete_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.delete, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_delete_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.delete, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_purge(self, mock_subprocess): self.client = HelmClient('kubeconfig', '3.2.4') self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) result = self.client.purge('name', 'namespace') self.assertEqual(result, None) @patch('kubedriver.helmclient.client.subprocess') def test_purge_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.purge, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_purge_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.purge, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_safe_get(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) success, helm_release = self.client.safe_get('name', 'namespace') self.assertEqual(success, True) self.assertIsInstance(helm_release, HelmReleaseDetails) self.assertEqual(helm_release.revision, 1) self.assertEqual(helm_release.last_deployed, 'Fri Jul 3 13:48:31 2020') self.assertEqual(helm_release.chart, None) @patch('kubedriver.helmclient.client.subprocess') def test_safe_get_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.safe_get, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_safe_get_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.safe_get, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_get_helm_3(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) helm_release = self.client.get('myhelm', 'default') self.assertIsInstance(helm_release, HelmReleaseDetails) self.assertEqual(helm_release.name, 'myhelm') self.assertEqual(helm_release.last_deployed, 'Fri Jul 3 13:48:31 2020') self.assertEqual(helm_release.namespace, 'default') self.assertEqual(helm_release.status, 'deployed') self.assertEqual(helm_release.revision, 1) self.assertEqual(helm_release.user_supplied_values, {'valueA': { 'mapKeyA': 'mapValueA' }}) self.assertEqual( helm_release.computed_values, { 'affinity': {}, 'image': { 'pullPolicy': 'IfNotPresent' }, 'tolerations': [] }) self.assertEqual(helm_release.manifest, [{ 'apiVersion': 'v1', 'kind': 'Service', 'metadata': { 'name': 'myhelm-mychart', 'labels': { 'app': 'mychart', } }, 'spec': { 'type': 'ClusterIP' } }, { "apiVersion": "apps/v1beta2", "kind": "Deployment", "metadata": { "name": "myhelm-mychart" }, "spec": { "replicas": 1 } }]) @patch('kubedriver.helmclient.client.subprocess') def test_get_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.get, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_get_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.get, 'name', 'namespace')
def test_purge(self, mock_subprocess): self.client = HelmClient('kubeconfig', '3.2.4') self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) result = self.client.purge('name', 'namespace') self.assertEqual(result, None)
def helm_client(self): if self._helm_client is None: self._helm_client = HelmClient(self.client_config, self.helm_version, tls=self.helm_tls) return self._helm_client
def setUp(self): self.client = HelmClient('kubeconfig', '2.16.6')
class TestHelmClient2(unittest.TestCase): """ The kubernetes driver supports multiple versions of helm that have different syntax for the helm commands. This class is to test actions using the Helm 2 syntax. """ def setUp(self): self.client = HelmClient('kubeconfig', '2.16.6') def tearDown(self): self.client.close() def __mock_subprocess_response(self, mock_subprocess, returncode, stdout): mock_subprocess.run.return_value = MagicMock(returncode=returncode, stdout=stdout) @patch('kubedriver.helmclient.client.subprocess') def test_install(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) name = self.client.install('chart', 'name', 'namespace') self.assertEqual(name, 'name') @patch('kubedriver.helmclient.client.subprocess') def test_install_wait(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) name = self.client.install(chart='chart', name='name', namespace='namespace', wait=True, timeout=30) self.assertEqual(name, 'name') @patch('kubedriver.helmclient.client.subprocess') def test_install_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.install, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_install_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.install, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) name = self.client.upgrade('chart', 'name', 'namespace') self.assertEqual(name, 'name') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade_wait(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) name = self.client.upgrade(chart='chart', name='name', namespace='namespace', wait=True, timeout=30) self.assertEqual(name, 'name') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.upgrade, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_upgrade_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.upgrade, 'chart', 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_delete(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) result = self.client.delete('name', 'namespace') self.assertEqual(result, None) @patch('kubedriver.helmclient.client.subprocess') def test_delete_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.delete, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_delete_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.delete, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_purge(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) result = self.client.purge('name', 'namespace') self.assertEqual(result, None) @patch('kubedriver.helmclient.client.subprocess') def test_purge_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.purge, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_purge_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.purge, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_safe_get(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) success, helm_release = self.client.safe_get('name', 'namespace') self.assertEqual(success, True) self.assertIsInstance(helm_release, HelmReleaseDetails) self.assertEqual(helm_release.revision, 1) self.assertEqual(helm_release.released, 'Wed May 13 13:03:30 2020') self.assertEqual(helm_release.chart, 'example-chart-0.9.0') @patch('kubedriver.helmclient.client.subprocess') def test_safe_get_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.safe_get, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_safe_get_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.safe_get, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_get(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 0, EXAMPLE_MANIFEST) helm_release = self.client.get('example', 'namespace') self.assertIsInstance(helm_release, HelmReleaseDetails) self.assertEqual(helm_release.revision, 1) self.assertEqual(helm_release.released, 'Wed May 13 13:03:30 2020') self.assertEqual(helm_release.chart, 'example-chart-0.9.0') self.assertEqual(helm_release.user_supplied_values, { 'valueA': { 'mapKeyA': 'mapValueA' } }) self.assertEqual(helm_release.computed_values, { 'valueA': { 'mapKeyA': 'mapValueA' }, 'valueB': {}, 'valueC': 10 }) self.assertEqual(helm_release.manifest, [ { 'apiVersion': 'v1', 'kind': 'ServiceAccount', 'metadata': { 'name': 'example' } }, { 'apiVersion': 'v1', 'kind': 'ConfigMap', 'metadata': { 'name': 'example' }, 'data': { 'someValue': 10 } } ]) @patch('kubedriver.helmclient.client.subprocess') def test_get_helm_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 1, EXAMPLE_MANIFEST) self.assertRaises(HelmError, self.client.get, 'name', 'namespace') @patch('kubedriver.helmclient.client.subprocess') def test_get_command_error(self, mock_subprocess): self.__mock_subprocess_response(mock_subprocess, 127, EXAMPLE_MANIFEST) self.assertRaises(HelmCommandNotFoundError, self.client.get, 'name', 'namespace')