From 6d0ff505113ca853fea82e5f0573a8edb96b63a6 Mon Sep 17 00:00:00 2001 From: Anumita Shenoy Date: Mon, 21 Feb 2022 19:06:48 +0530 Subject: [PATCH] Customcert and fix for non escaping values in helm (#4428) * Use userValues.txt instead of --resuse-values in update command * fix error msg * added custom cert * change setup.py * Helmupdatefix (#4) * Use userValues.txt instead of --resuse-values in update command * fix error msg Co-authored-by: Siri Teja Reddy Kasireddy * fix output file * Helmupdatefix (#5) * Use userValues.txt instead of --resuse-values in update command * fix error msg * fix output file Co-authored-by: Siri Teja Reddy Kasireddy * place values file in .azure folder * place values file in .azure folder * Helmupdatefix (#6) * Use userValues.txt instead of --resuse-values in update command * fix error msg * fix output file * place values file in .azure folder * place values file in .azure folder Co-authored-by: Siri Teja Reddy Kasireddy * place values file in .azure folder * nit * nit * nit * setp.py and history.rst updates * modify the way of fetching userValues.txt path * Waiting for LRO to complete before moving ahead with agent installation/deletion * update history.rst * fix * fix location variable Co-authored-by: Siri Teja Reddy Kasireddy Co-authored-by: siriteja <32883500+sirireddy12@users.noreply.github.com> --- src/connectedk8s/HISTORY.rst | 5 ++ .../azext_connectedk8s/_params.py | 2 +- src/connectedk8s/azext_connectedk8s/_utils.py | 1 + src/connectedk8s/azext_connectedk8s/custom.py | 48 ++++++++++++++----- src/connectedk8s/setup.py | 2 +- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/connectedk8s/HISTORY.rst b/src/connectedk8s/HISTORY.rst index 8cf543ef9f0..69a6c7c3e6b 100644 --- a/src/connectedk8s/HISTORY.rst +++ b/src/connectedk8s/HISTORY.rst @@ -2,6 +2,11 @@ Release History =============== +1.2.4 +++++++ + +* Custom cert changes, using "userValues.txt" for existing values in update command instead of --reuse-values, fix to wait for LRO to complete before starting agent installation/deletion + 1.2.3 ++++++ diff --git a/src/connectedk8s/azext_connectedk8s/_params.py b/src/connectedk8s/azext_connectedk8s/_params.py index 77223211f31..2621410e70e 100644 --- a/src/connectedk8s/azext_connectedk8s/_params.py +++ b/src/connectedk8s/azext_connectedk8s/_params.py @@ -44,7 +44,7 @@ def load_arguments(self, _): c.argument('https_proxy', options_list=['--proxy-https'], arg_group='Proxy', help='Https proxy URL to be used.') c.argument('http_proxy', options_list=['--proxy-http'], arg_group='Proxy', help='Http proxy URL to be used.') c.argument('no_proxy', options_list=['--proxy-skip-range'], arg_group='Proxy', help='List of URLs/CIDRs for which proxy should not to be used.') - c.argument('proxy_cert', options_list=['--proxy-cert'], arg_group='Proxy', type=file_type, completer=FilesCompleter(), help='Path to the certificate file for proxy') + c.argument('proxy_cert', options_list=['--proxy-cert'], arg_group='Proxy', type=file_type, completer=FilesCompleter(), help='Path to the any additional certificate file (for proxy as well)') c.argument('disable_proxy', options_list=['--disable-proxy'], arg_group='Proxy', action='store_true', help='Disables proxy settings for agents') c.argument('auto_upgrade', options_list=['--auto-upgrade'], help='Flag to enable/disable auto upgrade of arc agents. By default, auto upgrade of agents is enabled.', arg_type=get_enum_type(["true", "false"])) diff --git a/src/connectedk8s/azext_connectedk8s/_utils.py b/src/connectedk8s/azext_connectedk8s/_utils.py index 3ec025c2d76..4c87a356f03 100644 --- a/src/connectedk8s/azext_connectedk8s/_utils.py +++ b/src/connectedk8s/azext_connectedk8s/_utils.py @@ -322,6 +322,7 @@ def helm_install_release(chart_path, subscription_id, kubernetes_distro, kuberne cmd_helm_install.extend(["--set", "global.noProxy={}".format(no_proxy)]) if proxy_cert: cmd_helm_install.extend(["--set-file", "global.proxyCert={}".format(proxy_cert)]) + cmd_helm_install.extend(["--set", "global.isCustomCert={}".format(True)]) if https_proxy or http_proxy or no_proxy: cmd_helm_install.extend(["--set", "global.isProxyEnabled={}".format(True)]) if kube_config: diff --git a/src/connectedk8s/azext_connectedk8s/custom.py b/src/connectedk8s/azext_connectedk8s/custom.py index f66114fc499..4fde18967f2 100644 --- a/src/connectedk8s/azext_connectedk8s/custom.py +++ b/src/connectedk8s/azext_connectedk8s/custom.py @@ -181,7 +181,8 @@ def create_connectedk8s(cmd, client, resource_group_name, cluster_name, https_pr except Exception as e: # pylint: disable=broad-except utils.arm_exception_handler(e, consts.Get_ConnectedCluster_Fault_Type, 'Failed to check if connected cluster resource already exists.') cc = generate_request_payload(configuration, location, public_key, tags, kubernetes_distro, kubernetes_infra) - create_cc_resource(client, resource_group_name, cluster_name, cc, no_wait) + cc_response = create_cc_resource(client, resource_group_name, cluster_name, cc, no_wait).result() + return cc_response else: telemetry.set_exception(exception='The kubernetes cluster is already onboarded', fault_type=consts.Cluster_Already_Onboarded_Fault_Type, summary='Kubernetes cluster already onboarded') @@ -281,7 +282,7 @@ def create_connectedk8s(cmd, client, resource_group_name, cluster_name, https_pr cc = generate_request_payload(configuration, location, public_key, tags, kubernetes_distro, kubernetes_infra) # Create connected cluster resource - put_cc_response = create_cc_resource(client, resource_group_name, cluster_name, cc, no_wait) + put_cc_response = create_cc_resource(client, resource_group_name, cluster_name, cc, no_wait).result() # Checking if custom locations rp is registered and fetching oid if it is registered enable_custom_locations, custom_locations_oid = check_cl_registration_and_get_oid(cmd, cl_oid) @@ -679,7 +680,7 @@ def delete_connectedk8s(cmd, client, resource_group_name, cluster_name, release_namespace = get_release_namespace(kube_config, kube_context, helm_client_location) if not release_namespace: - delete_cc_resource(client, resource_group_name, cluster_name, no_wait) + delete_cc_resource(client, resource_group_name, cluster_name, no_wait).result() return # Loading config map @@ -704,7 +705,7 @@ def delete_connectedk8s(cmd, client, resource_group_name, cluster_name, summary='The resource cannot be deleted as user is using proxy kubeconfig.') raise ClientRequestError("az connectedk8s delete is not supported when using the Cluster Connect kubeconfig.", recommendation="Run the az connectedk8s delete command with your kubeconfig file pointing to the actual Kubernetes cluster to ensure that the agents are cleaned up successfully as part of the delete command.") - delete_cc_resource(client, resource_group_name, cluster_name, no_wait) + delete_cc_resource(client, resource_group_name, cluster_name, no_wait).result() else: telemetry.set_exception(exception='Unable to delete connected cluster', fault_type=consts.Bad_DeleteRequest_Fault_Type, summary='The resource cannot be deleted as kubernetes cluster is onboarded with some other resource id') @@ -752,9 +753,9 @@ def create_cc_resource(client, resource_group_name, cluster_name, cc, no_wait): def delete_cc_resource(client, resource_group_name, cluster_name, no_wait): try: - sdk_no_wait(no_wait, client.begin_delete, - resource_group_name=resource_group_name, - cluster_name=cluster_name) + return sdk_no_wait(no_wait, client.begin_delete, + resource_group_name=resource_group_name, + cluster_name=cluster_name) except Exception as e: utils.arm_exception_handler(e, consts.Delete_ConnectedCluster_Fault_Type, 'Unable to delete connected cluster resource') @@ -801,7 +802,7 @@ def update_agents(cmd, client, resource_group_name, cluster_name, https_proxy="" if https_proxy == "" and http_proxy == "" and no_proxy == "" and proxy_cert == "" and not disable_proxy and not auto_upgrade: raise RequiredArgumentMissingError(consts.No_Param_Error) - if (https_proxy or http_proxy or no_proxy or proxy_cert) and disable_proxy: + if (https_proxy or http_proxy or no_proxy) and disable_proxy: raise MutuallyExclusiveArgumentError(consts.EnableProxy_Conflict_Error) # Checking whether optional extra values file has been provided. @@ -879,9 +880,26 @@ def update_agents(cmd, client, resource_group_name, cluster_name, https_proxy="" # Get Helm chart path chart_path = utils.get_chart_path(registry_path, kube_config, kube_context, helm_client_location) + cmd_helm_values = [helm_client_location, "get", "values", "azure-arc", "--namespace", release_namespace] + if kube_config: + cmd_helm_values.extend(["--kubeconfig", kube_config]) + if kube_context: + cmd_helm_values.extend(["--kube-context", kube_context]) + + user_values_location = os.path.join(os.path.expanduser('~'), '.azure', 'userValues.txt') + existing_user_values = open(user_values_location, 'w+') + response_helm_values_get = Popen(cmd_helm_values, stdout=existing_user_values, stderr=PIPE) + _, error_helm_get_values = response_helm_values_get.communicate() + if response_helm_values_get.returncode != 0: + if ('forbidden' in error_helm_get_values.decode("ascii") or 'timed out waiting for the condition' in error_helm_get_values.decode("ascii")): + telemetry.set_user_fault() + telemetry.set_exception(exception=error_helm_get_values.decode("ascii"), fault_type=consts.Get_Helm_Values_Failed, + summary='Error while doing helm get values azure-arc') + raise CLIInternalError(str.format(consts.Update_Agent_Failure, error_helm_get_values.decode("ascii"))) + cmd_helm_upgrade = [helm_client_location, "upgrade", "azure-arc", chart_path, "--namespace", release_namespace, - "--reuse-values", - "--wait", "--output", "json"] + "-f", + user_values_location, "--wait", "--output", "json"] if values_file_provided: cmd_helm_upgrade.extend(["-f", values_file]) if auto_upgrade is not None: @@ -898,6 +916,7 @@ def update_agents(cmd, client, resource_group_name, cluster_name, https_proxy="" cmd_helm_upgrade.extend(["--set", "global.isProxyEnabled={}".format(False)]) if proxy_cert: cmd_helm_upgrade.extend(["--set-file", "global.proxyCert={}".format(proxy_cert)]) + cmd_helm_upgrade.extend(["--set", "global.isCustomCert={}".format(True)]) if kube_config: cmd_helm_upgrade.extend(["--kubeconfig", kube_config]) if kube_context: @@ -909,8 +928,15 @@ def update_agents(cmd, client, resource_group_name, cluster_name, https_proxy="" telemetry.set_user_fault() telemetry.set_exception(exception=error_helm_upgrade.decode("ascii"), fault_type=consts.Install_HelmRelease_Fault_Type, summary='Unable to install helm release') + try: + os.remove(user_values_location) + except OSError: + pass raise CLIInternalError(str.format(consts.Update_Agent_Failure, error_helm_upgrade.decode("ascii"))) - + try: + os.remove(user_values_location) + except OSError: + pass return str.format(consts.Update_Agent_Success, connected_cluster.name) diff --git a/src/connectedk8s/setup.py b/src/connectedk8s/setup.py index 66dc7977baa..df92c4d6167 100644 --- a/src/connectedk8s/setup.py +++ b/src/connectedk8s/setup.py @@ -17,7 +17,7 @@ # TODO: Confirm this is the right version number you want and it matches your # HISTORY.rst entry. -VERSION = '1.2.3' +VERSION = '1.2.4' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers