Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def cf_maintenance_configurations(cli_ctx, *_):
return get_container_service_client(cli_ctx).maintenance_configurations


def cf_managed_namespaces(cli_ctx, *_):
return get_container_service_client(cli_ctx).managed_namespaces


def cf_agent_pools(cli_ctx, *_):
return get_container_service_client(cli_ctx).agent_pools

Expand Down
10 changes: 10 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@
# azure policy
CONST_AZURE_POLICY_ADDON_NAME = "azurepolicy"

# Managed Namespace
CONST_NAMESPACE_ADOPTION_POLICY_NEVER = "Never"
CONST_NAMESPACE_ADOPTION_POLICY_IFIDENTICAL = "IfIdentical"
CONST_NAMESPACE_ADOPTION_POLICY_ALWAYS = "Always"
CONST_NAMESPACE_NETWORK_POLICY_RULE_DENYALL = "DenyAll"
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL = "AllowAll"
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE = "AllowSameNamespace"
CONST_NAMESPACE_DELETE_POLICY_KEEP = "Keep"
CONST_NAMESPACE_DELETE_POLICY_DELETE = "Delete"

# ingress application gateway
CONST_INGRESS_APPGW_ADDON_NAME = "ingressApplicationGateway"
CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME = "applicationGatewayName"
Expand Down
32 changes: 32 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,38 @@ def aks_show_table_format(result):
return [_aks_table_format(result)]


def aks_namespace_list_table_format(results):
"""Format an managed namespace list for display with "-o table"."""
return [_aks_namespace_list_table_format(r) for r in results]


def _aks_namespace_list_table_format(result):
if not result.get("properties"):
parsed = compile_jmes("""{
name: name,
resourceGroup: resourceGroup,
location: location
}""")
else:
parsed = compile_jmes("""{
name: name,
tags: to_string(tags),
provisioningState: to_string(properties.provisioningState),
labels: to_string(properties.labels),
annotations: to_string(properties.annotations),
cpuRequest: to_string(properties.defaultResourceQuota.cpuRequest),
cpuLimit: to_string(properties.defaultResourceQuota.cpuLimit),
memoryRequest: to_string(properties.defaultResourceQuota.memoryRequest),
memoryLimit: to_string(properties.defaultResourceQuota.memoryLimit),
ingress: to_string(properties.defaultNetworkPolicy.ingress),
egress: to_string(properties.defaultNetworkPolicy.egress),
adoptionPolicy: to_string(properties.adoptionPolicy),
deletePolicy: to_string(properties.deletePolicy)
}""")
# use ordered dicts so headers are predictable
return parsed.search(result, Options(dict_cls=OrderedDict))


def _aks_table_format(result):
parsed = compile_jmes("""{
name: name,
Expand Down
143 changes: 143 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1632,6 +1632,149 @@
}
"""

helps['aks namespace'] = """
type: group
short-summary: Commands to manage namespace in managed Kubernetes cluster.
"""

helps['aks namespace add'] = """
type: command
short-summary: Add namespace to the managed Kubernetes cluster.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
- name: --tags
type: string
short-summary: The tags of the managed namespace.
- name: --labels
type: string
short-summary: Labels for the managed namespace.
- name: --annotations
type: string
short-summary: Annotations for the managed namespace.
- name: --cpu-request
type: string
short-summary: CPU request of the namespace.
- name: --cpu-limit
type: string
short-summary: CPU limit of the namespace.
- name: --memory-request
type: string
short-summary: Memory request of the namespace.
- name: --memory-limit
type: string
short-summary: Memory limit of the namespace.
- name: --ingress-policy
type: string
short-summary: Ingress policy for the network. The default value is AllowSameNamespace.
- name: --egress-policy
type: string
short-summary: Egress policy for the network. The default value is AllowAll.
- name: --adoption-policy
type: string
short-summary: Action if Kubernetes namespace with same name already exists. The default value is Never.
- name: --delete-policy
type: string
short-summary: Delete options of a namespace. The default value is Keep.
- name: --aks-custom-headers
type: string
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2.
- name: --no-wait
type: bool
short-summary: Do not wait for the long-running operation to finish.
examples:
- name: Create a namespace in an existing AKS cluster.
text: az aks namespace add -g MyResourceGroup --cluster-name MyClusterName --name NamespaceName --cpu-request 500m --cpu-limit 800m --memory-request 1Gi --memory-limit 2Gi
- name: Create a namespace in an existing AKS cluster with labels, annotations and tags
text: az aks namespace add -g MyResourceGroup --cluster-name MyClusterName --name NamespaceName --labels a=b p=q --annotations a=b p=q --tags a=b p=q --cpu-request 500m --cpu-limit 800m --memory-request 1Gi --memory-limit 2Gi
"""

helps['aks namespace update'] = """
type: command
short-summary: Update namespace on the managed Kubernetes cluster.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
- name: --tags
type: string
short-summary: The tags of the managed namespace.
- name: --labels
type: string
short-summary: Labels for the managed namespace.
- name: --annotations
type: string
short-summary: Annotations for the managed namespace.
- name: --cpu-request
type: string
short-summary: CPU request of the namespace.
- name: --cpu-limit
type: string
short-summary: CPU limit of the namespace.
- name: --memory-request
type: string
short-summary: Memory request of the namespace.
- name: --memory-limit
type: string
short-summary: Memory limit of the namespace.
- name: --ingress-policy
type: string
short-summary: Ingress policy rule for the network.
- name: --egress-policy
type: string
short-summary: Egress policy rule for the network.
- name: --adoption-policy
type: string
short-summary: Action if Kubernetes namespace with same name already exists.
- name: --delete-policy
type: string
short-summary: Delete options of a namespace
- name: --aks-custom-headers
type: string
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2
- name: --no-wait
type: bool
short-summary: Do not wait for the long-running operation to finish
examples:
- name: update namespace in an existing AKS cluster.
text: az aks namespace update -g MyResourceGroup --cluster-name MyClusterName --name NamespaceName --labels a=b p=q --annotations a=b p=q --tags a=b p=q --cpu-request 600m --cpu-limit 800m --memory-request 2Gi --memory-limit 3Gi --adoption-policy Always
"""

helps['aks namespace show'] = """
type: command
short-summary: show the details of a managed namespace in managed Kubernetes cluster.
"""

helps['aks namespace list'] = """
type: command
short-summary: List managed namespaces in managed Kubernetes cluster.
"""

helps['aks namespace delete'] = """
type: command
short-summary: Delete a managed namespace in managed Kubernetes cluster.
"""

helps['aks namespace get-credentials'] = """
type: command
short-summary: Get access credentials for a managed namespace.
parameters:
- name: --file -f
type: string
short-summary: Kubernetes configuration file to update. Use "-" to print YAML to stdout instead.
- name: --overwrite-existing
type: bool
short-summary: Overwrite any existing cluster entry with the same name.
- name: --output -o
type: string
long-summary: Credentials are always in YAML format, so this argument is effectively ignored.
examples:
- name: Get access credentials for a managed namespace. (autogenerated)
text: az aks namespace get-credentials --resource-group MyResourceGroup --cluster-name MyManagedCluster --name ManagedNamespaceName
crafted: true
"""

helps["aks nodepool"] = """
type: group
short-summary: Commands to manage node pools in Kubernetes kubernetes cluster.
Expand Down
74 changes: 74 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@
CONST_NODE_OS_CHANNEL_SECURITY_PATCH,
CONST_NODEPOOL_MODE_SYSTEM, CONST_NODEPOOL_MODE_USER, CONST_NODEPOOL_MODE_GATEWAY,
CONST_OS_DISK_TYPE_EPHEMERAL, CONST_OS_DISK_TYPE_MANAGED,
CONST_NAMESPACE_ADOPTION_POLICY_NEVER,
CONST_NAMESPACE_ADOPTION_POLICY_IFIDENTICAL,
CONST_NAMESPACE_ADOPTION_POLICY_ALWAYS,
CONST_NAMESPACE_NETWORK_POLICY_RULE_DENYALL,
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL,
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE,
CONST_NAMESPACE_DELETE_POLICY_KEEP,
CONST_NAMESPACE_DELETE_POLICY_DELETE,
CONST_OS_SKU_AZURELINUX, CONST_OS_SKU_AZURELINUX3,
CONST_OS_SKU_CBLMARINER, CONST_OS_SKU_MARINER,
CONST_OS_SKU_UBUNTU, CONST_OS_SKU_UBUNTU2204,
Expand Down Expand Up @@ -89,6 +97,8 @@
validate_acr, validate_agent_pool_name, validate_assign_identity,
validate_assign_kubelet_identity, validate_azure_keyvault_kms_key_id,
validate_azure_keyvault_kms_key_vault_resource_id,
validate_namespace_name,
validate_resource_quota,
validate_azuremonitorworkspaceresourceid, validate_create_parameters,
validate_azuremonitor_privatelinkscope_resourceid,
validate_credential_format, validate_defender_config_parameter,
Expand Down Expand Up @@ -320,6 +330,24 @@
CONST_ARTIFACT_SOURCE_CACHE,
]

# consts for managed namespace
network_policy_rule = [
CONST_NAMESPACE_NETWORK_POLICY_RULE_DENYALL,
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL,
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE,
]

adoption_policy = [
CONST_NAMESPACE_ADOPTION_POLICY_NEVER,
CONST_NAMESPACE_ADOPTION_POLICY_IFIDENTICAL,
CONST_NAMESPACE_ADOPTION_POLICY_ALWAYS,
]

delete_policy = [
CONST_NAMESPACE_DELETE_POLICY_KEEP,
CONST_NAMESPACE_DELETE_POLICY_DELETE,
]

# consts for app routing add-on
app_routing_nginx_configs = [
CONST_APP_ROUTING_ANNOTATION_CONTROLLED_NGINX,
Expand Down Expand Up @@ -866,6 +894,52 @@ def load_arguments(self, _):
with self.argument_context('aks scale', resource_type=ResourceType.MGMT_CONTAINERSERVICE, operation_group='managed_clusters') as c:
c.argument('nodepool_name', validator=validate_nodepool_name, help='Node pool name, up to 12 alphanumeric characters.')

# managed namespace
with self.argument_context("aks namespace") as c:
c.argument("cluster_name", help="The cluster name.")
c.argument(
"name",
validator=validate_namespace_name,
help="The managed namespace name.",
)

for scope in [
"aks namespace add",
"aks namespace update",
]:
with self.argument_context(scope) as c:
c.argument("tags", tags_type, help="The tags to set to the managed namespace")
c.argument("labels", nargs="*", help="Labels set to the managed namespace")
c.argument(
"annotations",
nargs="*",
help="Annotations set to the managed namespace",
)
c.argument("cpu_request", validator=validate_resource_quota)
c.argument("cpu_limit", validator=validate_resource_quota)
c.argument("memory_request", validator=validate_resource_quota)
c.argument("memory_limit", validator=validate_resource_quota)
c.argument("ingress_policy", arg_type=get_enum_type(network_policy_rule))
c.argument("egress_policy", arg_type=get_enum_type(network_policy_rule))
c.argument("adoption_policy", arg_type=get_enum_type(adoption_policy))
c.argument("delete_policy", arg_type=get_enum_type(delete_policy))
c.argument("aks_custom_headers")
c.argument("no_wait", help="Do not wait for the long-running operation to finish")

with self.argument_context("aks namespace get-credentials") as c:
c.argument(
"context_name",
options_list=["--context"],
help="If specified, overwrite the default context name.",
)
c.argument(
"path",
options_list=["--file", "-f"],
type=file_type,
completer=FilesCompleter(),
default=os.path.join(os.path.expanduser("~"), ".kube", "config"),
)

with self.argument_context('aks check-acr', resource_type=ResourceType.MGMT_CONTAINERSERVICE, operation_group='managed_clusters') as c:
c.argument('acr', validator=validate_registry_name)
c.argument('node_name')
Expand Down
38 changes: 38 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,44 @@ def validate_ip_ranges(namespace):
raise CLIError("--api-server-authorized-ip-ranges should be a list of IPv4 addresses or CIDRs")


def validate_namespace_name(namespace):
_validate_namespace_name(namespace.name)


def _validate_namespace_name(name):
"""
Validates a Kubernetes namespace name.
Raises ValueError if the name is invalid.
"""
if name != "":
if len(name) < 1 or len(name) > 63:
raise ValueError("Namespace name must be between 1 and 63 characters.")
pattern = r'^[a-z0-9]([-a-z0-9]*[a-z0-9])?$'
if not re.match(pattern, name):
raise ValueError(
f"Invalid namespace '{name}'. Must consist of lower case alphanumeric characters or '-', "
"and must start and end with an alphanumeric character."
)


def validate_resource_quota(namespace):
if namespace.cpu_request is not None:
if not namespace.cpu_request.endswith("m"):
raise ValueError("--cpu-request must be specified in millicores, like 200m")
if namespace.cpu_limit is not None:
if not namespace.cpu_limit.endswith("m"):
raise ValueError("--cpu-limit must be specified in millicores, like 200m")
pattern = r"^\d+(Ki|Mi|Gi|Ti|Pi|Ei)$"
if namespace.memory_request is not None:
if not re.match(pattern, namespace.memory_request):
raise ValueError("--memory-request must be specified in the power-of-two equivalents form:"
"Ei, Pi, Ti, Gi, Mi, Ki.")
if namespace.memory_limit is not None:
if not re.match(pattern, namespace.memory_limit):
raise ValueError("--memory-limit must be specified in the power-of-two equivalents form:"
"Ei, Pi, Ti, Gi, Mi, Ki.")


def validate_k8s_version(namespace):
"""Validates a string as a possible Kubernetes version. An empty string is also valid, which tells the server
to use its default version."""
Expand Down
Loading