|
15 | 15 |
|
16 | 16 | from azure.mgmt.containerservice.models import KubernetesSupportPlan |
17 | 17 |
|
| 18 | +from azure.cli.command_modules.acs._client_factory import get_graph_client |
18 | 19 | from azure.cli.command_modules.acs._consts import ( |
19 | 20 | CONST_LOAD_BALANCER_SKU_BASIC, |
20 | 21 | CONST_LOAD_BALANCER_SKU_STANDARD, |
| 22 | + CONST_MANAGED_CLUSTER_SKU_NAME_BASE, |
| 23 | + CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC, |
21 | 24 | CONST_MANAGED_CLUSTER_SKU_TIER_FREE, |
22 | 25 | CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD, |
23 | 26 | CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM, |
|
71 | 74 | from azure.cli.command_modules.acs._resourcegroup import get_rg_location |
72 | 75 | from azure.cli.command_modules.acs._roleassignments import ( |
73 | 76 | add_role_assignment, |
| 77 | + add_role_assignment_executor, |
74 | 78 | ensure_aks_acr, |
75 | 79 | ensure_cluster_identity_permission_on_kubelet_identity, |
76 | 80 | subnet_role_assignment_exists, |
@@ -316,6 +320,7 @@ def external_functions(self) -> SimpleNamespace: |
316 | 320 | external_functions["get_user_assigned_identity_by_resource_id"] = get_user_assigned_identity_by_resource_id |
317 | 321 | external_functions["get_rg_location"] = get_rg_location |
318 | 322 | external_functions["add_role_assignment"] = add_role_assignment |
| 323 | + external_functions["add_role_assignment_executor"] = add_role_assignment_executor |
319 | 324 | external_functions["add_ingress_appgw_addon_role_assignment"] = add_ingress_appgw_addon_role_assignment |
320 | 325 | external_functions["add_monitoring_role_assignment"] = add_monitoring_role_assignment |
321 | 326 | external_functions["add_virtual_node_role_assignment"] = add_virtual_node_role_assignment |
@@ -2270,6 +2275,20 @@ def get_ip_families(self) -> Union[List[str], None]: |
2270 | 2275 | # this parameter does not need validation |
2271 | 2276 | return ip_families |
2272 | 2277 |
|
| 2278 | + def get_sku_name(self) -> str: |
| 2279 | + # read the original value passed by the command |
| 2280 | + skuName = self.raw_param.get("sku") |
| 2281 | + if skuName is None: |
| 2282 | + if ( |
| 2283 | + self.mc and |
| 2284 | + self.mc.sku and |
| 2285 | + getattr(self.mc.sku, 'name', None) is not None |
| 2286 | + ): |
| 2287 | + skuName = vars(self.mc.sku)['name'].lower() |
| 2288 | + else: |
| 2289 | + skuName = CONST_MANAGED_CLUSTER_SKU_NAME_BASE |
| 2290 | + return skuName |
| 2291 | + |
2273 | 2292 | def _get_outbound_type( |
2274 | 2293 | self, |
2275 | 2294 | enable_validation: bool = False, |
@@ -2313,6 +2332,12 @@ def _get_outbound_type( |
2313 | 2332 | if not read_from_mc and not isBasicSKULb and outbound_type is None: |
2314 | 2333 | outbound_type = CONST_OUTBOUND_TYPE_LOAD_BALANCER |
2315 | 2334 |
|
| 2335 | + skuName = self.get_sku_name() |
| 2336 | + isVnetSubnetIdEmpty = self.get_vnet_subnet_id() in ["", None] |
| 2337 | + if skuName is not None and skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC and isVnetSubnetIdEmpty: |
| 2338 | + # outbound_type of Automatic SKU should be ManagedNATGateway if no subnet id provided. |
| 2339 | + outbound_type = CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY |
| 2340 | + |
2316 | 2341 | # validation |
2317 | 2342 | # Note: The parameters involved in the validation are not verified in their own getters. |
2318 | 2343 | if enable_validation: |
@@ -2781,6 +2806,10 @@ def _get_enable_addons(self, enable_validation: bool = False) -> List[str]: |
2781 | 2806 | # normalize |
2782 | 2807 | enable_addons = enable_addons.split(',') if enable_addons else [] |
2783 | 2808 |
|
| 2809 | + sku_name = self.get_sku_name() |
| 2810 | + if sku_name == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC: |
| 2811 | + enable_addons.append("monitoring") |
| 2812 | + |
2784 | 2813 | # validation |
2785 | 2814 | if enable_validation: |
2786 | 2815 | # check duplicate addons |
@@ -2956,6 +2985,9 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: |
2956 | 2985 | ) == "true" |
2957 | 2986 | ) |
2958 | 2987 |
|
| 2988 | + sku_name = self.get_sku_name() |
| 2989 | + if sku_name == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC: |
| 2990 | + return True |
2959 | 2991 | # this parameter does not need dynamic completion |
2960 | 2992 | # this parameter does not need validation |
2961 | 2993 | return enable_msi_auth_for_monitoring |
@@ -3973,7 +4005,8 @@ def _get_apiserver_subnet_id(self, enable_validation: bool = False) -> Union[str |
3973 | 4005 | ( |
3974 | 4006 | enable_apiserver_vnet_integration is None or |
3975 | 4007 | enable_apiserver_vnet_integration is False |
3976 | | - ) |
| 4008 | + ) and |
| 4009 | + self.get_sku_name() != CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC |
3977 | 4010 | ): |
3978 | 4011 | raise RequiredArgumentMissingError( |
3979 | 4012 | '"--apiserver-subnet-id" requires "--enable-apiserver-vnet-integration".') |
@@ -5191,6 +5224,9 @@ def _get_disable_local_accounts(self, enable_validation: bool = False) -> bool: |
5191 | 5224 | self.mc.disable_local_accounts is not None |
5192 | 5225 | ): |
5193 | 5226 | disable_local_accounts = self.mc.disable_local_accounts |
| 5227 | + sku_name = self.get_sku_name() |
| 5228 | + if sku_name == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC: |
| 5229 | + disable_local_accounts = True |
5194 | 5230 |
|
5195 | 5231 | # this parameter does not need dynamic completion |
5196 | 5232 | # validation |
@@ -5369,6 +5405,9 @@ def _get_enable_azure_monitor_metrics(self, enable_validation: bool = False) -> |
5369 | 5405 | self.mc.azure_monitor_profile.metrics |
5370 | 5406 | ): |
5371 | 5407 | enable_azure_monitor_metrics = self.mc.azure_monitor_profile.metrics.enabled |
| 5408 | + skuName = self.get_sku_name() |
| 5409 | + if skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC: |
| 5410 | + enable_azure_monitor_metrics = True |
5372 | 5411 | # This parameter does not need dynamic completion. |
5373 | 5412 | if enable_validation: |
5374 | 5413 | if enable_azure_monitor_metrics and self._get_disable_azure_monitor_metrics(False): |
@@ -6868,17 +6907,24 @@ def set_up_sku(self, mc: ManagedCluster) -> ManagedCluster: |
6868 | 6907 | """ |
6869 | 6908 | self._ensure_mc(mc) |
6870 | 6909 |
|
6871 | | - if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD: |
6872 | | - mc.sku = self.models.ManagedClusterSKU( |
6873 | | - name="Base", |
6874 | | - tier="Standard" |
6875 | | - ) |
| 6910 | + mc.sku = self.models.ManagedClusterSKU() |
| 6911 | + skuName = self.context.get_sku_name() |
| 6912 | + tier = self.context.get_tier() |
6876 | 6913 |
|
6877 | | - if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM: |
6878 | | - mc.sku = self.models.ManagedClusterSKU( |
6879 | | - name="Base", |
6880 | | - tier="Premium" |
6881 | | - ) |
| 6914 | + if skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC: |
| 6915 | + mc.sku.name = "Automatic" |
| 6916 | + # default tier for automatic sku is standard |
| 6917 | + mc.sku.tier = "Standard" |
| 6918 | + else: |
| 6919 | + mc.sku.name = "Base" |
| 6920 | + |
| 6921 | + if tier == CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD: |
| 6922 | + mc.sku.tier = "Standard" |
| 6923 | + if tier == CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM: |
| 6924 | + mc.sku.tier = "Premium" |
| 6925 | + # backfill the tier to "Free" if it's not set |
| 6926 | + if mc.sku.tier is None: |
| 6927 | + mc.sku.tier = "Free" |
6882 | 6928 | return mc |
6883 | 6929 |
|
6884 | 6930 | def set_up_extended_location(self, mc: ManagedCluster) -> ManagedCluster: |
@@ -7385,6 +7431,21 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None: |
7385 | 7431 | self.context.get_name(), |
7386 | 7432 | ) |
7387 | 7433 |
|
| 7434 | + # Add role assignments for automatic sku |
| 7435 | + if cluster.sku is not None and cluster.sku.name == "Automatic": |
| 7436 | + try: |
| 7437 | + user = get_graph_client(self.cmd.cli_ctx).signed_in_user_get() |
| 7438 | + except Exception as e: # pylint: disable=broad-except |
| 7439 | + logger.warning("Could not get signed in user: %s", str(e)) |
| 7440 | + else: |
| 7441 | + self.context.external_functions.add_role_assignment_executor( # type: ignore # pylint: disable=protected-access |
| 7442 | + self.cmd, |
| 7443 | + "Azure Kubernetes Service RBAC Cluster Admin", |
| 7444 | + user["id"], |
| 7445 | + scope=cluster.id, |
| 7446 | + resolve_assignee=False, |
| 7447 | + ) |
| 7448 | + |
7388 | 7449 | def put_mc(self, mc: ManagedCluster) -> ManagedCluster: |
7389 | 7450 | active_cloud = get_active_cloud(self.cmd.cli_ctx) |
7390 | 7451 | if active_cloud.profile != "latest": |
@@ -7714,24 +7775,26 @@ def update_sku(self, mc: ManagedCluster) -> ManagedCluster: |
7714 | 7775 | """ |
7715 | 7776 | self._ensure_mc(mc) |
7716 | 7777 |
|
7717 | | - # Premium without LTS is ok (not vice versa) |
7718 | | - if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM: |
7719 | | - mc.sku = self.models.ManagedClusterSKU( |
7720 | | - name="Base", |
7721 | | - tier="Premium" |
7722 | | - ) |
7723 | | - |
7724 | | - if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD: |
7725 | | - mc.sku = self.models.ManagedClusterSKU( |
7726 | | - name="Base", |
7727 | | - tier="Standard" |
7728 | | - ) |
| 7778 | + # there are existing MCs with nil sku, that is Base/Free |
| 7779 | + if mc.sku is None: |
| 7780 | + mc.sku = self.models.ManagedClusterSKU() |
| 7781 | + skuName = self.context.get_sku_name() |
| 7782 | + tier = self.context.get_tier() |
| 7783 | + if skuName == CONST_MANAGED_CLUSTER_SKU_NAME_AUTOMATIC: |
| 7784 | + mc.sku.name = "Automatic" |
| 7785 | + else: |
| 7786 | + mc.sku.name = "Base" |
7729 | 7787 |
|
7730 | | - if self.context.get_tier() == CONST_MANAGED_CLUSTER_SKU_TIER_FREE: |
7731 | | - mc.sku = self.models.ManagedClusterSKU( |
7732 | | - name="Base", |
7733 | | - tier="Free" |
7734 | | - ) |
| 7788 | + # Premium without LTS is ok (not vice versa) |
| 7789 | + if tier == CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM: |
| 7790 | + mc.sku.tier = "Premium" |
| 7791 | + if tier == CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD: |
| 7792 | + mc.sku.tier = "Standard" |
| 7793 | + if tier == CONST_MANAGED_CLUSTER_SKU_TIER_FREE: |
| 7794 | + mc.sku.tier = "Free" |
| 7795 | + # backfill the tier to "Free" if it's not set |
| 7796 | + if mc.sku.tier is None: |
| 7797 | + mc.sku.tier = "Free" |
7735 | 7798 | return mc |
7736 | 7799 |
|
7737 | 7800 | def update_outbound_type_in_network_profile(self, mc: ManagedCluster) -> ManagedCluster: |
|
0 commit comments