Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/aks-preview/azext_aks_preview/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# pylint: disable=unused-import
import azext_aks_preview._help
from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW
from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW, CUSTOM_MGMT_AKS_PIS_PREVIEW


def register_aks_preview_resource_type():
Expand All @@ -19,6 +19,12 @@ def register_aks_preview_resource_type():
None,
)

register_resource_type(
"latest",
CUSTOM_MGMT_AKS_PIS_PREVIEW,
None,
)


class ContainerServiceCommandsLoader(AzCommandsLoader):

Expand Down
11 changes: 11 additions & 0 deletions src/aks-preview/azext_aks_preview/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
CUSTOM_MGMT_AKS_PREVIEW = CustomResourceType('azext_aks_preview.vendored_sdks.azure_mgmt_preview_aks',
'ContainerServiceClient')

CUSTOM_MGMT_AKS_PIS_PREVIEW = CustomResourceType('azext_aks_preview.vendored_sdks.azure_mgmt_preview_aks_pis',
'ContainerServiceClient')

# Note: cf_xxx, as the client_factory option value of a command group at command declaration, it should ignore
# parameters other than cli_ctx; get_xxx_client is used as the client of other services in the command implementation,
# and usually accepts subscription_id as a parameter to reconfigure the subscription when sending the request
Expand All @@ -23,6 +26,10 @@ def get_container_service_client(cli_ctx, subscription_id=None):
return get_mgmt_service_client(cli_ctx, CUSTOM_MGMT_AKS_PREVIEW, subscription_id=subscription_id)


def get_container_service_pis_client(cli_ctx, subscription_id=None):
return get_mgmt_service_client(cli_ctx, CUSTOM_MGMT_AKS_PIS_PREVIEW, subscription_id=subscription_id)


def cf_container_services(cli_ctx, *_):
return get_container_service_client(cli_ctx).container_services

Expand Down Expand Up @@ -163,3 +170,7 @@ def cf_jwt_authenticators(cli_ctx, *_):

def cf_vm_skus(cli_ctx, *_):
return get_container_service_client(cli_ctx).vm_skus


def cf_prepared_image_specifications(cli_ctx, *_, subscription_id=None):
return get_container_service_pis_client(cli_ctx, subscription_id=subscription_id).prepared_image_specifications
56 changes: 56 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,9 @@
Provides scaled and performance-guaranteed control plane capacity for AKS clusters.
Enables customers to select a control plane scaling size that delivers higher API server throughput,
increased etcd capacity, and faster pod scheduling rates. Available values are 'H2', 'H4', and 'H8'.
- name: --prepared-image-specification
type: string
short-summary: (PREVIEW) The resource ID of the prepared image specification to use for provisioning nodes in the default 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
Expand Down Expand Up @@ -2309,6 +2312,9 @@
- name: --final-soak-duration
type: int
short-summary: Wait time (in minutes) after all old nodes are drained before removing them. Default is 60 minutes. Only for blue-green upgrades.
- name: --prepared-image-specification
type: string
short-summary: The resource ID of the prepared image specification to use for provisioning nodes in the 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
Expand Down Expand Up @@ -4656,3 +4662,53 @@
- name: Show a specific JWT authenticator configuration
text: az aks jwtauthenticator show -g MyResourceGroup --cluster-name MyCluster --name myjwt
"""

helps['aks prepared-image-specification'] = """
type: group
short-summary: Commands to manage prepared image specifications.
"""

helps['aks prepared-image-specification create'] = """
type: command
short-summary: Create a new prepared image specification.
"""

helps['aks prepared-image-specification update'] = """
type: command
short-summary: Update a prepared image specification.
"""

helps['aks prepared-image-specification delete'] = """
type: command
short-summary: Delete a prepared image specification.
"""

helps['aks prepared-image-specification list'] = """
type: command
short-summary: List prepared image specifications.
"""

helps['aks prepared-image-specification show'] = """
type: command
short-summary: Show a prepared image specification.
"""

helps['aks prepared-image-specification version'] = """
type: group
short-summary: Commands to manage prepared image specification versions.
"""

helps['aks prepared-image-specification version delete'] = """
type: command
short-summary: Delete a prepared image specification version.
"""

helps['aks prepared-image-specification version list'] = """
type: command
short-summary: List prepared image specification versions.
"""

helps['aks prepared-image-specification version show'] = """
type: command
short-summary: Show a prepared image specification version.
"""
100 changes: 100 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
tags_type,
zones_type,
)
from azure.cli.core.commands.validators import validate_file_or_dict
from azext_aks_preview._validators import (
validate_nat_gateway_managed_outbound_ipv6_count,
validate_nat_gateway_v2_params,
Expand Down Expand Up @@ -247,6 +248,7 @@
validate_drain_batch_size,
validate_resource_group_parameter,
validate_location_resource_group_cluster_parameters,
validate_prepared_image_specification,
)
from azext_aks_preview.azurecontainerstorage._consts import (
CONST_ACSTOR_ALL,
Expand Down Expand Up @@ -1279,6 +1281,13 @@ def load_arguments(self, _):
is_preview=True,
help="Enable continuous control plane and addon monitor for the cluster.",
)
# prepared image specification
c.argument(
'prepared_image_specification',
is_preview=True,
validator=validate_prepared_image_specification,
help='The resource ID of the prepared image specification to use for provisioning nodes in the default node pool.'
)

with self.argument_context("aks update") as c:
# managed cluster paramerters
Expand Down Expand Up @@ -2208,6 +2217,13 @@ def load_arguments(self, _):
'localdns_config',
help='Path to a JSON file to configure the local DNS profile for a new nodepool.'
)
# prepared image specification
c.argument(
'prepared_image_specification',
is_preview=True,
validator=validate_prepared_image_specification,
help='The resource ID of the prepared image specification to use for provisioning nodes in the node pool.'
)

with self.argument_context("aks nodepool update") as c:
c.argument(
Expand Down Expand Up @@ -3398,6 +3414,90 @@ def load_arguments(self, _):
help="Show all VM SKU information including those not available for the current subscription.",
)

with self.argument_context("aks prepared-image-specification create") as c:
c.argument(
"name",
options_list=["--name", "-n"],
required=True,
help="The prepared image specification name.",
)
c.argument(
"container_images",
nargs="+",
help="Container images.",
)
c.argument(
"customization_scripts",
type=validate_file_or_dict,
help="Customization scripts. Expected value: json-string/@json-file.",
)
c.argument(
"assign_identity",
help="Specify an existing user assigned identity.",
)
c.argument(
"version",
required=True,
help="The prepared image specification version.",
)

with self.argument_context("aks prepared-image-specification update") as c:
c.argument(
"name",
options_list=["--name", "-n"],
required=True,
help="The prepared image specification name.",
)

with self.argument_context("aks prepared-image-specification delete") as c:
c.argument(
"name",
options_list=["--name", "-n"],
required=True,
help="The prepared image specification name.",
)

with self.argument_context("aks prepared-image-specification show") as c:
c.argument(
"name",
options_list=["--name", "-n"],
required=True,
help="The prepared image specification name.",
)

with self.argument_context("aks prepared-image-specification version delete") as c:
c.argument(
"pis_name",
required=True,
help="The prepared image specification name.",
)
c.argument(
"name",
options_list=["--name", "-n"],
required=True,
help="The version name.",
)

with self.argument_context("aks prepared-image-specification version list") as c:
c.argument(
"pis_name",
required=True,
help="The prepared image specification name.",
)

with self.argument_context("aks prepared-image-specification version show") as c:
c.argument(
"pis_name",
required=True,
help="The prepared image specification name.",
)
c.argument(
"name",
options_list=["--name", "-n"],
required=True,
help="The version name.",
)


def _get_default_install_location(exe_name):
system = platform.system()
Expand Down
16 changes: 16 additions & 0 deletions src/aks-preview/azext_aks_preview/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1204,3 +1204,19 @@ def validate_nat_gateway_v2_params(namespace):
"--nat-gateway-outbound-ip-prefixes are only "
"valid with --outbound-type managedNATGatewayV2."
)


def validate_prepared_image_specification(namespace):
if namespace.prepared_image_specification:
if not is_valid_resource_id(namespace.prepared_image_specification):
raise InvalidArgumentValueError(
"--prepared-image-specification is not a valid Azure resource ID."
)
parsed = parse_resource_id(namespace.prepared_image_specification)
resource_type = (parsed.get("type", "") + "/" + parsed.get("resource_type", "")).lower()
resource_namespace = parsed.get("namespace", "").lower()
if resource_namespace != "microsoft.containerservice" or resource_type != "preparedimagespecifications/versions":
raise InvalidArgumentValueError(
"--prepared-image-specification must be a resource ID of type "
"Microsoft.ContainerService/preparedImageSpecifications/versions."
)
20 changes: 20 additions & 0 deletions src/aks-preview/azext_aks_preview/agentpool_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,12 @@ def get_if_none_match(self) -> str:
"""
return self.raw_param.get("if_none_match")

def get_prepared_image_specification(self) -> Union[str, None]:
"""Obtain the value of prepared_image_specification.
:return: str or None
"""
return self.raw_param.get('prepared_image_specification')

def get_gateway_prefix_size(self) -> Union[int, None]:
"""Obtain the value of gateway_prefix_size.
:return: int or None
Expand Down Expand Up @@ -1594,6 +1600,18 @@ def set_up_localdns_profile(self, agentpool: AgentPool) -> AgentPool:
self._ensure_agentpool(agentpool)
return self.context.build_localdns_profile(agentpool)

def set_up_prepared_image_specification(self, agentpool: AgentPool) -> AgentPool:
"""Set up prepared image specification profile for the AgentPool object."""
self._ensure_agentpool(agentpool)

prepared_image_specification = self.context.get_prepared_image_specification()
if prepared_image_specification is not None:
agentpool.prepared_image_specification_profile = self.models.PreparedImageSpecificationProfile( # pylint: disable=no-member
prepared_image_specification_id=prepared_image_specification,
)

return agentpool

def construct_agentpool_profile_preview(self) -> AgentPool:
"""The overall controller used to construct the preview AgentPool profile.

Expand Down Expand Up @@ -1653,6 +1671,8 @@ def construct_agentpool_profile_preview(self) -> AgentPool:
agentpool = self.set_up_virtual_machines_profile(agentpool)
# set up local DNS profile
agentpool = self.set_up_localdns_profile(agentpool)
# set up prepared image specification
agentpool = self.set_up_prepared_image_specification(agentpool)
# set up upgrade strategy
agentpool = self.set_up_upgrade_strategy(agentpool)
# set up blue green upgrade settings
Expand Down
50 changes: 50 additions & 0 deletions src/aks-preview/azext_aks_preview/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
cf_identity_bindings,
cf_jwt_authenticators,
cf_vm_skus,
cf_prepared_image_specifications,
)

from azext_aks_preview._format import (
Expand Down Expand Up @@ -159,6 +160,12 @@ def load_command_table(self, _):
client_factory=cf_vm_skus,
)

prepared_image_specifications_sdk = CliCommandType(
operations_tmpl="azext_aks_preview.vendored_sdks.azure_mgmt_preview_aks_pis."
"operations._operations#PreparedImageSpecificationsOperations.{}",
client_factory=cf_prepared_image_specifications,
)

# AKS managed cluster commands
with self.command_group(
"aks",
Expand Down Expand Up @@ -636,3 +643,46 @@ def load_command_table(self, _):
self.command_table["aks safeguards delete"] = Delete(loader=self)
self.command_table["aks safeguards list"] = List(loader=self)
self.command_table["aks safeguards wait"] = Wait(loader=self)

with self.command_group("aks prepared-image-specification", prepared_image_specifications_sdk,
client_factory=cf_prepared_image_specifications) as g:
g.custom_command(
"create",
"aks_prepared_image_specification_create",
supports_no_wait=True,
)
g.custom_command(
"update",
"aks_prepared_image_specification_update",
)
g.custom_command(
"delete",
"aks_prepared_image_specification_delete",
supports_no_wait=True,
confirmation=True,
)
g.custom_command(
"list",
"aks_prepared_image_specification_list",
)
g.custom_show_command(
"show",
"aks_prepared_image_specification_show",
)

with self.command_group("aks prepared-image-specification version", prepared_image_specifications_sdk,
client_factory=cf_prepared_image_specifications) as g:
g.custom_command(
"delete",
"aks_prepared_image_specification_version_delete",
supports_no_wait=True,
confirmation=True,
)
g.custom_command(
"list",
"aks_prepared_image_specification_version_list",
)
g.custom_show_command(
"show",
"aks_prepared_image_specification_version_show",
)
Loading