Skip to content

Commit

Permalink
feat(acns): add acns to GA cli
Browse files Browse the repository at this point in the history
address pr comments, remove redundant commands, add more tests, raise mutual exclusion errors for acns cases

update test ctx

convert one test to non cilium for enable acns

update help msg

update style

update managed_cluster_decorator for acns and tests
  • Loading branch information
snguyen64 committed Nov 8, 2024
1 parent 6a1c3ca commit a5592e4
Show file tree
Hide file tree
Showing 6 changed files with 439 additions and 0 deletions.
21 changes: 21 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 @@ -541,6 +541,15 @@
- name: --enable-vtpm
type: bool
short-summary: Enable vTPM on all node pools in the cluster. Must use VMSS agent pool type.
- name: --enable-acns
type: bool
short-summary: Enable advanced network functionalities on a cluster. Enabling this will incur additional costs.
- name: --disable-acns-observability
type: bool
short-summary: Used to disable advanced networking observability features on a clusters when enabling advanced networking features with "--enable-acns".
- name: --disable-acns-security
type: bool
short-summary: Used to disable advanced networking security features on a clusters when enabling advanced networking features with "--enable-acns".
examples:
- name: Create a Kubernetes cluster with an existing SSH public key.
Expand Down Expand Up @@ -943,6 +952,18 @@
- name: --disable-cost-analysis
type: bool
short-summary: Disable exporting Kubernetes Namespace and Deployment details to the Cost Analysis views in the Azure portal.
- name: --enable-acns
type: bool
short-summary: Enable advanced network functionalities on a cluster. Enabling this will incur additional costs.
- name: --disable-acns
type: bool
short-summary: Disable all advanced networking functionalities on a cluster.
- name: --disable-acns-observability
type: bool
short-summary: Used to disable advanced networking observability features on a clusters when enabling advanced networking features with "--enable-acns".
- name: --disable-acns-security
type: bool
short-summary: Used to disable advanced networking security features on a clusters when enabling advanced networking features with "--enable-acns".
examples:
- name: Reconcile the cluster back to its current state.
Expand Down
9 changes: 9 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 @@ -464,6 +464,10 @@ def load_arguments(self, _):
c.argument('enable_cost_analysis', action='store_true')
c.argument('enable_vtpm', action="store_true")
c.argument('enable_secure_boot', action="store_true")
# advanced networking
c.argument('enable_acns', action='store_true')
c.argument('disable_acns_observability', action='store_true')
c.argument('disable_acns_security', action='store_true')

with self.argument_context('aks update') as c:
# managed cluster paramerters
Expand All @@ -487,6 +491,11 @@ def load_arguments(self, _):
help="Comma-separated list of key=value pairs for configuring cluster autoscaler. Pass an empty string to clear the profile.")
c.argument('tier', arg_type=get_enum_type(sku_tiers), validator=validate_sku_tier)
c.argument('api_server_authorized_ip_ranges', validator=validate_ip_ranges)
# advanced networking
c.argument('enable_acns', action='store_true')
c.argument('disable_acns', action='store_true')
c.argument('disable_acns_observability', action='store_true')
c.argument('disable_acns_security', action='store_true')
# private cluster parameters
c.argument('enable_public_fqdn', action='store_true')
c.argument('disable_public_fqdn', action='store_true')
Expand Down
9 changes: 9 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acs/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,10 @@ def aks_create(
image_cleaner_interval_hours=None,
enable_keda=False,
enable_vpa=False,
# advanced networking
enable_acns=None,
disable_acns_observability=None,
disable_acns_security=None,
# addons
enable_addons=None,
workspace_resource_id=None,
Expand Down Expand Up @@ -754,6 +758,11 @@ def aks_update(
enable_force_upgrade=False,
disable_force_upgrade=False,
upgrade_override_until=None,
# advanced networking
disable_acns=None,
enable_acns=None,
disable_acns_observability=None,
disable_acns_security=None,
# addons
enable_secret_rotation=False,
disable_secret_rotation=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2360,6 +2360,54 @@ def get_network_dataplane(self) -> Union[str, None]:
"""
return self.raw_param.get("network_dataplane")

def get_acns_enablement(self) -> Tuple[
Union[bool, None],
Union[bool, None],
Union[bool, None],
]:
"""Get the enablement of acns
:return: Tuple of 3 elements which can be bool or None
"""
enable_acns = self.raw_param.get("enable_acns")
disable_acns = self.raw_param.get("disable_acns")
if enable_acns is None and disable_acns is None:
return None, None, None
if enable_acns and disable_acns:
raise MutuallyExclusiveArgumentError(
"Cannot specify --enable-acns and "
"--disable-acns at the same time."
)
enable_acns = bool(enable_acns) if enable_acns is not None else False
disable_acns = bool(disable_acns) if disable_acns is not None else False
acns = enable_acns or not disable_acns
acns_observability = self.get_acns_observability()
acns_security = self.get_acns_security()
if acns and (acns_observability is False and acns_security is False):
raise MutuallyExclusiveArgumentError(
"Cannot disable both observability and security when enabling ACNS. "
"Please enable at least one of them or disable ACNS with --disable-acns."
)
if not acns and (acns_observability is not None or acns_security is not None):
raise MutuallyExclusiveArgumentError(
"--disable-acns does not use any additional acns arguments."
)
return acns, acns_observability, acns_security

def get_acns_observability(self) -> Union[bool, None]:
"""Get the enablement of acns observability
:return: bool or None"""
disable_acns_observability = self.raw_param.get("disable_acns_observability")
return not bool(disable_acns_observability) if disable_acns_observability is not None else None

def get_acns_security(self) -> Union[bool, None]:
"""Get the enablement of acns security
:return: bool or None"""
disable_acns_security = self.raw_param.get("disable_acns_security")
return not bool(disable_acns_security) if disable_acns_security is not None else None

def _get_pod_cidr_and_service_cidr_and_dns_service_ip_and_docker_bridge_address_and_network_policy(
self, enable_validation: bool = False
) -> Tuple[
Expand Down Expand Up @@ -5651,6 +5699,19 @@ def set_up_network_profile(self, mc: ManagedCluster) -> ManagedCluster:

network_dataplane = self.context.get_network_dataplane()

acns = self.models.AdvancedNetworking()
(acns_enabled, acns_observability, acns_security) = self.context.get_acns_enablement()
if acns_enabled is not None:
acns.enabled = acns_enabled
if acns_observability is not None:
acns.observability = self.models.AdvancedNetworkingObservability(
enabled=acns_observability,
)
if acns_security is not None:
acns.security = self.models.AdvancedNetworkingSecurity(
enabled=acns_security,
)

if any(
[
network_plugin,
Expand Down Expand Up @@ -5710,6 +5771,8 @@ def set_up_network_profile(self, mc: ManagedCluster) -> ManagedCluster:
load_balancer_sku = self.context.get_load_balancer_sku()
if load_balancer_sku != CONST_LOAD_BALANCER_SKU_BASIC:
network_profile.nat_gateway_profile = nat_gateway_profile
if acns_enabled is not None:
network_profile.advanced_networking=acns
mc.network_profile = network_profile
return mc

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11549,3 +11549,216 @@ def test_aks_create_update_vtpm_flow(self, resource_group, resource_group_locati
"aks delete -g {resource_group} -n {name} --yes --no-wait",
checks=[self.is_empty()],
)

# ACNS related tests
@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(
random_name_length=17,
name_prefix="clitest",
location="westcentralus",
)
def test_aks_update_enable_acns(
self, resource_group, resource_group_location
):
aks_name = self.create_random_name("cliakstest", 16)
self.kwargs.update(
{
"resource_group": resource_group,
"name": aks_name,
"ssh_key_value": self.generate_ssh_keys(),
"location": resource_group_location,
}
)

create_cmd = (
"aks create --resource-group={resource_group} --name={name} --location={location} "
"--ssh-key-value={ssh_key_value} --node-count=1 --tier standard "
"--network-plugin azure --network-dataplane=cilium --network-plugin-mode overlay "
)
self.cmd(create_cmd, checks=[self.check("provisioningState", "Succeeded")])

# update to enable acns
update_cmd = (
"aks update --resource-group={resource_group} --name={name} "
"--enable-acns "
)
self.cmd(
update_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", True),
self.check("networkProfile.advancedNetworking.security.enabled", True),
self.check("networkProfile.advancedNetworking.observability.enabled", True),
],
)

# update to disable acns
update_cmd_two = (
"aks update --resource-group={resource_group} --name={name} --disable-acns "
)
self.cmd(
update_cmd_two,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", False),
self.check("networkProfile.advancedNetworking.security.enabled", False),
self.check("networkProfile.advancedNetworking.observability.enabled", False),
],
)

# 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="westcentralus",
)
def test_aks_create_with_enable_acns(
self, resource_group, resource_group_location
):
# reset the count so in replay mode the random names will start with 0
self.test_resources_count = 0
# kwargs for string formatting

aks_name = self.create_random_name("cliakstest", 16)
self.kwargs.update(
{
"resource_group": resource_group,
"name": aks_name,
"ssh_key_value": self.generate_ssh_keys(),
"location": resource_group_location,
}
)

# create
create_cmd = (
"aks create --resource-group={resource_group} --name={name} --location={location} "
"--ssh-key-value={ssh_key_value} --node-count=1 --tier standard "
"--network-plugin azure --network-plugin-mode overlay --enable-acns "
)
self.cmd(
create_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", True),
self.check("networkProfile.advancedNetworking.security.enabled", False),
self.check("networkProfile.advancedNetworking.observability.enabled", 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="eastus2euap",
)
def test_aks_create_with_enable_acns_complex(
self, resource_group, resource_group_location
):
# reset the count so in replay mode the random names will start with 0
self.test_resources_count = 0
# kwargs for string formatting

aks_name = self.create_random_name("cliakstest", 16)
self.kwargs.update(
{
"resource_group": resource_group,
"name": aks_name,
"ssh_key_value": self.generate_ssh_keys(),
"location": resource_group_location,
}
)

# create: enable acns
create_cmd = (
"aks create --resource-group={resource_group} --name={name} --location={location} "
"--ssh-key-value={ssh_key_value} --node-count=1 --tier standard "
"--network-plugin azure --network-dataplane=cilium --network-plugin-mode overlay "
"--enable-acns --disable-acns-security "
)
self.cmd(
create_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", True),
self.check("networkProfile.advancedNetworking.security.enabled", False),
self.check("networkProfile.advancedNetworking.observability.enabled", True),
],
)

# update: enable security and observability
update_cmd = (
"aks update --resource-group={resource_group} --name={name} "
"--enable-acns "
)
self.cmd(
update_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", True),
self.check("networkProfile.advancedNetworking.security.enabled", True),
self.check("networkProfile.advancedNetworking.observability.enabled", True),
],
)

# update: disable security
update_cmd2 = (
"aks update --resource-group={resource_group} --name={name} "
"--enable-acns --disable-acns-security "
)
self.cmd(
update_cmd2,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", True),
self.check("networkProfile.advancedNetworking.security.enabled", False),
self.check("networkProfile.advancedNetworking.observability.enabled", True),
],
)

# update: enable FQDN policy, disable observability
update_cmd3 = (
"aks update --resource-group={resource_group} --name={name} "
"--enable-acns --disable-acns-observability "
)
self.cmd(
update_cmd3,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", True),
self.check("networkProfile.advancedNetworking.security.enabled", True),
self.check("networkProfile.advancedNetworking.observability.enabled", False),
],
)

# update: disable acns
update_cmd5 = (
"aks update --resource-group={resource_group} --name={name} "
"--disable-acns "
)
self.cmd(
update_cmd5,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("networkProfile.advancedNetworking.enabled", False),
self.check("networkProfile.advancedNetworking.security.enabled", False),
self.check("networkProfile.advancedNetworking.observability.enabled", False),
],
)

# delete
self.cmd(
"aks delete -g {resource_group} -n {name} --yes --no-wait",
checks=[self.is_empty()],
)
Loading

0 comments on commit a5592e4

Please sign in to comment.