diff --git a/magnum_capi_helm/conf.py b/magnum_capi_helm/conf.py index e0f198f..51cea68 100644 --- a/magnum_capi_helm/conf.py +++ b/magnum_capi_helm/conf.py @@ -58,7 +58,7 @@ ), cfg.StrOpt( "default_helm_chart_version", - default="0.1.4", + default="0.1.6", help=( "Version of the helm chart specified " "by the config: capi_driver.helm_chart_repo " diff --git a/magnum_capi_helm/driver.py b/magnum_capi_helm/driver.py index c4ce52b..ec21eab 100644 --- a/magnum_capi_helm/driver.py +++ b/magnum_capi_helm/driver.py @@ -538,6 +538,9 @@ def _get_kube_dash_enabled(self, cluster): def _get_autoheal_enabled(self, cluster): return self._get_label_bool(cluster, "auto_healing_enabled", True) + def _get_k8s_keystone_auth_enabled(self, cluster): + return self._get_label_bool(cluster, "keystone_auth_enabled", True) + def _get_fixed_network_id(self, context, cluster): network = cluster.fixed_network if not network: @@ -690,6 +693,25 @@ def _update_helm_release(self, context, cluster, nodegroups=None): } values = helm.mergeconcat(values, network_details) + if self._get_k8s_keystone_auth_enabled(cluster): + k8s_keystone_auth_config = { + "authWebhook": "k8s-keystone-auth", + "openstack": { + "k8sKeystoneAuth": { # addon subchart configuration + "enabled": True, + "values": { + "openstackAuthUrl": context.auth_url, + "projectId": context.project_id, + }, + } + }, + } + values = helm.mergeconcat(values, k8s_keystone_auth_config) + LOG.debug( + "Enable K8s keystone auth webhook for" + f" project: {context.project_id} auth url: {context.auth_url}" + ) + self._helm_client.install_or_upgrade( driver_utils.chart_release_name(cluster), CONF.capi_helm.helm_chart_name, diff --git a/magnum_capi_helm/tests/test_driver.py b/magnum_capi_helm/tests/test_driver.py index 1259ecc..3104de3 100644 --- a/magnum_capi_helm/tests/test_driver.py +++ b/magnum_capi_helm/tests/test_driver.py @@ -1187,6 +1187,9 @@ def _get_cluster_helm_standard_values(self): "machineSSHKeyName": None, } + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object(neutron, "get_network", autospec=True) @mock.patch.object( @@ -1205,6 +1208,7 @@ def test_create_cluster( mock_certs, mock_get_net, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ( "imageid1", @@ -1245,6 +1249,9 @@ def test_create_cluster( ) self.assertEqual([], mock_get_net.call_args_list) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object( driver.Driver, "_ensure_certificate_secrets", autospec=True @@ -1261,6 +1268,7 @@ def test_create_cluster_no_dns( mock_appcred, mock_certs, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ("imageid1", "1.27.4", "ubuntu") mock_client = mock.MagicMock(spec=kubernetes.Client) @@ -1296,6 +1304,9 @@ def test_create_cluster_no_dns( self.driver, self.context, self.cluster_obj ) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object( driver.Driver, "_ensure_certificate_secrets", autospec=True @@ -1312,6 +1323,7 @@ def test_create_cluster_boot_volume( mock_appcred, mock_certs, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ("imageid1", "1.27.4", "ubuntu") mock_client = mock.MagicMock(spec=kubernetes.Client) @@ -1356,6 +1368,9 @@ def test_create_cluster_boot_volume( self.driver, self.context, self.cluster_obj ) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object( driver.Driver, "_ensure_certificate_secrets", autospec=True @@ -1372,6 +1387,7 @@ def test_create_cluster_boot_volume_extra_network( mock_appcred, mock_certs, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ( "imageid1", @@ -1432,6 +1448,9 @@ def test_create_cluster_boot_volume_extra_network( self.driver, self.context, self.cluster_obj ) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object(driver.Driver, "_ensure_certificate_secrets") @mock.patch.object(driver.Driver, "_create_appcred_secret") @@ -1446,6 +1465,7 @@ def test_create_cluster_with_keypair( mock_appcred, mock_certs, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ( "imageid1", @@ -1479,6 +1499,9 @@ def test_create_cluster_with_keypair( mock_appcred.assert_called_once_with(self.context, self.cluster_obj) mock_certs.assert_called_once_with(self.context, self.cluster_obj) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object(driver.Driver, "_ensure_certificate_secrets") @mock.patch.object(driver.Driver, "_create_appcred_secret") @@ -1493,6 +1516,7 @@ def test_create_cluster_flatcar( mock_appcred, mock_certs, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ( "imageid1", @@ -1522,6 +1546,9 @@ def test_create_cluster_flatcar( mock_appcred.assert_called_once_with(self.context, self.cluster_obj) mock_certs.assert_called_once_with(self.context, self.cluster_obj) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) @mock.patch.object(driver.Driver, "_validate_allowed_flavor") @mock.patch.object( driver.Driver, "_ensure_certificate_secrets", autospec=True @@ -1538,6 +1565,7 @@ def test_create_cluster_no_autoheal( mock_appcred, mock_certs, mock_validate_allowed_flavor, + mock_get_keystone_auth_enabled, ): mock_image.return_value = ("imageid1", "1.27.4", "ubuntu") mock_client = mock.MagicMock(spec=kubernetes.Client) @@ -1762,6 +1790,79 @@ def test_delete_nodegroup(self, mock_update): mock_update.call_args.args[2][0].as_dict(), ) + @mock.patch.object( + driver.Driver, "_get_k8s_keystone_auth_enabled", return_value=False + ) + @mock.patch.object(neutron, "get_network", autospec=True) + @mock.patch.object( + driver.Driver, "_ensure_certificate_secrets", autospec=True + ) + @mock.patch.object(driver.Driver, "_create_appcred_secret", autospec=True) + @mock.patch.object(kubernetes.Client, "load", autospec=True) + @mock.patch.object(driver.Driver, "_get_image_details", autospec=True) + @mock.patch.object(helm.Client, "install_or_upgrade", autospec=True) + def test_k8s_keystone_auth_not_enabled( + self, + mock_install, + mock_image, + mock_load, + mock_appcred, + mock_certs, + mock_get_net, + mock_get_keystone_auth_enabled, + ): + mock_image.return_value = ( + "imageid1", + "1.27.4", + "ubuntu", + ) + mock_client = mock.MagicMock(spec=kubernetes.Client) + mock_load.return_value = mock_client + mock_get_net.side_effect = ( + lambda c, net, source, target, external: f"{net}-{external}" + ) + self.driver._update_helm_release(self.context, self.cluster_obj) + mock_install.assert_called() + values = mock_install.call_args.args[3] + # self.assertIn("kubernetesVersion", values) + # print("values: %s" % values["kubernetesVersion"]) + self.assertNotIn("authWebhook", values) + + @mock.patch.object(neutron, "get_network", autospec=True) + @mock.patch.object( + driver.Driver, "_ensure_certificate_secrets", autospec=True + ) + @mock.patch.object(driver.Driver, "_create_appcred_secret", autospec=True) + @mock.patch.object(kubernetes.Client, "load", autospec=True) + @mock.patch.object(driver.Driver, "_get_image_details", autospec=True) + @mock.patch.object(helm.Client, "install_or_upgrade", autospec=True) + def test_k8s_keystone_auth_enabled( + self, + mock_install, + mock_image, + mock_load, + mock_appcred, + mock_certs, + mock_get_net, + ): + # CONF.capi_helm.k8s_keystone_auth_enabled = True + mock_image.return_value = ( + "imageid1", + "1.27.4", + "ubuntu", + ) + mock_client = mock.MagicMock(spec=kubernetes.Client) + mock_load.return_value = mock_client + mock_get_net.side_effect = ( + lambda c, net, source, target, external: f"{net}-{external}" + ) + self.driver._update_helm_release(self.context, self.cluster_obj) + mock_install.assert_called() + values = mock_install.call_args.args[3] + self.assertIn("authWebhook", values) + k8s_keystone_auth_conf = values["openstack"]["k8sKeystoneAuth"] + self.assertEqual(k8s_keystone_auth_conf["enabled"], True) + def test_create_federation(self): self.assertRaises( NotImplementedError,