Skip to content

Commit 2efe55a

Browse files
authored
[AKS] az aks create/update: Change --enable-azure-container-storage --disable-azure-container-storage behavior and add --container-storage-version (#31966)
1 parent 604774c commit 2efe55a

File tree

10 files changed

+1414
-547
lines changed

10 files changed

+1414
-547
lines changed

linter_exclusions.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ aks create:
294294
node_provisioning_default_pools:
295295
rule_exclusions:
296296
- option_length_too_long
297+
container_storage_version:
298+
rule_exclusions:
299+
- option_length_too_long
297300
aks enable-addons:
298301
parameters:
299302
workspace_resource_id:
@@ -380,6 +383,9 @@ aks update:
380383
node_provisioning_default_pools:
381384
rule_exclusions:
382385
- option_length_too_long
386+
container_storage_version:
387+
rule_exclusions:
388+
- option_length_too_long
383389
aks update-credentials:
384390
parameters:
385391
aad_server_app_secret:

src/azure-cli/azure/cli/command_modules/acs/_params.py

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,12 @@ def load_arguments(self, _):
506506
# azure container storage
507507
c.argument(
508508
"enable_azure_container_storage",
509-
arg_type=get_enum_type(storage_pool_types),
510-
help="enable azure container storage and define storage pool type",
509+
arg_type=_get_enable_azure_container_storage_type(),
510+
help="enable azure container storage. Can be used as a flag (defaults to True) or with a storage pool type value: (azureDisk, ephemeralDisk, elasticSan)",
511+
)
512+
c.argument(
513+
"container_storage_version",
514+
help="set azure container storage version, the latest version will be installed by default",
511515
)
512516
c.argument(
513517
"storage_pool_name",
@@ -704,13 +708,17 @@ def load_arguments(self, _):
704708
# azure container storage
705709
c.argument(
706710
"enable_azure_container_storage",
707-
arg_type=get_enum_type(storage_pool_types),
708-
help="enable azure container storage and define storage pool type",
711+
arg_type=_get_enable_azure_container_storage_type(),
712+
help="enable azure container storage. Can be used as a flag (defaults to True) or with a storage pool type value: (azureDisk, ephemeralDisk, elasticSan)",
709713
)
710714
c.argument(
711715
"disable_azure_container_storage",
712-
arg_type=get_enum_type(disable_storage_pool_types),
713-
help="disable azure container storage or any one of the storage pool types",
716+
arg_type=_get_disable_azure_container_storage_type(),
717+
help="disable azure container storage or any one of the storage pool types. Can be used as a flag (defaults to True) or with a storagepool type value: azureDisk, ephemeralDisk, elasticSan, all (to disable all storage pools).",
718+
)
719+
c.argument(
720+
"container_storage_version",
721+
help="set azure container storage version, the latest version will be installed by default",
714722
)
715723
c.argument(
716724
"storage_pool_name",
@@ -1135,3 +1143,65 @@ def _get_default_install_location(exe_name):
11351143
else:
11361144
install_location = None
11371145
return install_location
1146+
1147+
1148+
def _get_enable_azure_container_storage_type():
1149+
"""Custom argument type that accepts both None and enum values"""
1150+
import argparse
1151+
from azure.cli.core.azclierror import InvalidArgumentValueError
1152+
1153+
class AzureContainerStorageAction(argparse.Action):
1154+
def __call__(self, parser, namespace, values, option_string=None):
1155+
if values is None:
1156+
# When used as a flag without value, set as True
1157+
setattr(namespace, self.dest, True)
1158+
return
1159+
1160+
if isinstance(values, str):
1161+
# Handle enum values (case insensitive)
1162+
for storage_type in storage_pool_types:
1163+
if values.lower() == storage_type.lower():
1164+
setattr(namespace, self.dest, storage_type)
1165+
return
1166+
1167+
# Invalid value
1168+
valid_values = storage_pool_types
1169+
raise InvalidArgumentValueError(
1170+
f"Invalid value '{values}'. Valid values are: {', '.join(valid_values)}"
1171+
)
1172+
1173+
return CLIArgumentType(
1174+
nargs='?', # Optional argument
1175+
action=AzureContainerStorageAction,
1176+
)
1177+
1178+
1179+
def _get_disable_azure_container_storage_type():
1180+
"""Custom argument type that accepts both None and enum values"""
1181+
import argparse
1182+
from azure.cli.core.azclierror import InvalidArgumentValueError
1183+
1184+
class AzureContainerStorageAction(argparse.Action):
1185+
def __call__(self, parser, namespace, values, option_string=None):
1186+
if values is None:
1187+
# When used as a flag without value, set as True
1188+
setattr(namespace, self.dest, True)
1189+
return
1190+
1191+
if isinstance(values, str):
1192+
# Handle enum values (case insensitive)
1193+
for storage_type in disable_storage_pool_types:
1194+
if values.lower() == storage_type.lower():
1195+
setattr(namespace, self.dest, storage_type)
1196+
return
1197+
1198+
# Invalid value
1199+
valid_values = disable_storage_pool_types
1200+
raise InvalidArgumentValueError(
1201+
f"Invalid value '{values}'. Valid values are: {', '.join(valid_values)}"
1202+
)
1203+
1204+
return CLIArgumentType(
1205+
nargs='?', # Optional argument
1206+
action=AzureContainerStorageAction,
1207+
)

src/azure-cli/azure/cli/command_modules/acs/azurecontainerstorage/_consts.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66
CONST_ACSTOR_ALL = "all"
77
CONST_ACSTOR_IO_ENGINE_LABEL_KEY = "acstor.azure.com/io-engine"
88
CONST_ACSTOR_IO_ENGINE_LABEL_VAL = "acstor"
9-
CONST_ACSTOR_K8S_EXTENSION_NAME = "microsoft.azurecontainerstorage"
9+
CONST_ACSTOR_V1_K8S_EXTENSION_NAME = "microsoft.azurecontainerstorage"
10+
CONST_ACSTOR_V1_EXT_INSTALLATION_NAME = "azurecontainerstorage"
11+
CONST_ACSTOR_VERSION_V1 = "1"
1012
CONST_DISK_TYPE_EPHEMERAL_VOLUME_ONLY = "EphemeralVolumeOnly"
1113
CONST_DISK_TYPE_PV_WITH_ANNOTATION = "PersistentVolumeWithAnnotation"
1214
CONST_EPHEMERAL_NVME_PERF_TIER_BASIC = "Basic"
1315
CONST_EPHEMERAL_NVME_PERF_TIER_PREMIUM = "Premium"
1416
CONST_EPHEMERAL_NVME_PERF_TIER_STANDARD = "Standard"
15-
CONST_EXT_INSTALLATION_NAME = "azurecontainerstorage"
17+
CONST_ACSTOR_EXT_INSTALLATION_NAME = "acstor"
18+
CONST_ACSTOR_EXT_INSTALLATION_NAMESPACE = "kube-system"
19+
CONST_ACSTOR_K8S_EXTENSION_NAME = "microsoft.azurecontainerstoragev2"
1620
CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME = "azext_k8s_extension._client_factory"
1721
CONST_K8S_EXTENSION_CUSTOM_MOD_NAME = "azext_k8s_extension.custom"
1822
CONST_K8S_EXTENSION_NAME = "k8s-extension"

src/azure-cli/azure/cli/command_modules/acs/azurecontainerstorage/_helpers.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
from azure.cli.command_modules.acs.azurecontainerstorage._consts import (
99
CONST_ACSTOR_ALL,
1010
CONST_ACSTOR_IO_ENGINE_LABEL_KEY,
11-
CONST_ACSTOR_K8S_EXTENSION_NAME,
11+
CONST_ACSTOR_V1_K8S_EXTENSION_NAME,
1212
CONST_DISK_TYPE_EPHEMERAL_VOLUME_ONLY,
1313
CONST_DISK_TYPE_PV_WITH_ANNOTATION,
1414
CONST_EPHEMERAL_NVME_PERF_TIER_BASIC,
1515
CONST_EPHEMERAL_NVME_PERF_TIER_PREMIUM,
1616
CONST_EPHEMERAL_NVME_PERF_TIER_STANDARD,
17-
CONST_EXT_INSTALLATION_NAME,
17+
CONST_ACSTOR_V1_EXT_INSTALLATION_NAME,
1818
CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME,
1919
CONST_K8S_EXTENSION_CUSTOM_MOD_NAME,
2020
CONST_K8S_EXTENSION_NAME,
@@ -29,7 +29,7 @@
2929
build_role_scope,
3030
delete_role_assignments,
3131
)
32-
from azure.cli.core.azclierror import UnknownError
32+
from azure.cli.core.azclierror import ResourceNotFoundError, UnknownError
3333
from knack.log import get_logger
3434

3535
logger = get_logger(__name__)
@@ -133,12 +133,12 @@ def check_if_extension_is_installed(cmd, resource_group, cluster_name) -> bool:
133133
client,
134134
resource_group,
135135
cluster_name,
136-
CONST_EXT_INSTALLATION_NAME,
136+
CONST_ACSTOR_V1_EXT_INSTALLATION_NAME,
137137
"managedClusters",
138138
)
139139

140140
extension_type = extension.extension_type.lower()
141-
if extension_type != CONST_ACSTOR_K8S_EXTENSION_NAME:
141+
if extension_type != CONST_ACSTOR_V1_K8S_EXTENSION_NAME:
142142
return_val = False
143143
except: # pylint: disable=bare-except
144144
return_val = False
@@ -169,12 +169,12 @@ def get_extension_installed_and_cluster_configs(
169169
client,
170170
resource_group,
171171
cluster_name,
172-
CONST_EXT_INSTALLATION_NAME,
172+
CONST_ACSTOR_V1_EXT_INSTALLATION_NAME,
173173
"managedClusters",
174174
)
175175

176176
extension_type = extension.extension_type.lower()
177-
is_extension_installed = extension_type == CONST_ACSTOR_K8S_EXTENSION_NAME
177+
is_extension_installed = extension_type == CONST_ACSTOR_V1_K8S_EXTENSION_NAME
178178
config_settings = extension.configuration_settings
179179

180180
if is_extension_installed and config_settings is not None:
@@ -245,6 +245,35 @@ def get_extension_installed_and_cluster_configs(
245245
)
246246

247247

248+
def get_container_storage_extension_installed(
249+
cmd,
250+
resource_group,
251+
cluster_name,
252+
extension_name,
253+
) -> Tuple[bool, str]:
254+
255+
client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME)
256+
client = client_factory.cf_k8s_extension_operation(cmd.cli_ctx)
257+
k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME)
258+
is_extension_installed = False
259+
extension_version = ""
260+
261+
try:
262+
extension = k8s_extension_custom_mod.show_k8s_extension(
263+
client,
264+
resource_group,
265+
cluster_name,
266+
extension_name,
267+
"managedClusters",
268+
)
269+
is_extension_installed = True
270+
extension_version = extension.current_version
271+
except ResourceNotFoundError:
272+
# Extension not found, which is expected if not installed.
273+
is_extension_installed = False
274+
return is_extension_installed, extension_version
275+
276+
248277
def get_initial_resource_value_args(
249278
storage_pool_type,
250279
storage_pool_option,

0 commit comments

Comments
 (0)