diff --git a/src/connectedk8s/HISTORY.rst b/src/connectedk8s/HISTORY.rst index 63dd80a20ff..5f7ce0b8ab0 100644 --- a/src/connectedk8s/HISTORY.rst +++ b/src/connectedk8s/HISTORY.rst @@ -3,12 +3,6 @@ Release History =============== -1.5.5 -++++++ -* Deprecate '--app-id' and '--app-secret' RBAC params. -* Use 1P apps for authN/authZ when RBAC is enabled. -* Add warning to use kubelogin version v0.0.32 or higher which has support for generating PoP token. - 1.5.4 ++++++ * Log debug if 'arcConfigEndpoint' doesn't exist in 'dataplaneEndpoints' ARM metadata. @@ -92,7 +86,7 @@ Release History 1.3.10 ++++++ * Added CLI heuristics change -* Added AKS IOT infra support +* Added AKS IOT infra support * Bug Fix in precheckutils 1.3.9 diff --git a/src/connectedk8s/azext_connectedk8s/_constants.py b/src/connectedk8s/azext_connectedk8s/_constants.py index 62ed0fdca41..485075e5d39 100644 --- a/src/connectedk8s/azext_connectedk8s/_constants.py +++ b/src/connectedk8s/azext_connectedk8s/_constants.py @@ -118,6 +118,7 @@ Operate_RG_Cluster_Name_Conflict = 'The provided cluster name and rg correspond to different cluster being operated on' Custom_Locations_Registration_Check_Fault_Type = "Error while checking resource provider registration of custom locations." Custom_Locations_OID_Fetch_Fault_Type = "Error while fetching oid for custom locations." +Application_Details_Not_Provided_For_Azure_RBAC_Fault = 'Application ID or secret not provided for Azure RBAC' Successfully_Enabled_Features = 'Successsfully enabled features: {} for the Connected Cluster {}' Successfully_Disabled_Features = 'Successsfully disabled features: {} for the Connected Cluster {}' Error_enabling_Features = 'Error while updating agents for enabling features. Please run \"kubectl get pods -n azure-arc\" to check the pods in case of timeout error. Error: {}' diff --git a/src/connectedk8s/azext_connectedk8s/_help.py b/src/connectedk8s/azext_connectedk8s/_help.py index 7fdb2fdf63b..2fbb29b112b 100644 --- a/src/connectedk8s/azext_connectedk8s/_help.py +++ b/src/connectedk8s/azext_connectedk8s/_help.py @@ -109,7 +109,7 @@ - name: Enables the Cluster-Connect feature. text: az connectedk8s enable-features -n clusterName -g resourceGroupName --features cluster-connect - name: Enable Azure RBAC feature. - text: az connectedk8s enable-features -n clusterName -g resourceGroupName --features azure-rbac --skip-azure-rbac-list "user1@domain.com,spn_oid" + text: az connectedk8s enable-features -n clusterName -g resourceGroupName --features azure-rbac --app-id appID --app-secret="appSecret" --skip-azure-rbac-list "user1@domain.com,spn_oid" - name: Enable multiple features. text: az connectedk8s enable-features -n clusterName -g resourceGroupName --features cluster-connect custom-locations """ diff --git a/src/connectedk8s/azext_connectedk8s/_params.py b/src/connectedk8s/azext_connectedk8s/_params.py index 3fb7931f8ba..042b4d2081b 100644 --- a/src/connectedk8s/azext_connectedk8s/_params.py +++ b/src/connectedk8s/azext_connectedk8s/_params.py @@ -80,8 +80,8 @@ def load_arguments(self, _): c.argument('kube_config', options_list=['--kube-config'], help='Path to the kube config file.') c.argument('kube_context', options_list=['--kube-context'], help='Kubconfig context from current machine.') c.argument('features', features_types, options_list=['--features'], help='Space-separated list of features you want to enable.') - c.argument('azrbac_client_id', options_list=['--app-id'], arg_group='Azure RBAC', help='Application ID for enabling Azure RBAC.', deprecate_info=c.deprecate(hide=True)) - c.argument('azrbac_client_secret', options_list=['--app-secret'], arg_group='Azure RBAC', help='Application secret for enabling Azure RBAC.', deprecate_info=c.deprecate(hide=True)) + c.argument('azrbac_client_id', options_list=['--app-id'], arg_group='Azure RBAC', help='Application ID for enabling Azure RBAC. Specify when enabling azure-rbac.') + c.argument('azrbac_client_secret', options_list=['--app-secret'], arg_group='Azure RBAC', help='Application secret for enabling Azure RBAC. Specify when enabling azure-rbac.') c.argument('azrbac_skip_authz_check', options_list=['--skip-azure-rbac-list'], arg_group='Azure RBAC', help='Comma separated list of names of usernames/email/oid. Azure RBAC will be skipped for these users. Specify when enabling azure-rbac.') c.argument('cl_oid', options_list=['--custom-locations-oid'], help="OID of 'custom-locations' app") diff --git a/src/connectedk8s/azext_connectedk8s/custom.py b/src/connectedk8s/azext_connectedk8s/custom.py index a8785687199..b75132b0ffa 100644 --- a/src/connectedk8s/azext_connectedk8s/custom.py +++ b/src/connectedk8s/azext_connectedk8s/custom.py @@ -1396,6 +1396,10 @@ def enable_features(cmd, client, resource_group_name, cluster_name, features, ku raise InvalidArgumentValueError("The features 'cluster-connect' and 'custom-locations' cannot be enabled for a private link enabled connected cluster.") if enable_azure_rbac: + if (azrbac_client_id is None) or (azrbac_client_secret is None): + telemetry.set_exception(exception='Application ID or secret is not provided for Azure RBAC', fault_type=consts.Application_Details_Not_Provided_For_Azure_RBAC_Fault, + summary='Application id, application secret is required to enable/update Azure RBAC feature') + raise RequiredArgumentMissingError("Please provide Application id, application secret to enable/update Azure RBAC feature") if azrbac_skip_authz_check is None: azrbac_skip_authz_check = "" azrbac_skip_authz_check = escape_proxy_settings(azrbac_skip_authz_check) @@ -1483,9 +1487,8 @@ def enable_features(cmd, client, resource_group_name, cluster_name, features, ku cmd_helm_upgrade.extend(["--kube-context", kube_context]) if enable_azure_rbac: cmd_helm_upgrade.extend(["--set", "systemDefaultValues.guard.enabled=true"]) - # Setting the default authnMode mode as "arc" for guard. This mode uses PoP token based auth. and Arc RBAC 1P apps for authN/authZ. - cmd_helm_upgrade.extend(["--set", "systemDefaultValues.guard.authnMode=arc"]) - logger.warning("Please use the kubelogin version v0.0.32 or higher which has support for generating PoP token(s). This is needed by guard running in 'arc' authN mode.") + cmd_helm_upgrade.extend(["--set", "systemDefaultValues.guard.clientId={}".format(azrbac_client_id)]) + cmd_helm_upgrade.extend(["--set", "systemDefaultValues.guard.clientSecret={}".format(azrbac_client_secret)]) cmd_helm_upgrade.extend(["--set", "systemDefaultValues.guard.skipAuthzCheck={}".format(azrbac_skip_authz_check)]) if enable_cluster_connect: cmd_helm_upgrade.extend(["--set", "systemDefaultValues.clusterconnect-agent.enabled=true"]) diff --git a/src/connectedk8s/azext_connectedk8s/tests/latest/test_connectedk8s_scenario.py b/src/connectedk8s/azext_connectedk8s/tests/latest/test_connectedk8s_scenario.py index 4cd16f7f77f..a0734055927 100644 --- a/src/connectedk8s/azext_connectedk8s/tests/latest/test_connectedk8s_scenario.py +++ b/src/connectedk8s/azext_connectedk8s/tests/latest/test_connectedk8s_scenario.py @@ -150,8 +150,9 @@ class Connectedk8sScenarioTest(LiveScenarioTest): @live_only() @ResourceGroupPreparer(name_prefix='conk8stest', location=CONFIG['location'], random_name_length=16) def test_connect(self,resource_group): + managed_cluster_name = self.create_random_name(prefix='test-connect', length=24) - kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) + kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) self.kwargs.update({ 'rg': resource_group, 'name': self.create_random_name(prefix='cc-', length=12), @@ -180,7 +181,7 @@ def test_connect(self,resource_group): def test_forcedelete(self,resource_group): managed_cluster_name = self.create_random_name(prefix='test-force-delete', length=24) - kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) + kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) self.kwargs.update({ 'rg': resource_group, 'name': self.create_random_name(prefix='cc-', length=12), @@ -239,7 +240,7 @@ def test_enable_disable_features(self,resource_group): 'rbac_app_secret': CONFIG['rbacAppSecret'], 'location': CONFIG['location'] }) - + self.cmd('aks create -g {rg} -n {managed_cluster_name} --generate-ssh-keys') self.cmd('aks get-credentials -g {rg} -n {managed_cluster_name} -f {kubeconfig} --admin') self.cmd('connectedk8s connect -g {rg} -n {name} -l {location} --tags foo=doo --kube-config {kubeconfig} --kube-context {managed_cluster_name}-admin', checks=[ @@ -298,7 +299,7 @@ def test_enable_disable_features(self,resource_group): assert(enabled_cmd1["systemDefaultValues"]['customLocations']['enabled'] == bool(1)) assert(enabled_cmd1["systemDefaultValues"]['clusterconnect-agent']['enabled'] == bool(1)) - # scenario-4: azure rbac turned off and turning azure rbac on again using 1P + # scenario-4: azure rbac turned off and turning azure rbac on again using app id and app secret self.cmd('connectedk8s disable-features -n {name} -g {rg} --features azure-rbac --kube-config {kubeconfig} --kube-context {managed_cluster_name}-admin -y') cmd_output1 = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE) _, error_helm_delete = cmd_output1.communicate() @@ -306,7 +307,7 @@ def test_enable_disable_features(self,resource_group): disabled_cmd1 = json.loads(cmd_output1.communicate()[0].strip()) assert(disabled_cmd1["systemDefaultValues"]['guard']['enabled'] == bool(0)) - self.cmd('az connectedk8s enable-features -n {name} -g {rg} --kube-config {kubeconfig} --kube-context {managed_cluster_name}-admin --features azure-rbac') + self.cmd('az connectedk8s enable-features -n {name} -g {rg} --kube-config {kubeconfig} --kube-context {managed_cluster_name}-admin --features azure-rbac --app-id {rbac_app_id} --app-secret {rbac_app_secret}') # deleting the cluster self.cmd('connectedk8s delete -g {rg} -n {name} --kube-config {kubeconfig} --kube-context {managed_cluster_name}-admin -y') @@ -322,14 +323,14 @@ def test_connectedk8s_list(self,resource_group): managed_cluster_name = self.create_random_name(prefix='first', length=24) managed_cluster_name_second = self.create_random_name(prefix='second', length=24) - kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) + kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) kubeconfigpls="%s" % (_get_test_data_file('pls-config.yaml')) name = self.create_random_name(prefix='cc-', length=12) name_second = self.create_random_name(prefix='cc-', length=12) managed_cluster_list=[] managed_cluster_list.append(name) managed_cluster_list.append(name_second) - managed_cluster_list.sort() + managed_cluster_list.sort() self.kwargs.update({ 'rg': resource_group, 'name': name, @@ -395,7 +396,7 @@ def test_connectedk8s_list(self,resource_group): def test_upgrade(self,resource_group): managed_cluster_name = self.create_random_name(prefix='test-upgrade', length=24) - kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) + kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) self.kwargs.update({ 'name': self.create_random_name(prefix='cc-', length=12), 'rg': resource_group, @@ -460,7 +461,7 @@ def test_upgrade(self,resource_group): @ResourceGroupPreparer(name_prefix='conk8stest', location=CONFIG['location'], random_name_length=16) def test_update(self,resource_group): managed_cluster_name = self.create_random_name(prefix='test-update', length=24) - kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) + kubeconfig="%s" % (_get_test_data_file(managed_cluster_name + '-config.yaml')) self.kwargs.update({ 'name': self.create_random_name(prefix='cc-', length=12), 'kubeconfig': kubeconfig,