diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index b83cf078c95..f963d2c9971 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to Pending +++++++ +0.5.76 +++++++ +* Add support for Custom CA Trust in `az aks create`, `az aks nodepool add`, `az aks nodepool update`. + 0.5.75 ++++++ diff --git a/src/aks-preview/azcli_aks_live_test/configs/ext_matrix_default.json b/src/aks-preview/azcli_aks_live_test/configs/ext_matrix_default.json index ebb4fd26e25..5c35d735573 100644 --- a/src/aks-preview/azcli_aks_live_test/configs/ext_matrix_default.json +++ b/src/aks-preview/azcli_aks_live_test/configs/ext_matrix_default.json @@ -27,7 +27,8 @@ "test_aks_snapshot", "test_aks_custom_kubelet_identity", "test_aks_nodepool_add_with_ossku_windows2022", - "test_list_trustedaccess_roles" + "test_list_trustedaccess_roles", + "test_aks_custom_ca_trust_flow" ] } } \ No newline at end of file diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index 633c9998a0d..4cbbd2a6477 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -441,6 +441,9 @@ - name: --dns-zone-resource-id type: string short-summary: The resource ID of the DNS zone resource to use with the web_application_routing addon. + - name: --enable-custom-ca-trust + type: bool + short-summary: Enable Custom CA Trust on agent node pool. examples: - name: Create a Kubernetes cluster with an existing SSH public key. text: az aks create -g MyResourceGroup -n MyManagedCluster --ssh-key-value /path/to/publickey @@ -504,6 +507,8 @@ text: az aks create -g MyResourceGroup -n MyMC --kubernetes-version 1.20.13 --location westus2 --host-group-id /subscriptions/00000/resourceGroups/AnotherResourceGroup/providers/Microsoft.ContainerService/hostGroups/myHostGroup --node-vm-size VMSize --enable-managed-identity --assign-identity - name: Create a kubernetes cluster with no CNI installed. text: az aks create -g MyResourceGroup -n MyManagedCluster --network-plugin none + - name: Create a kubernetes cluster with Custom CA Trust enabled. + text: az aks create -g MyResourceGroup -n MyManagedCluster --enable-custom-ca-trust """.format(sp_cache=AKS_SERVICE_PRINCIPAL_CACHE) @@ -1129,6 +1134,9 @@ - name: --message-of-the-day type: string short-summary: Path to a file containing the desired message of the day. Only valid for linux nodes. Will be written to /etc/motd. + - name: --enable-custom-ca-trust + type: bool + short-summary: Enable Custom CA Trust on agent node pool. examples: - name: Create a nodepool in an existing AKS cluster with ephemeral os enabled. text: az aks nodepool add -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster --node-osdisk-type Ephemeral --node-osdisk-size 48 @@ -1211,6 +1219,12 @@ - name: --node-taints type: string short-summary: The node taints for the node pool. + - name: --enable-custom-ca-trust + type: bool + short-summary: Enable Custom CA Trust on agent node pool. + - name: --dcat --disable-custom-ca-trust + type: bool + short-summary: Disable Custom CA Trust on agent node pool. - name: --aks-custom-headers type: string short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2 diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index 12280314a68..6d0c28b25be 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -109,6 +109,7 @@ validate_user, validate_vm_set_type, validate_vnet_subnet_id, + validate_enable_custom_ca_trust, ) # candidates for enumeration @@ -299,6 +300,8 @@ def load_arguments(self, _): c.argument('enable_apiserver_vnet_integration', action='store_true', is_preview=True) c.argument('apiserver_subnet_id', validator=validate_apiserver_subnet_id, is_preview=True) c.argument('dns-zone-resource-id') + # no validation for aks create because it already only supports Linux. + c.argument('enable_custom_ca_trust', action='store_true') with self.argument_context('aks update') as c: # managed cluster paramerters @@ -445,6 +448,7 @@ def load_arguments(self, _): c.argument('kubelet_config') c.argument('linux_os_config') c.argument('aks_custom_headers') + c.argument('enable_custom_ca_trust', action='store_true', validator=validate_enable_custom_ca_trust) # extensions c.argument('host_group_id', validator=validate_host_group_id, is_preview=True) c.argument('crg_id', validator=validate_crg_id, is_preview=True) @@ -484,6 +488,8 @@ def load_arguments(self, _): c.argument('max_surge', validator=validate_max_surge) c.argument('mode', arg_type=get_enum_type(node_mode_types)) c.argument('scale_down_mode', arg_type=get_enum_type(scale_down_modes)) + c.argument('enable_custom_ca_trust', action='store_true', validator=validate_enable_custom_ca_trust) + c.argument('disable_custom_ca_trust', options_list=['--disable-custom-ca-trust', '--dcat'], action='store_true') with self.argument_context('aks addon show') as c: c.argument('addon', options_list=[ diff --git a/src/aks-preview/azext_aks_preview/_validators.py b/src/aks-preview/azext_aks_preview/_validators.py index e1a5c55804f..479e84e17db 100644 --- a/src/aks-preview/azext_aks_preview/_validators.py +++ b/src/aks-preview/azext_aks_preview/_validators.py @@ -585,3 +585,11 @@ def validate_azure_keyvault_kms_key_id(namespace): segments = key_id[len(https_prefix):].split("/") if len(segments) != 4 or segments[1] != "keys": raise InvalidArgumentValueError(err_msg) + + +def validate_enable_custom_ca_trust(namespace): + """Validates Custom CA Trust can only be used on Linux.""" + if namespace.enable_custom_ca_trust: + if hasattr(namespace, 'os_type') and namespace.os_type != "Linux": + raise ArgumentUsageError( + '--enable_custom_ca_trust can only be set for Linux nodepools') diff --git a/src/aks-preview/azext_aks_preview/agentpool_decorator.py b/src/aks-preview/azext_aks_preview/agentpool_decorator.py index cb46210f32a..9258ab58d98 100644 --- a/src/aks-preview/azext_aks_preview/agentpool_decorator.py +++ b/src/aks-preview/azext_aks_preview/agentpool_decorator.py @@ -16,7 +16,10 @@ AKSAgentPoolParamDict, AKSAgentPoolUpdateDecorator, ) -from azure.cli.core.azclierror import InvalidArgumentValueError +from azure.cli.core.azclierror import ( + ArgumentUsageError, + InvalidArgumentValueError, +) from azure.cli.core.commands import AzCliCommand from azure.cli.core.profiles import ResourceType from azure.cli.core.util import read_file_content diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py index 15066054a38..456f605bc17 100644 --- a/src/aks-preview/azext_aks_preview/custom.py +++ b/src/aks-preview/azext_aks_preview/custom.py @@ -812,6 +812,7 @@ def aks_create(cmd, enable_apiserver_vnet_integration=False, apiserver_subnet_id=None, dns_zone_resource_id=None, + enable_custom_ca_trust=False, yes=False): # DO NOT MOVE: get all the original parameters and save them as a dictionary raw_parameters = locals() @@ -902,7 +903,8 @@ def aks_update(cmd, # pylint: disable=too-many-statements,too-many-branches, enable_azure_keyvault_kms=False, azure_keyvault_kms_key_id=None, enable_apiserver_vnet_integration=False, - apiserver_subnet_id=None): + apiserver_subnet_id=None, + ): # DO NOT MOVE: get all the original parameters and save them as a dictionary raw_parameters = locals() @@ -1651,8 +1653,9 @@ def aks_agentpool_add(cmd, # pylint: disable=unused-argument,too-many-local message_of_the_day=None, workload_runtime=None, gpu_instance_profile=None, + enable_custom_ca_trust=False, no_wait=False, - aks_custom_headers=None,): + aks_custom_headers=None): instances = client.list(resource_group_name, cluster_name) for agentpool_profile in instances: if agentpool_profile.name == nodepool_name: @@ -1729,7 +1732,8 @@ def aks_agentpool_add(cmd, # pylint: disable=unused-argument,too-many-local gpu_instance_profile=gpu_instance_profile, creation_data=creationData, host_group_id=host_group_id, - capacity_reservation_group_id=crg_id + capacity_reservation_group_id=crg_id, + enable_custom_ca_trust=enable_custom_ca_trust ) if priority == CONST_SCALE_SET_PRIORITY_SPOT: @@ -1851,13 +1855,16 @@ def aks_agentpool_update(cmd, # pylint: disable=unused-argument max_surge=None, mode=None, scale_down_mode=None, + enable_custom_ca_trust=False, + disable_custom_ca_trust=False, no_wait=False, aks_custom_headers=None): - update_autoscaler = enable_cluster_autoscaler + \ disable_cluster_autoscaler + update_cluster_autoscaler - if (update_autoscaler != 1 and not tags and not scale_down_mode and not mode and not max_surge and labels is None and node_taints is None): + update_custom_ca_trust = enable_custom_ca_trust + disable_custom_ca_trust + + if (update_autoscaler != 1 and not tags and not scale_down_mode and not mode and not max_surge and labels is None and node_taints is None and not update_custom_ca_trust): reconcilePrompt = 'no argument specified to update would you like to reconcile to current settings?' if not prompt_y_n(reconcilePrompt, default="n"): raise CLIError('Please specify one or more of "--enable-cluster-autoscaler" or ' @@ -1931,6 +1938,17 @@ def aks_agentpool_update(cmd, # pylint: disable=unused-argument if labels is not None: instance.node_labels = labels + + if enable_custom_ca_trust: + instance.enable_custom_ca_trust = True + + if disable_custom_ca_trust: + if not instance.enable_custom_ca_trust: + logger.warning( + 'Custom CA Trust is already disabled for this node pool.') + return None + instance.enable_custom_ca_trust = False + return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, cluster_name, nodepool_name, instance) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 43d09b5b2a7..d0ecd839859 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -241,11 +241,11 @@ def pod_identity_models(self) -> SimpleNamespace: # pylint: disable=too-many-public-methods class AKSPreviewContext(AKSContext): def __init__( - self, - cmd: AzCliCommand, - raw_parameters: Dict, - models: AKSPreviewModels, - decorator_mode, + self, + cmd: AzCliCommand, + raw_parameters: Dict, + models: AKSPreviewModels, + decorator_mode, ): super().__init__(cmd, raw_parameters, models, decorator_mode) @@ -259,9 +259,9 @@ def __validate_pod_identity_with_kubenet(self, mc, enable_pod_identity, enable_p :return: None """ if ( - mc and - mc.network_profile and - safe_lower(mc.network_profile.network_plugin) == "kubenet" + mc and + mc.network_profile and + safe_lower(mc.network_profile.network_plugin) == "kubenet" ): if enable_pod_identity and not enable_pod_identity_with_kubenet: raise RequiredArgumentMissingError( @@ -271,11 +271,11 @@ def __validate_pod_identity_with_kubenet(self, mc, enable_pod_identity, enable_p # pylint: disable=no-self-use def __validate_gmsa_options( - self, - enable_windows_gmsa, - gmsa_dns_server, - gmsa_root_domain_name, - yes, + self, + enable_windows_gmsa, + gmsa_dns_server, + gmsa_root_domain_name, + yes, ) -> None: """Helper function to validate gmsa related options. @@ -359,8 +359,8 @@ def get_pod_subnet_id(self) -> Union[str, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - agent_pool_profile.pod_subnet_id is not None + agent_pool_profile and + agent_pool_profile.pod_subnet_id is not None ): pod_subnet_id = agent_pool_profile.pod_subnet_id @@ -381,8 +381,8 @@ def get_enable_fips_image(self) -> bool: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - agent_pool_profile.enable_fips is not None + agent_pool_profile and + agent_pool_profile.enable_fips is not None ): enable_fips_image = agent_pool_profile.enable_fips @@ -403,10 +403,10 @@ def get_workload_runtime(self) -> Union[str, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - # backward compatibility - hasattr(agent_pool_profile, "workload_runtime") and - agent_pool_profile.workload_runtime is not None + agent_pool_profile and + # backward compatibility + hasattr(agent_pool_profile, "workload_runtime") and + agent_pool_profile.workload_runtime is not None ): workload_runtime = agent_pool_profile.workload_runtime @@ -427,10 +427,10 @@ def get_gpu_instance_profile(self) -> Union[str, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - # backward compatibility - hasattr(agent_pool_profile, "gpu_instance_profile") and - agent_pool_profile.gpu_instance_profile is not None + agent_pool_profile and + # backward compatibility + hasattr(agent_pool_profile, "gpu_instance_profile") and + agent_pool_profile.gpu_instance_profile is not None ): gpu_instance_profile = agent_pool_profile.gpu_instance_profile @@ -465,10 +465,10 @@ def get_message_of_the_day(self) -> Union[str, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - # backward compatibility - hasattr(agent_pool_profile, "message_of_the_day") and - agent_pool_profile.message_of_the_day is not None + agent_pool_profile and + # backward compatibility + hasattr(agent_pool_profile, "message_of_the_day") and + agent_pool_profile.message_of_the_day is not None ): message_of_the_day = agent_pool_profile.message_of_the_day @@ -476,6 +476,31 @@ def get_message_of_the_day(self) -> Union[str, None]: # this parameter does not need validation return message_of_the_day + def get_enable_custom_ca_trust(self) -> Union[bool, None]: + """Obtain the value of enable_custom_ca_trust. + + :return: bool or None + """ + # read the original value passed by the command + enable_custom_ca_trust = self.raw_param.get("enable_custom_ca_trust") + + # try to read the property value corresponding to the parameter from the `mc` object + if self.mc and self.mc.agent_pool_profiles: + agent_pool_profile = safe_list_get( + self.mc.agent_pool_profiles, 0, None + ) + if ( + agent_pool_profile and + # backward compatibility + hasattr(agent_pool_profile, "enable_custom_ca_trust") and + agent_pool_profile.enable_custom_ca_trust is not None + ): + enable_custom_ca_trust = agent_pool_profile.enable_custom_ca_trust + + # this parameter does not need dynamic completion + # this parameter does not need validation + return enable_custom_ca_trust + def get_kubelet_config(self) -> Union[dict, KubeletConfig, None]: """Obtain the value of kubelet_config. @@ -507,8 +532,8 @@ def get_kubelet_config(self) -> Union[dict, KubeletConfig, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - agent_pool_profile.kubelet_config is not None + agent_pool_profile and + agent_pool_profile.kubelet_config is not None ): kubelet_config = agent_pool_profile.kubelet_config @@ -547,8 +572,8 @@ def get_linux_os_config(self) -> Union[dict, LinuxOSConfig, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - agent_pool_profile.linux_os_config is not None + agent_pool_profile and + agent_pool_profile.linux_os_config is not None ): linux_os_config = agent_pool_profile.linux_os_config @@ -618,11 +643,11 @@ def get_nat_gateway_managed_outbound_ip_count(self) -> Union[int, None]: # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.nat_gateway_profile and - self.mc.network_profile.nat_gateway_profile.managed_outbound_ip_profile and - self.mc.network_profile.nat_gateway_profile.managed_outbound_ip_profile.count is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.nat_gateway_profile and + self.mc.network_profile.nat_gateway_profile.managed_outbound_ip_profile and + self.mc.network_profile.nat_gateway_profile.managed_outbound_ip_profile.count is not None ): nat_gateway_managed_outbound_ip_count = ( self.mc.network_profile.nat_gateway_profile.managed_outbound_ip_profile.count @@ -645,10 +670,10 @@ def get_nat_gateway_idle_timeout(self) -> Union[int, None]: # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.nat_gateway_profile and - self.mc.network_profile.nat_gateway_profile.idle_timeout_in_minutes is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.nat_gateway_profile and + self.mc.network_profile.nat_gateway_profile.idle_timeout_in_minutes is not None ): nat_gateway_idle_timeout = ( self.mc.network_profile.nat_gateway_profile.idle_timeout_in_minutes @@ -672,8 +697,8 @@ def _get_enable_pod_security_policy(self, enable_validation: bool = False) -> bo # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.enable_pod_security_policy is not None + self.mc and + self.mc.enable_pod_security_policy is not None ): enable_pod_security_policy = self.mc.enable_pod_security_policy @@ -732,7 +757,7 @@ def get_disable_pod_security_policy(self) -> bool: # pylint: disable=unused-argument def _get_enable_managed_identity( - self, enable_validation: bool = False, read_only: bool = False + self, enable_validation: bool = False, read_only: bool = False ) -> bool: """Internal function to obtain the value of enable_managed_identity. @@ -774,9 +799,9 @@ def _get_enable_pod_identity(self, enable_validation: bool = False) -> bool: # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.pod_identity_profile and - self.mc.pod_identity_profile.enabled is not None + self.mc and + self.mc.pod_identity_profile and + self.mc.pod_identity_profile.enabled is not None ): enable_pod_identity = self.mc.pod_identity_profile.enabled @@ -870,9 +895,9 @@ def _get_enable_pod_identity_with_kubenet(self, enable_validation: bool = False) # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.pod_identity_profile and - self.mc.pod_identity_profile.allow_network_plugin_kubenet is not None + self.mc and + self.mc.pod_identity_profile and + self.mc.pod_identity_profile.allow_network_plugin_kubenet is not None ): enable_pod_identity_with_kubenet = self.mc.pod_identity_profile.allow_network_plugin_kubenet @@ -936,12 +961,12 @@ def get_appgw_subnet_prefix(self) -> Union[str, None]: appgw_subnet_prefix = self.raw_param.get("appgw_subnet_prefix") # try to read the property value corresponding to the parameter from the `mc` object if ( - self.mc and - self.mc.addon_profiles and - CONST_INGRESS_APPGW_ADDON_NAME in self.mc.addon_profiles and - self.mc.addon_profiles.get( - CONST_INGRESS_APPGW_ADDON_NAME - ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) is not None + self.mc and + self.mc.addon_profiles and + CONST_INGRESS_APPGW_ADDON_NAME in self.mc.addon_profiles and + self.mc.addon_profiles.get( + CONST_INGRESS_APPGW_ADDON_NAME + ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) is not None ): appgw_subnet_prefix = self.mc.addon_profiles.get( CONST_INGRESS_APPGW_ADDON_NAME @@ -971,12 +996,12 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: "enable_msi_auth_for_monitoring") # try to read the property value corresponding to the parameter from the `mc` object if ( - self.mc and - self.mc.addon_profiles and - CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and - self.mc.addon_profiles.get( - CONST_MONITORING_ADDON_NAME - ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None + self.mc and + self.mc.addon_profiles and + CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and + self.mc.addon_profiles.get( + CONST_MONITORING_ADDON_NAME + ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None ): enable_msi_auth_for_monitoring = self.mc.addon_profiles.get( CONST_MONITORING_ADDON_NAME @@ -1009,7 +1034,7 @@ def get_no_wait(self) -> bool: # TOOD: may remove this function after the fix for the internal function get merged and released # pylint: disable=unused-argument def _get_workspace_resource_id( - self, enable_validation: bool = False, read_only: bool = False + self, enable_validation: bool = False, read_only: bool = False ) -> Union[str, None]: # pragma: no cover """Internal function to dynamically obtain the value of workspace_resource_id according to the context. @@ -1038,12 +1063,12 @@ def _get_workspace_resource_id( # try to read the property value corresponding to the parameter from the `mc` object read_from_mc = False if ( - self.mc and - self.mc.addon_profiles and - CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and - self.mc.addon_profiles.get( - CONST_MONITORING_ADDON_NAME - ).config.get(CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID) is not None + self.mc and + self.mc.addon_profiles and + CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and + self.mc.addon_profiles.get( + CONST_MONITORING_ADDON_NAME + ).config.get(CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID) is not None ): workspace_resource_id = self.mc.addon_profiles.get( CONST_MONITORING_ADDON_NAME @@ -1130,27 +1155,27 @@ def get_load_balancer_managed_outbound_ip_count(self) -> Union[int, None]: # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.load_balancer_profile and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.load_balancer_profile and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count is not None ): load_balancer_managed_outbound_ip_count = ( self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count ) elif self.decorator_mode == DecoratorMode.UPDATE: if ( - not self.get_load_balancer_outbound_ips() and - not self.get_load_balancer_outbound_ip_prefixes() and - load_balancer_managed_outbound_ip_count is None + not self.get_load_balancer_outbound_ips() and + not self.get_load_balancer_outbound_ip_prefixes() and + load_balancer_managed_outbound_ip_count is None ): if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.load_balancer_profile and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.load_balancer_profile and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count is not None ): load_balancer_managed_outbound_ip_count = ( self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count @@ -1172,27 +1197,27 @@ def get_load_balancer_managed_outbound_ipv6_count(self) -> Union[int, None]: if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.load_balancer_profile and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count_ipv6 is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.load_balancer_profile and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count_ipv6 is not None ): count_ipv6 = ( self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count_ipv6 ) elif self.decorator_mode == DecoratorMode.UPDATE: if ( - not self.get_load_balancer_outbound_ips() and - not self.get_load_balancer_outbound_ip_prefixes() and - count_ipv6 is None + not self.get_load_balancer_outbound_ips() and + not self.get_load_balancer_outbound_ip_prefixes() and + count_ipv6 is None ): if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.load_balancer_profile and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and - self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count_ipv6 is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.load_balancer_profile and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps and + self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count_ipv6 is not None ): count_ipv6 = ( self.mc.network_profile.load_balancer_profile.managed_outbound_i_ps.count_ipv6 @@ -1202,10 +1227,10 @@ def get_load_balancer_managed_outbound_ipv6_count(self) -> Union[int, None]: # pylint: disable=unused-argument def _get_outbound_type( - self, - enable_validation: bool = False, - read_only: bool = False, - load_balancer_profile: ManagedClusterLoadBalancerProfile = None, + self, + enable_validation: bool = False, + read_only: bool = False, + load_balancer_profile: ManagedClusterLoadBalancerProfile = None, ) -> Union[str, None]: """Internal function to dynamically obtain the value of outbound_type according to the context. @@ -1235,9 +1260,9 @@ def _get_outbound_type( # try to read the property value corresponding to the parameter from the `mc` object read_from_mc = False if ( - self.mc and - self.mc.network_profile and - self.mc.network_profile.outbound_type is not None + self.mc and + self.mc.network_profile and + self.mc.network_profile.outbound_type is not None ): outbound_type = self.mc.network_profile.outbound_type read_from_mc = True @@ -1248,10 +1273,10 @@ def _get_outbound_type( # dynamic completion if ( - not read_from_mc and - outbound_type != CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY and - outbound_type != CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY and - outbound_type != CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING + not read_from_mc and + outbound_type != CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY and + outbound_type != CONST_OUTBOUND_TYPE_USER_ASSIGNED_NAT_GATEWAY and + outbound_type != CONST_OUTBOUND_TYPE_USER_DEFINED_ROUTING ): outbound_type = CONST_OUTBOUND_TYPE_LOAD_BALANCER @@ -1283,9 +1308,9 @@ def _get_outbound_type( ) if load_balancer_profile: if ( - load_balancer_profile.managed_outbound_i_ps or - load_balancer_profile.outbound_i_ps or - load_balancer_profile.outbound_ip_prefixes + load_balancer_profile.managed_outbound_i_ps or + load_balancer_profile.outbound_i_ps or + load_balancer_profile.outbound_ip_prefixes ): raise MutuallyExclusiveArgumentError( "userDefinedRouting doesn't support customizing " @@ -1293,9 +1318,9 @@ def _get_outbound_type( ) else: if ( - self.get_load_balancer_managed_outbound_ip_count() or - self.get_load_balancer_outbound_ips() or - self.get_load_balancer_outbound_ip_prefixes() + self.get_load_balancer_managed_outbound_ip_count() or + self.get_load_balancer_outbound_ips() or + self.get_load_balancer_outbound_ip_prefixes() ): raise MutuallyExclusiveArgumentError( "userDefinedRouting doesn't support customizing " @@ -1316,12 +1341,12 @@ def _get_enable_windows_gmsa(self, enable_validation: bool = False) -> bool: # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.windows_profile and - # backward compatibility - hasattr(self.mc.windows_profile, "gmsa_profile") and - self.mc.windows_profile.gmsa_profile and - self.mc.windows_profile.gmsa_profile.enabled is not None + self.mc and + self.mc.windows_profile and + # backward compatibility + hasattr(self.mc.windows_profile, "gmsa_profile") and + self.mc.windows_profile.gmsa_profile and + self.mc.windows_profile.gmsa_profile.enabled is not None ): enable_windows_gmsa = self.mc.windows_profile.gmsa_profile.enabled @@ -1368,12 +1393,12 @@ def _get_gmsa_dns_server_and_root_domain_name(self, enable_validation: bool = Fa gmsa_dns_read_from_mc = False if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.windows_profile and - # backward compatibility - hasattr(self.mc.windows_profile, "gmsa_profile") and - self.mc.windows_profile.gmsa_profile and - self.mc.windows_profile.gmsa_profile.dns_server is not None + self.mc and + self.mc.windows_profile and + # backward compatibility + hasattr(self.mc.windows_profile, "gmsa_profile") and + self.mc.windows_profile.gmsa_profile and + self.mc.windows_profile.gmsa_profile.dns_server is not None ): gmsa_dns_server = self.mc.windows_profile.gmsa_profile.dns_server gmsa_dns_read_from_mc = True @@ -1385,12 +1410,12 @@ def _get_gmsa_dns_server_and_root_domain_name(self, enable_validation: bool = Fa gmsa_root_read_from_mc = False if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.windows_profile and - # backward compatibility - hasattr(self.mc.windows_profile, "gmsa_profile") and - self.mc.windows_profile.gmsa_profile and - self.mc.windows_profile.gmsa_profile.root_domain_name is not None + self.mc and + self.mc.windows_profile and + # backward compatibility + hasattr(self.mc.windows_profile, "gmsa_profile") and + self.mc.windows_profile.gmsa_profile and + self.mc.windows_profile.gmsa_profile.root_domain_name is not None ): gmsa_root_domain_name = self.mc.windows_profile.gmsa_profile.root_domain_name gmsa_root_read_from_mc = True @@ -1440,9 +1465,9 @@ def get_snapshot_id(self) -> Union[str, None]: self.mc.agent_pool_profiles, 0, None ) if ( - agent_pool_profile and - agent_pool_profile.creation_data and - agent_pool_profile.creation_data.source_resource_id is not None + agent_pool_profile and + agent_pool_profile.creation_data and + agent_pool_profile.creation_data.source_resource_id is not None ): snapshot_id = ( agent_pool_profile.creation_data.source_resource_id @@ -1483,9 +1508,9 @@ def get_cluster_snapshot_id(self) -> Union[str, None]: snapshot_id = self.raw_param.get("cluster_snapshot_id") # try to read the property value corresponding to the parameter from the `mc` object if ( - self.mc and - self.mc.creation_data and - self.mc.creation_data.source_resource_id is not None + self.mc and + self.mc.creation_data and + self.mc.creation_data.source_resource_id is not None ): snapshot_id = ( self.mc.creation_data.source_resource_id @@ -1880,9 +1905,9 @@ def _get_enable_azure_keyvault_kms(self, enable_validation: bool = False) -> boo # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.security_profile and - self.mc.security_profile.azure_key_vault_kms + self.mc and + self.mc.security_profile and + self.mc.security_profile.azure_key_vault_kms ): enable_azure_keyvault_kms = self.mc.security_profile.azure_key_vault_kms.enabled @@ -1920,10 +1945,10 @@ def _get_azure_keyvault_kms_key_id(self, enable_validation: bool = False) -> Uni # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.security_profile and - self.mc.security_profile.azure_key_vault_kms and - self.mc.security_profile.azure_key_vault_kms.key_id is not None + self.mc and + self.mc.security_profile and + self.mc.security_profile.azure_key_vault_kms and + self.mc.security_profile.azure_key_vault_kms.key_id is not None ): azure_keyvault_kms_key_id = self.mc.security_profile.azure_key_vault_kms.key_id @@ -1931,11 +1956,11 @@ def _get_azure_keyvault_kms_key_id(self, enable_validation: bool = False) -> Uni enable_azure_keyvault_kms = self._get_enable_azure_keyvault_kms( enable_validation=False) if ( - azure_keyvault_kms_key_id and - ( - enable_azure_keyvault_kms is None or - enable_azure_keyvault_kms is False - ) + azure_keyvault_kms_key_id and + ( + enable_azure_keyvault_kms is None or + enable_azure_keyvault_kms is False + ) ): raise RequiredArgumentMissingError( '"--azure-keyvault-kms-key-id" requires "--enable-azure-keyvault-kms".') @@ -1973,8 +1998,9 @@ def get_cluster_uaidentity_object_id(self) -> str: cluster_identity_resource_id = "" if assigned_identity is None or assigned_identity == "": # Suppose identity is present on mc - if not(self.mc and self.mc.identity and self.mc.identity.user_assigned_identities): - raise RequiredArgumentMissingError("--assign-identity is not provided and the cluster identity type is not user assigned, cannot update kubelet identity") + if not (self.mc and self.mc.identity and self.mc.identity.user_assigned_identities): + raise RequiredArgumentMissingError( + "--assign-identity is not provided and the cluster identity type is not user assigned, cannot update kubelet identity") cluster_identity_resource_id = list(self.mc.identity.user_assigned_identities.keys())[0] else: cluster_identity_resource_id = assigned_identity @@ -1994,9 +2020,9 @@ def _get_enable_apiserver_vnet_integration(self, enable_validation: bool = False # In create mode, try to read the property value corresponding to the parameter from the `mc` object. if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.api_server_access_profile and - self.mc.api_server_access_profile.enable_vnet_integration is not None + self.mc and + self.mc.api_server_access_profile and + self.mc.api_server_access_profile.enable_vnet_integration is not None ): enable_apiserver_vnet_integration = self.mc.api_server_access_profile.enable_vnet_integration @@ -2045,9 +2071,9 @@ def _get_apiserver_subnet_id(self, enable_validation: bool = False) -> Union[str # try to read the property value corresponding to the parameter from the `mc` object if self.decorator_mode == DecoratorMode.CREATE: if ( - self.mc and - self.mc.api_server_access_profile and - self.mc.api_server_access_profile.subnet_id is not None + self.mc and + self.mc.api_server_access_profile and + self.mc.api_server_access_profile.subnet_id is not None ): apiserver_subnet_id = self.mc.api_server_access_profile.subnet_id @@ -2063,11 +2089,11 @@ def _get_apiserver_subnet_id(self, enable_validation: bool = False) -> Union[str enable_apiserver_vnet_integration = self._get_enable_apiserver_vnet_integration( enable_validation=False) if ( - apiserver_subnet_id and - ( - enable_apiserver_vnet_integration is None or - enable_apiserver_vnet_integration is False - ) + apiserver_subnet_id and + ( + enable_apiserver_vnet_integration is None or + enable_apiserver_vnet_integration is False + ) ): raise RequiredArgumentMissingError( '"--apiserver-subnet-id" requires "--enable-apiserver-vnet-integration".') @@ -2088,11 +2114,11 @@ def get_apiserver_subnet_id(self) -> Union[str, None]: class AKSPreviewCreateDecorator(AKSCreateDecorator): # pylint: disable=super-init-not-called def __init__( - self, - cmd: AzCliCommand, - client: ContainerServiceClient, - raw_parameters: Dict, - resource_type: ResourceType, + self, + cmd: AzCliCommand, + client: ContainerServiceClient, + raw_parameters: Dict, + resource_type: ResourceType, ): """Internal controller of aks_create in aks-preview. @@ -2135,6 +2161,9 @@ def set_up_agent_pool_profiles(self, mc: ManagedCluster) -> ManagedCluster: agent_pool_profile.message_of_the_day = ( self.context.get_message_of_the_day() ) + agent_pool_profile.enable_custom_ca_trust = ( + self.context.get_enable_custom_ca_trust() + ) agent_pool_profile.kubelet_config = self.context.get_kubelet_config() agent_pool_profile.linux_os_config = self.context.get_linux_os_config() @@ -2355,11 +2384,11 @@ def build_ingress_appgw_addon_profile(self) -> ManagedClusterAddonProfile: ingress_appgw_addon_profile = super().build_ingress_appgw_addon_profile() appgw_subnet_prefix = self.context.get_appgw_subnet_prefix() if ( - appgw_subnet_prefix is not None and - ingress_appgw_addon_profile.config.get( - CONST_INGRESS_APPGW_SUBNET_CIDR - ) - is None + appgw_subnet_prefix is not None and + ingress_appgw_addon_profile.config.get( + CONST_INGRESS_APPGW_SUBNET_CIDR + ) + is None ): ingress_appgw_addon_profile.config[CONST_INGRESS_APPGW_SUBNET_CIDR] = appgw_subnet_prefix return ingress_appgw_addon_profile @@ -2581,11 +2610,11 @@ def create_mc_preview(self, mc: ManagedCluster) -> ManagedCluster: class AKSPreviewUpdateDecorator(AKSUpdateDecorator): # pylint: disable=super-init-not-called def __init__( - self, - cmd: AzCliCommand, - client: ContainerServiceClient, - raw_parameters: Dict, - resource_type: ResourceType, + self, + cmd: AzCliCommand, + client: ContainerServiceClient, + raw_parameters: Dict, + resource_type: ResourceType, ): """Internal controller of aks_update in aks-preview. diff --git a/src/aks-preview/azext_aks_preview/tests/latest/recordings/test_aks_custom_ca_trust_flow.yaml b/src/aks-preview/azext_aks_preview/tests/latest/recordings/test_aks_custom_ca_trust_flow.yaml new file mode 100644 index 00000000000..cf4091fe248 --- /dev/null +++ b/src/aks-preview/azext_aks_preview/tests/latest/recordings/test_aks_custom_ca_trust_flow.yaml @@ -0,0 +1,1187 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-resource/20.0.0 Python/3.8.9 (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest000001?api-version=2021-04-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001","name":"clitest000001","type":"Microsoft.Resources/resourceGroups","location":"eastus","tags":{"product":"azurecli","cause":"automation","date":"2022-05-27T00:02:02Z"},"properties":{"provisioningState":"Succeeded"}}' + headers: + cache-control: + - no-cache + content-length: + - '304' + content-type: + - application/json; charset=utf-8 + date: + - Fri, 27 May 2022 00:02:04 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: '{"location": "eastus", "identity": {"type": "SystemAssigned"}, "properties": + {"kubernetesVersion": "", "dnsPrefix": "cliakstest-clitestblnwff3pc-8ecadf", + "agentPoolProfiles": [{"count": 1, "vmSize": "Standard_DS2_v2", "workloadRuntime": + "OCIContainer", "osType": "Linux", "enableAutoScaling": false, "type": "VirtualMachineScaleSets", + "mode": "System", "enableNodePublicIP": false, "enableCustomCATrust": true, + "scaleSetPriority": "Regular", "scaleSetEvictionPolicy": "Delete", "spotMaxPrice": + -1.0, "enableEncryptionAtHost": false, "enableUltraSSD": false, "enableFIPS": + false, "name": "c000003"}], "linuxProfile": {"adminUsername": "azureuser", "ssh": + {"publicKeys": [{"keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCbIg1guRHbI0lV11wWDt1r2cUdcNd27CJsg+SfgC7miZeubtwUhbsPdhMQsfDyhOWHq1+ZL0M+nJZV63d/1dhmhtgyOqejUwrPlzKhydsbrsdUor+JmNJDdW01v7BXHyuymT8G4s09jCasNOwiufbP/qp72ruu0bIA1nySsvlf9pCQAuFkAnVnf/rFhUlOkhtRpwcq8SUNY2zRHR/EKb/4NWY1JzR4sa3q2fWIJdrrX0DvLoa5g9bIEd4Df79ba7v+yiUBOS0zT2ll+z4g9izHK3EO5d8hL4jYxcjKs+wcslSYRWrascfscLgMlMGh0CdKeNTDjHpGPncaf3Z+FwwwjWeuiNBxv7bJo13/8B/098KlVDl4GZqsoBCEjPyJfV6hO0y/LkRGkk7oHWKgeWAfKtfLItRp00eZ4fcJNK9kCaSMmEugoZWcI7NGbZXzqFWqbpRI7NcDP9+WIQ+i9U5vqWsqd/zng4kbuAJ6UuKqIzB0upYrLShfQE3SAck8oaLhJqqq56VfDuASNpJKidV+zq27HfSBmbXnkR/5AK337dc3MXKJypoK/QPMLKUAP5XLPbs+NddJQV7EZXd29DLgp+fRIg3edpKdO7ZErWhv7d+3Kws+e1Y+ypmR2WIVSwVyBEUfgv2C8Ts9gnTF4pNcEY/S2aBicz5Ew2+jdyGNQQ== + test@example.com\n"}]}}, "addonProfiles": {}, "enableRBAC": true, "enablePodSecurityPolicy": + false, "networkProfile": {"networkPlugin": "kubenet", "podCidr": "10.244.0.0/16", + "serviceCidr": "10.0.0.0/16", "dnsServiceIP": "10.0.0.10", "dockerBridgeCidr": + "172.17.0.1/16", "outboundType": "loadBalancer", "loadBalancerSku": "standard"}, + "disableLocalAccounts": false, "storageProfile": {}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + Content-Length: + - '1796' + Content-Type: + - application/json + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002?api-version=2022-04-02-preview + response: + body: + string: "{\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002\",\n + \ \"location\": \"eastus\",\n \"name\": \"cliakstest000002\",\n \"type\": + \"Microsoft.ContainerService/ManagedClusters\",\n \"properties\": {\n \"provisioningState\": + \"Creating\",\n \"powerState\": {\n \"code\": \"Running\"\n },\n \"kubernetesVersion\": + \"1.22.6\",\n \"currentKubernetesVersion\": \"1.22.6\",\n \"dnsPrefix\": + \"cliakstest-clitestblnwff3pc-8ecadf\",\n \"fqdn\": \"cliakstest-clitestblnwff3pc-8ecadf-8c02f020.hcp.eastus.azmk8s.io\",\n + \ \"azurePortalFQDN\": \"cliakstest-clitestblnwff3pc-8ecadf-8c02f020.portal.hcp.eastus.azmk8s.io\",\n + \ \"agentPoolProfiles\": [\n {\n \"name\": \"c000003\",\n \"count\": + 1,\n \"vmSize\": \"Standard_DS2_v2\",\n \"osDiskSizeGB\": 128,\n \"osDiskType\": + \"Managed\",\n \"kubeletDiskType\": \"OS\",\n \"workloadRuntime\": + \"OCIContainer\",\n \"maxPods\": 110,\n \"type\": \"VirtualMachineScaleSets\",\n + \ \"enableAutoScaling\": false,\n \"provisioningState\": \"Creating\",\n + \ \"powerState\": {\n \"code\": \"Running\"\n },\n \"orchestratorVersion\": + \"1.22.6\",\n \"enableNodePublicIP\": false,\n \"enableCustomCATrust\": + true,\n \"mode\": \"System\",\n \"enableEncryptionAtHost\": false,\n + \ \"enableUltraSSD\": false,\n \"osType\": \"Linux\",\n \"osSKU\": + \"Ubuntu\",\n \"nodeImageVersion\": \"AKSUbuntu-1804gen2containerd-2022.05.10\",\n + \ \"enableFIPS\": false\n }\n ],\n \"linuxProfile\": {\n \"adminUsername\": + \"azureuser\",\n \"ssh\": {\n \"publicKeys\": [\n {\n \"keyData\": + \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCbIg1guRHbI0lV11wWDt1r2cUdcNd27CJsg+SfgC7miZeubtwUhbsPdhMQsfDyhOWHq1+ZL0M+nJZV63d/1dhmhtgyOqejUwrPlzKhydsbrsdUor+JmNJDdW01v7BXHyuymT8G4s09jCasNOwiufbP/qp72ruu0bIA1nySsvlf9pCQAuFkAnVnf/rFhUlOkhtRpwcq8SUNY2zRHR/EKb/4NWY1JzR4sa3q2fWIJdrrX0DvLoa5g9bIEd4Df79ba7v+yiUBOS0zT2ll+z4g9izHK3EO5d8hL4jYxcjKs+wcslSYRWrascfscLgMlMGh0CdKeNTDjHpGPncaf3Z+FwwwjWeuiNBxv7bJo13/8B/098KlVDl4GZqsoBCEjPyJfV6hO0y/LkRGkk7oHWKgeWAfKtfLItRp00eZ4fcJNK9kCaSMmEugoZWcI7NGbZXzqFWqbpRI7NcDP9+WIQ+i9U5vqWsqd/zng4kbuAJ6UuKqIzB0upYrLShfQE3SAck8oaLhJqqq56VfDuASNpJKidV+zq27HfSBmbXnkR/5AK337dc3MXKJypoK/QPMLKUAP5XLPbs+NddJQV7EZXd29DLgp+fRIg3edpKdO7ZErWhv7d+3Kws+e1Y+ypmR2WIVSwVyBEUfgv2C8Ts9gnTF4pNcEY/S2aBicz5Ew2+jdyGNQQ== + test@example.com\\n\"\n }\n ]\n }\n },\n \"servicePrincipalProfile\": + {\n \"clientId\":\"00000000-0000-0000-0000-000000000001\"\n },\n \"nodeResourceGroup\": + \"MC_clitest000001_cliakstest000002_eastus\",\n \"enableRBAC\": true,\n + \ \"enablePodSecurityPolicy\": false,\n \"networkProfile\": {\n \"networkPlugin\": + \"kubenet\",\n \"loadBalancerSku\": \"standard\",\n \"loadBalancerProfile\": + {\n \"managedOutboundIPs\": {\n \"count\": 1\n }\n },\n \"podCidr\": + \"10.244.0.0/16\",\n \"serviceCidr\": \"10.0.0.0/16\",\n \"dnsServiceIP\": + \"10.0.0.10\",\n \"dockerBridgeCidr\": \"172.17.0.1/16\",\n \"outboundType\": + \"loadBalancer\",\n \"podCidrs\": [\n \"10.244.0.0/16\"\n ],\n \"serviceCidrs\": + [\n \"10.0.0.0/16\"\n ],\n \"ipFamilies\": [\n \"IPv4\"\n ]\n + \ },\n \"maxAgentPools\": 100,\n \"disableLocalAccounts\": false,\n \"securityProfile\": + {},\n \"storageProfile\": {\n \"diskCSIDriver\": {\n \"enabled\": + true\n },\n \"fileCSIDriver\": {\n \"enabled\": true\n },\n \"snapshotController\": + {\n \"enabled\": true\n }\n },\n \"oidcIssuerProfile\": {\n \"enabled\": + false\n }\n },\n \"identity\": {\n \"type\": \"SystemAssigned\",\n \"principalId\":\"00000000-0000-0000-0000-000000000001\",\n + \ \"tenantId\": \"72f988bf-86f1-41af-91ab-2d7cd011db47\"\n },\n \"sku\": + {\n \"name\": \"Basic\",\n \"tier\": \"Free\"\n }\n }" + headers: + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + cache-control: + - no-cache + content-length: + - '3593' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:02:11 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1199' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:02:41 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:03:11 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:03:42 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:04:12 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:04:41 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:05:13 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/2badeedc-8ca8-4786-abd6-d8fae1834ac9?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"dceead2b-a88c-8647-abd6-d8fae1834ac9\",\n \"status\": + \"Succeeded\",\n \"startTime\": \"2022-05-27T00:02:11.2Z\",\n \"endTime\": + \"2022-05-27T00:05:41.5108479Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '164' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:05:43 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks create + Connection: + - keep-alive + ParameterSetName: + - --resource-group --name --nodepool-name -c --ssh-key-value --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002?api-version=2022-04-02-preview + response: + body: + string: "{\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002\",\n + \ \"location\": \"eastus\",\n \"name\": \"cliakstest000002\",\n \"type\": + \"Microsoft.ContainerService/ManagedClusters\",\n \"properties\": {\n \"provisioningState\": + \"Succeeded\",\n \"powerState\": {\n \"code\": \"Running\"\n },\n \"kubernetesVersion\": + \"1.22.6\",\n \"currentKubernetesVersion\": \"1.22.6\",\n \"dnsPrefix\": + \"cliakstest-clitestblnwff3pc-8ecadf\",\n \"fqdn\": \"cliakstest-clitestblnwff3pc-8ecadf-8c02f020.hcp.eastus.azmk8s.io\",\n + \ \"azurePortalFQDN\": \"cliakstest-clitestblnwff3pc-8ecadf-8c02f020.portal.hcp.eastus.azmk8s.io\",\n + \ \"agentPoolProfiles\": [\n {\n \"name\": \"c000003\",\n \"count\": + 1,\n \"vmSize\": \"Standard_DS2_v2\",\n \"osDiskSizeGB\": 128,\n \"osDiskType\": + \"Managed\",\n \"kubeletDiskType\": \"OS\",\n \"workloadRuntime\": + \"OCIContainer\",\n \"maxPods\": 110,\n \"type\": \"VirtualMachineScaleSets\",\n + \ \"enableAutoScaling\": false,\n \"provisioningState\": \"Succeeded\",\n + \ \"powerState\": {\n \"code\": \"Running\"\n },\n \"orchestratorVersion\": + \"1.22.6\",\n \"enableNodePublicIP\": false,\n \"enableCustomCATrust\": + true,\n \"mode\": \"System\",\n \"enableEncryptionAtHost\": false,\n + \ \"enableUltraSSD\": false,\n \"osType\": \"Linux\",\n \"osSKU\": + \"Ubuntu\",\n \"nodeImageVersion\": \"AKSUbuntu-1804gen2containerd-2022.05.10\",\n + \ \"enableFIPS\": false\n }\n ],\n \"linuxProfile\": {\n \"adminUsername\": + \"azureuser\",\n \"ssh\": {\n \"publicKeys\": [\n {\n \"keyData\": + \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCbIg1guRHbI0lV11wWDt1r2cUdcNd27CJsg+SfgC7miZeubtwUhbsPdhMQsfDyhOWHq1+ZL0M+nJZV63d/1dhmhtgyOqejUwrPlzKhydsbrsdUor+JmNJDdW01v7BXHyuymT8G4s09jCasNOwiufbP/qp72ruu0bIA1nySsvlf9pCQAuFkAnVnf/rFhUlOkhtRpwcq8SUNY2zRHR/EKb/4NWY1JzR4sa3q2fWIJdrrX0DvLoa5g9bIEd4Df79ba7v+yiUBOS0zT2ll+z4g9izHK3EO5d8hL4jYxcjKs+wcslSYRWrascfscLgMlMGh0CdKeNTDjHpGPncaf3Z+FwwwjWeuiNBxv7bJo13/8B/098KlVDl4GZqsoBCEjPyJfV6hO0y/LkRGkk7oHWKgeWAfKtfLItRp00eZ4fcJNK9kCaSMmEugoZWcI7NGbZXzqFWqbpRI7NcDP9+WIQ+i9U5vqWsqd/zng4kbuAJ6UuKqIzB0upYrLShfQE3SAck8oaLhJqqq56VfDuASNpJKidV+zq27HfSBmbXnkR/5AK337dc3MXKJypoK/QPMLKUAP5XLPbs+NddJQV7EZXd29DLgp+fRIg3edpKdO7ZErWhv7d+3Kws+e1Y+ypmR2WIVSwVyBEUfgv2C8Ts9gnTF4pNcEY/S2aBicz5Ew2+jdyGNQQ== + test@example.com\\n\"\n }\n ]\n }\n },\n \"servicePrincipalProfile\": + {\n \"clientId\":\"00000000-0000-0000-0000-000000000001\"\n },\n \"nodeResourceGroup\": + \"MC_clitest000001_cliakstest000002_eastus\",\n \"enableRBAC\": true,\n + \ \"enablePodSecurityPolicy\": false,\n \"networkProfile\": {\n \"networkPlugin\": + \"kubenet\",\n \"loadBalancerSku\": \"Standard\",\n \"loadBalancerProfile\": + {\n \"managedOutboundIPs\": {\n \"count\": 1\n },\n \"effectiveOutboundIPs\": + [\n {\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MC_clitest000001_cliakstest000002_eastus/providers/Microsoft.Network/publicIPAddresses/16a5a9b3-cabe-4cef-b76d-99116444aaf5\"\n + \ }\n ]\n },\n \"podCidr\": \"10.244.0.0/16\",\n \"serviceCidr\": + \"10.0.0.0/16\",\n \"dnsServiceIP\": \"10.0.0.10\",\n \"dockerBridgeCidr\": + \"172.17.0.1/16\",\n \"outboundType\": \"loadBalancer\",\n \"podCidrs\": + [\n \"10.244.0.0/16\"\n ],\n \"serviceCidrs\": [\n \"10.0.0.0/16\"\n + \ ],\n \"ipFamilies\": [\n \"IPv4\"\n ]\n },\n \"maxAgentPools\": + 100,\n \"identityProfile\": {\n \"kubeletidentity\": {\n \"resourceId\": + \"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/MC_clitest000001_cliakstest000002_eastus/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cliakstest000002-agentpool\",\n + \ \"clientId\":\"00000000-0000-0000-0000-000000000001\",\n \"objectId\":\"00000000-0000-0000-0000-000000000001\"\n + \ }\n },\n \"disableLocalAccounts\": false,\n \"securityProfile\": + {},\n \"storageProfile\": {\n \"diskCSIDriver\": {\n \"enabled\": + true\n },\n \"fileCSIDriver\": {\n \"enabled\": true\n },\n \"snapshotController\": + {\n \"enabled\": true\n }\n },\n \"oidcIssuerProfile\": {\n \"enabled\": + false\n }\n },\n \"identity\": {\n \"type\": \"SystemAssigned\",\n \"principalId\":\"00000000-0000-0000-0000-000000000001\",\n + \ \"tenantId\": \"72f988bf-86f1-41af-91ab-2d7cd011db47\"\n },\n \"sku\": + {\n \"name\": \"Basic\",\n \"tier\": \"Free\"\n }\n }" + headers: + cache-control: + - no-cache + content-length: + - '4244' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:05:44 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002/agentPools?api-version=2022-04-02-preview + response: + body: + string: "{\n \"value\": [\n {\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002/agentPools/c000003\",\n + \ \"name\": \"c000003\",\n \"type\": \"Microsoft.ContainerService/managedClusters/agentPools\",\n + \ \"properties\": {\n \"count\": 1,\n \"vmSize\": \"Standard_DS2_v2\",\n + \ \"osDiskSizeGB\": 128,\n \"osDiskType\": \"Managed\",\n \"kubeletDiskType\": + \"OS\",\n \"workloadRuntime\": \"OCIContainer\",\n \"maxPods\": 110,\n + \ \"type\": \"VirtualMachineScaleSets\",\n \"enableAutoScaling\": false,\n + \ \"provisioningState\": \"Succeeded\",\n \"powerState\": {\n \"code\": + \"Running\"\n },\n \"orchestratorVersion\": \"1.22.6\",\n \"enableNodePublicIP\": + false,\n \"enableCustomCATrust\": true,\n \"mode\": \"System\",\n + \ \"enableEncryptionAtHost\": false,\n \"enableUltraSSD\": false,\n + \ \"osType\": \"Linux\",\n \"osSKU\": \"Ubuntu\",\n \"nodeImageVersion\": + \"AKSUbuntu-1804gen2containerd-2022.05.10\",\n \"enableFIPS\": false\n + \ }\n }\n ]\n }" + headers: + cache-control: + - no-cache + content-length: + - '1033' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:05:45 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: '{"properties": {"count": 3, "vmSize": "Standard_DS2_v2", "workloadRuntime": + "OCIContainer", "osType": "Linux", "scaleDownMode": "Delete", "mode": "User", + "upgradeSettings": {}, "enableNodePublicIP": false, "enableCustomCATrust": true, + "scaleSetPriority": "Regular", "scaleSetEvictionPolicy": "Delete", "spotMaxPrice": + -1.0, "nodeTaints": [], "enableEncryptionAtHost": false, "enableUltraSSD": false, + "enableFIPS": false}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + Content-Length: + - '421' + Content-Type: + - application/json + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002/agentPools/c000004?api-version=2022-04-02-preview + response: + body: + string: "{\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002/agentPools/c000004\",\n + \ \"name\": \"c000004\",\n \"type\": \"Microsoft.ContainerService/managedClusters/agentPools\",\n + \ \"properties\": {\n \"count\": 3,\n \"vmSize\": \"Standard_DS2_v2\",\n + \ \"osDiskSizeGB\": 128,\n \"osDiskType\": \"Managed\",\n \"kubeletDiskType\": + \"OS\",\n \"workloadRuntime\": \"OCIContainer\",\n \"maxPods\": 110,\n + \ \"type\": \"VirtualMachineScaleSets\",\n \"scaleDownMode\": \"Delete\",\n + \ \"provisioningState\": \"Creating\",\n \"powerState\": {\n \"code\": + \"Running\"\n },\n \"orchestratorVersion\": \"1.22.6\",\n \"enableNodePublicIP\": + false,\n \"enableCustomCATrust\": true,\n \"mode\": \"User\",\n \"enableEncryptionAtHost\": + false,\n \"enableUltraSSD\": false,\n \"osType\": \"Linux\",\n \"osSKU\": + \"Ubuntu\",\n \"nodeImageVersion\": \"AKSUbuntu-1804gen2containerd-2022.05.10\",\n + \ \"upgradeSettings\": {},\n \"enableFIPS\": false\n }\n }" + headers: + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + cache-control: + - no-cache + content-length: + - '972' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:05:49 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1199' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:06:19 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:06:50 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:07:20 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:07:50 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:08:20 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:08:51 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"InProgress\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '120' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:09:21 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/d2acb303-2cdf-4348-92ba-5caf9433b9cb?api-version=2017-08-31 + response: + body: + string: "{\n \"name\": \"03b3acd2-df2c-4843-92ba-5caf9433b9cb\",\n \"status\": + \"Succeeded\",\n \"startTime\": \"2022-05-27T00:05:50.4Z\",\n \"endTime\": + \"2022-05-27T00:09:26.1755092Z\"\n }" + headers: + cache-control: + - no-cache + content-length: + - '164' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:09:51 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - aks nodepool add + Connection: + - keep-alive + ParameterSetName: + - --resource-group --cluster-name --name --os-type --enable-custom-ca-trust + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002/agentPools/c000004?api-version=2022-04-02-preview + response: + body: + string: "{\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002/agentPools/c000004\",\n + \ \"name\": \"c000004\",\n \"type\": \"Microsoft.ContainerService/managedClusters/agentPools\",\n + \ \"properties\": {\n \"count\": 3,\n \"vmSize\": \"Standard_DS2_v2\",\n + \ \"osDiskSizeGB\": 128,\n \"osDiskType\": \"Managed\",\n \"kubeletDiskType\": + \"OS\",\n \"workloadRuntime\": \"OCIContainer\",\n \"maxPods\": 110,\n + \ \"type\": \"VirtualMachineScaleSets\",\n \"scaleDownMode\": \"Delete\",\n + \ \"provisioningState\": \"Succeeded\",\n \"powerState\": {\n \"code\": + \"Running\"\n },\n \"orchestratorVersion\": \"1.22.6\",\n \"enableNodePublicIP\": + false,\n \"enableCustomCATrust\": true,\n \"mode\": \"User\",\n \"enableEncryptionAtHost\": + false,\n \"enableUltraSSD\": false,\n \"osType\": \"Linux\",\n \"osSKU\": + \"Ubuntu\",\n \"nodeImageVersion\": \"AKSUbuntu-1804gen2containerd-2022.05.10\",\n + \ \"upgradeSettings\": {},\n \"enableFIPS\": false\n }\n }" + headers: + cache-control: + - no-cache + content-length: + - '973' + content-type: + - application/json + date: + - Fri, 27 May 2022 00:09:51 GMT + expires: + - '-1' + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - aks delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -g -n --yes --no-wait + User-Agent: + - AZURECLI/2.36.0 azsdk-python-azure-mgmt-containerservice/19.0.0b Python/3.8.9 + (macOS-12.4-x86_64-i386-64bit) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.ContainerService/managedClusters/cliakstest000002?api-version=2022-04-02-preview + response: + body: + string: '' + headers: + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operations/36fb350d-ecda-48f4-bbac-0440411b0b4c?api-version=2017-08-31 + cache-control: + - no-cache + content-length: + - '0' + date: + - Fri, 27 May 2022 00:09:53 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/eastus/operationresults/36fb350d-ecda-48f4-bbac-0440411b0b4c?api-version=2017-08-31 + pragma: + - no-cache + server: + - nginx + strict-transport-security: + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-deletes: + - '14999' + status: + code: 202 + message: Accepted +version: 1 diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py b/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py index baf01cf2882..6c7694128fe 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py @@ -1411,6 +1411,7 @@ def test_aks_create_add_nodepool_with_motd(self, resource_group, resource_group_ 'ssh_key_value': self.generate_ssh_keys(), 'message_of_the_day': _get_test_data_file("motd.txt") }) + # 1. create create_cmd = 'aks create --resource-group={resource_group} --name={name} ' \ '--nodepool-name {node_pool_name} -c 1 ' \ @@ -1436,6 +1437,45 @@ def test_aks_create_add_nodepool_with_motd(self, resource_group, resource_group_ self.cmd( 'aks delete -g {resource_group} -n {name} --yes --no-wait', checks=[self.is_empty()]) + @AllowLargeResponse() + @AKSCustomResourceGroupPreparer(random_name_length=17, name_prefix='clitest', location='eastus') + def test_aks_custom_ca_trust_flow(self, resource_group, resource_group_location): + aks_name = self.create_random_name('cliakstest', 16) + node_pool_name = self.create_random_name('c', 6) + node_pool_name_second = self.create_random_name('c', 6) + self.kwargs.update({ + 'resource_group': resource_group, + 'name': aks_name, + 'node_pool_name': node_pool_name, + 'node_pool_name_second': node_pool_name_second, + 'ssh_key_value': self.generate_ssh_keys(), + }) + + # 1. create + create_cmd = 'aks create --resource-group={resource_group} --name={name} ' \ + '--nodepool-name {node_pool_name} -c 1 ' \ + '--ssh-key-value={ssh_key_value} ' \ + '--enable-custom-ca-trust' + self.cmd(create_cmd, checks=[ + self.check('provisioningState', 'Succeeded'), + self.check('agentPoolProfiles[0].enableCustomCaTrust', 'True') + ]) + + # 2. add nodepool + self.cmd('aks nodepool add ' + '--resource-group={resource_group} ' + '--cluster-name={name} ' + '--name={node_pool_name_second} ' + '--os-type Linux ' + '--enable-custom-ca-trust', + checks=[ + self.check('provisioningState', 'Succeeded'), + self.check('enableCustomCaTrust', 'True'), + ]) + + # delete + self.cmd('aks delete -g {resource_group} -n {name} --yes --no-wait', checks=[self.is_empty()]) + @AllowLargeResponse() @AKSCustomResourceGroupPreparer(random_name_length=17, name_prefix='clitest', location='centraluseuap') def test_aks_nodepool_stop_and_start(self, resource_group, resource_group_location): diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py index b852b3a3479..d02535a7ea1 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py @@ -594,6 +594,27 @@ def test_get_message_of_the_day(self): ) self.assertEqual(ctx_3.get_message_of_the_day(), "W10=") + def test_get_enable_custom_ca_trust(self): + # default + ctx_1 = AKSPreviewContext( + self.cmd, + {"enable_custom_ca_trust": None}, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + self.assertEqual(ctx_1.get_enable_custom_ca_trust(), None) + agent_pool_profile = self.models.ManagedClusterAgentPoolProfile( + name="test_nodepool_name", + enable_custom_ca_trust=True, + ) + mc = self.models.ManagedCluster( + location="test_location", agent_pool_profiles=[agent_pool_profile] + ) + ctx_1.attach_mc(mc) + self.assertEqual( + ctx_1.get_enable_custom_ca_trust(), True + ) + def test_get_kubelet_config(self): # default ctx_1 = AKSPreviewContext( @@ -3527,6 +3548,7 @@ def test_construct_mc_preview_profile(self): mode="System", enable_auto_scaling=False, enable_fips=False, + enable_custom_ca_trust=False, ) ssh_config_1 = self.models.ContainerServiceSshConfiguration( public_keys=[ diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_validators.py b/src/aks-preview/azext_aks_preview/tests/latest/test_validators.py index 819ceb13228..6ae5c137a1b 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_validators.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_validators.py @@ -99,11 +99,19 @@ def __init__(self, spot_max_price): self.priority = "Spot" self.spot_max_price = spot_max_price + class MessageOfTheDayNamespace: def __init__(self, message_of_the_day, os_type): self.os_type = os_type self.message_of_the_day = message_of_the_day + +class EnableCustomCATrustNamespace: + def __init__(self, os_type, enable_custom_ca_trust): + self.os_type = os_type + self.enable_custom_ca_trust = enable_custom_ca_trust + + class TestMaxSurge(unittest.TestCase): def test_valid_cases(self): valid = ["5", "33%", "1", "100%"] @@ -164,6 +172,22 @@ def test_fail_if_os_type_invalid(self): validators.validate_message_of_the_day(MessageOfTheDayNamespace("foo", "invalid")) self.assertTrue('--message-of-the-day can only be set for linux nodepools' in str(cm.exception), msg=str(cm.exception)) + +class TestEnableCustomCATrust(unittest.TestCase): + def test_pass_if_os_type_linux(self): + validators.validate_enable_custom_ca_trust(EnableCustomCATrustNamespace("Linux", True)) + + def test_fail_if_os_type_windows(self): + with self.assertRaises(CLIError) as cm: + validators.validate_enable_custom_ca_trust(EnableCustomCATrustNamespace("Windows", True)) + self.assertTrue('--enable_custom_ca_trust can only be set for Linux nodepools' in str(cm.exception), msg=str(cm.exception)) + + def test_fail_if_os_type_invalid(self): + with self.assertRaises(CLIError) as cm: + validators.validate_enable_custom_ca_trust(EnableCustomCATrustNamespace("invalid", True)) + self.assertTrue('--enable_custom_ca_trust can only be set for Linux nodepools' in str(cm.exception), msg=str(cm.exception)) + + class ValidateAddonsNamespace: def __init__(self, addons): self.addons = addons diff --git a/src/aks-preview/setup.py b/src/aks-preview/setup.py index 970fccb82a3..96a91ebfba5 100644 --- a/src/aks-preview/setup.py +++ b/src/aks-preview/setup.py @@ -9,7 +9,7 @@ from setuptools import setup, find_packages -VERSION = "0.5.75" +VERSION = "0.5.76" CLASSIFIERS = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers",