Skip to content

Commit 3120497

Browse files
committed
Add istio egress CLI commands
Signed-off-by: nshankar <[email protected]>
1 parent a469a8c commit 3120497

File tree

9 files changed

+492
-0
lines changed

9 files changed

+492
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@
234234
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_START = "Start"
235235
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_COMPLETE = "Complete"
236236
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_ROLLBACK = "Rollback"
237+
CONST_AZURE_SERVICE_MESH_DEFAULT_EGRESS_NAMESPACE = "aks-istio-egress"
238+
CONST_AZURE_SERVICE_MESH_MAX_EGRESS_NAME_LENGTH = 253
237239

238240
# Dns zone contributor role
239241
CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE = "Private DNS Zone Contributor"

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,6 +2564,46 @@
25642564
text: az aks mesh disable-ingress-gateway --resource-group MyResourceGroup --name MyManagedCluster --ingress-gateway-type Internal
25652565
"""
25662566

2567+
helps['aks mesh enable-egress-gateway'] = """
2568+
type: command
2569+
short-summary: Enable an Azure Service Mesh egress gateway.
2570+
long-summary: This command enables an Azure Service Mesh egress gateway in given cluster.
2571+
parameters:
2572+
- name: --istio-eg-gtw-name --istio-egressgateway-name
2573+
type: string
2574+
short-summary: Specify the name of the Istio egress gateway.
2575+
long-summary: This required field specifies the name of the Istio egress gateway. Must be between 1 and 253 characters, must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character.
2576+
- name: --istio-eg-gtw-ns --istio-egressgateway-namespace
2577+
type: string
2578+
short-summary: Specify the namespace of the Istio egress gateway.
2579+
long-summary: This optional field specifies the namespace of the Istio egress gateway. Defaults to "aks-istio-egress" if unspecified.
2580+
- name: --gateway-configuration-name --gtw-config-name
2581+
type: string
2582+
short-summary: Specify the name of the StaticGatewayConfiguration resource.
2583+
long-summary: This required field specifies the name of the StaticGatewayConfiguration resource for the Istio egress gateway. See https://aka.ms/aks-static-egress-gateway on how to create and configure a Static Egress Gateway agentpool.
2584+
examples:
2585+
- name: Enable an Istio egress gateway. Static egress gateway must be enabled prior to creating an Istio egress gateway. See https://aka.ms/aks-static-egress-gateway on how to create and configure a Static Egress Gateway agentpool.
2586+
text: az aks mesh enable-egress-gateway --resource-group MyResourceGroup --name MyManagedCluster --istio-egressgateway-name my-istio-egress-1 --istio-egressgateway-namespace my-namespace-1 --gateway-configuration-name sgc-istio-egress-1
2587+
"""
2588+
2589+
helps['aks mesh disable-egress-gateway'] = """
2590+
type: command
2591+
short-summary: Disable an Azure Service Mesh ingress gateway.
2592+
long-summary: This command disables an Azure Service Mesh egress gateway in given cluster.
2593+
parameters:
2594+
- name: --istio-eg-gtw-name --istio-egressgateway-name
2595+
type: string
2596+
short-summary: Specify the name of the Istio egress gateway.
2597+
long-summary: This required field specifies the name of the Istio egress gateway. Must be between 1 and 253 characters, must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character.
2598+
- name: --istio-eg-gtw-ns --istio-egressgateway-namespace
2599+
type: string
2600+
short-summary: Specify the namespace of the Istio egress gateway.
2601+
long-summary: This optional field specifies the namespace of the Istio egress gateway. Defaults to "aks-istio-egress" if unspecified.
2602+
examples:
2603+
- name: Disable an Istio egress gateway.
2604+
text: az aks mesh disable-egress-gateway --resource-group MyResourceGroup --name MyManagedCluster --istio-egressgateway-name my-istio-egress-1 --istio-egressgateway-namespace my-namespace-1
2605+
"""
2606+
25672607
helps["aks mesh get-revisions"] = """
25682608
type: command
25692609
short-summary: Discover available Azure Service Mesh revisions and their compatibility.

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
CONST_LOAD_BALANCER_BACKEND_POOL_TYPE_NODE_IP_CONFIGURATION,
5555
CONST_AZURE_SERVICE_MESH_INGRESS_MODE_EXTERNAL,
5656
CONST_AZURE_SERVICE_MESH_INGRESS_MODE_INTERNAL,
57+
CONST_AZURE_SERVICE_MESH_DEFAULT_EGRESS_NAMESPACE,
5758
CONST_NRG_LOCKDOWN_RESTRICTION_LEVEL_READONLY,
5859
CONST_NRG_LOCKDOWN_RESTRICTION_LEVEL_UNRESTRICTED,
5960
CONST_ARTIFACT_SOURCE_DIRECT,
@@ -115,6 +116,7 @@
115116
validate_allowed_host_ports, validate_application_security_groups,
116117
validate_node_public_ip_tags,
117118
validate_disable_windows_outbound_nat,
119+
validate_asm_egress_name,
118120
validate_crg_id, validate_apiserver_subnet_id,
119121
validate_azure_service_mesh_revision,
120122
validate_message_of_the_day,
@@ -1087,6 +1089,39 @@ def load_arguments(self, _):
10871089
c.argument('ingress_gateway_type',
10881090
arg_type=get_enum_type(ingress_gateway_types))
10891091

1092+
with self.argument_context("aks mesh enable-egress-gateway") as c:
1093+
c.argument(
1094+
"istio_egressgateway_name",
1095+
validator=validate_asm_egress_name,
1096+
required=True,
1097+
options_list=["--istio-egressgateway-name", "--istio-eg-gtw-name"]
1098+
)
1099+
c.argument(
1100+
"istio_egressgateway_namespace",
1101+
required=False,
1102+
default=CONST_AZURE_SERVICE_MESH_DEFAULT_EGRESS_NAMESPACE,
1103+
options_list=["--istio-egressgateway-namespace", "--istio-eg-gtw-ns"]
1104+
)
1105+
c.argument(
1106+
"gateway_configuration_name",
1107+
required=True,
1108+
options_list=["--gateway-configuration-name", "--gtw-config-name"]
1109+
)
1110+
1111+
with self.argument_context("aks mesh disable-egress-gateway") as c:
1112+
c.argument(
1113+
"istio_egressgateway_name",
1114+
validator=validate_asm_egress_name,
1115+
required=True,
1116+
options_list=["--istio-egressgateway-name", "--istio-eg-gtw-name"]
1117+
)
1118+
c.argument(
1119+
"istio_egressgateway_namespace",
1120+
required=False,
1121+
default=CONST_AZURE_SERVICE_MESH_DEFAULT_EGRESS_NAMESPACE,
1122+
options_list=["--istio-egressgateway-namespace", "--istio-eg-gtw-ns"]
1123+
)
1124+
10901125
with self.argument_context('aks mesh enable') as c:
10911126
c.argument('revision', validator=validate_azure_service_mesh_revision)
10921127
c.argument('key_vault_id')

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
CONST_NETWORK_POD_IP_ALLOCATION_MODE_DYNAMIC_INDIVIDUAL,
2020
CONST_NETWORK_POD_IP_ALLOCATION_MODE_STATIC_BLOCK,
2121
CONST_NODEPOOL_MODE_GATEWAY,
22+
CONST_AZURE_SERVICE_MESH_MAX_EGRESS_NAME_LENGTH,
2223
CONST_VIRTUAL_MACHINE_SCALE_SETS,
2324
CONST_AVAILABILITY_SET,
2425
CONST_VIRTUAL_MACHINES,
@@ -136,6 +137,18 @@ def validate_agent_pool_name(namespace):
136137
"""Validates a nodepool name to be at most 12 characters, alphanumeric only."""
137138
_validate_nodepool_name(namespace.agent_pool_name)
138139

140+
def validate_asm_egress_name(namespace):
141+
if namespace.istio_egressgateway_name is None:
142+
return
143+
name = namespace.istio_egressgateway_name
144+
asm_egress_name_regex = re.compile(r'^[a-z0-9]([-a-z0-9]*[a-z0-9])?(.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$')
145+
match = asm_egress_name_regex.match(name)
146+
if not match or len(name) > CONST_AZURE_SERVICE_MESH_MAX_EGRESS_NAME_LENGTH:
147+
raise InvalidArgumentValueError(
148+
f"Istio egress name {name} is invalid. Name must be between 1 and "
149+
f"{CONST_AZURE_SERVICE_MESH_MAX_EGRESS_NAME_LENGTH} characters, must consist of lower case alphanumeric "
150+
"characters, '-' or '.', and must start and end with an alphanumeric character."
151+
)
139152

140153
def validate_kubectl_version(namespace):
141154
"""Validates a string as a possible Kubernetes version."""

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,20 @@ def load_command_table(self, _):
254254
'enable-ingress-gateway',
255255
'aks_mesh_enable_ingress_gateway',
256256
supports_no_wait=True)
257+
g.custom_command(
258+
"enable-egress-gateway",
259+
"aks_mesh_enable_egress_gateway",
260+
supports_no_wait=True)
257261
g.custom_command(
258262
'disable-ingress-gateway',
259263
'aks_mesh_disable_ingress_gateway',
260264
supports_no_wait=True,
261265
confirmation=True)
266+
g.custom_command(
267+
"disable-egress-gateway",
268+
"aks_mesh_disable_egress_gateway",
269+
supports_no_wait=True,
270+
confirmation=True)
262271
g.custom_command(
263272
'get-revisions',
264273
'aks_mesh_get_revisions',

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,6 +3411,41 @@ def aks_mesh_disable_ingress_gateway(
34113411
disable_ingress_gateway=True,
34123412
ingress_gateway_type=ingress_gateway_type)
34133413

3414+
def aks_mesh_enable_egress_gateway(
3415+
cmd,
3416+
client,
3417+
resource_group_name,
3418+
name,
3419+
istio_egressgateway_name,
3420+
istio_egressgateway_namespace,
3421+
gateway_configuration_name,
3422+
):
3423+
return _aks_mesh_update(
3424+
cmd,
3425+
client,
3426+
resource_group_name,
3427+
name,
3428+
enable_egress_gateway=True,
3429+
istio_egressgateway_name=istio_egressgateway_name,
3430+
istio_egressgateway_namespace=istio_egressgateway_namespace,
3431+
gateway_configuration_name=gateway_configuration_name)
3432+
3433+
def aks_mesh_disable_egress_gateway(
3434+
cmd,
3435+
client,
3436+
resource_group_name,
3437+
name,
3438+
istio_egressgateway_name,
3439+
istio_egressgateway_namespace,
3440+
):
3441+
return _aks_mesh_update(
3442+
cmd,
3443+
client,
3444+
resource_group_name,
3445+
name,
3446+
istio_egressgateway_name=istio_egressgateway_name,
3447+
istio_egressgateway_namespace=istio_egressgateway_namespace,
3448+
disable_egress_gateway=True)
34143449

34153450
def aks_mesh_get_revisions(
34163451
cmd,
@@ -3534,6 +3569,11 @@ def _aks_mesh_update(
35343569
enable_ingress_gateway=None,
35353570
disable_ingress_gateway=None,
35363571
ingress_gateway_type=None,
3572+
enable_egress_gateway=None,
3573+
disable_egress_gateway=None,
3574+
istio_egressgateway_name=None,
3575+
istio_egressgateway_namespace=None,
3576+
gateway_configuration_name=None,
35373577
revision=None,
35383578
yes=False,
35393579
mesh_upgrade_command=None,

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

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4712,6 +4712,90 @@ def _handle_ingress_gateways_asm(self, new_profile: ServiceMeshProfile) -> Tuple
47124712

47134713
return new_profile, updated
47144714

4715+
def _handle_egress_gateways_asm(self, new_profile: ServiceMeshProfile) -> Tuple[ServiceMeshProfile, bool]:
4716+
updated = False
4717+
enable_egress_gateway = self.raw_param.get("enable_egress_gateway", False)
4718+
disable_egress_gateway = self.raw_param.get("disable_egress_gateway", False)
4719+
istio_egressgateway_name = self.raw_param.get("istio_egressgateway_name", None)
4720+
istio_egressgateway_namespace = self.raw_param.get(
4721+
"istio_egressgateway_namespace",
4722+
CONST_AZURE_SERVICE_MESH_DEFAULT_EGRESS_NAMESPACE
4723+
)
4724+
gateway_configuration_name = self.raw_param.get("gateway_configuration_name", None)
4725+
4726+
# disallow disable egress gateway on a cluser with no asm enabled
4727+
if disable_egress_gateway:
4728+
if new_profile is None or new_profile.mode == CONST_AZURE_SERVICE_MESH_MODE_DISABLED:
4729+
raise ArgumentUsageError(
4730+
"Istio has not been enabled for this cluster, please refer to https://aka.ms/asm-aks-addon-docs "
4731+
"for more details on enabling Azure Service Mesh."
4732+
)
4733+
# deal with egress gateways
4734+
if enable_egress_gateway and disable_egress_gateway:
4735+
raise MutuallyExclusiveArgumentError(
4736+
"Cannot both enable and disable azure service mesh egress gateway at the same time.",
4737+
)
4738+
if enable_egress_gateway or disable_egress_gateway:
4739+
# if a gateway is enabled, enable the mesh
4740+
if enable_egress_gateway:
4741+
4742+
new_profile.mode = CONST_AZURE_SERVICE_MESH_MODE_ISTIO
4743+
if new_profile.istio is None:
4744+
new_profile.istio = self.models.IstioServiceMesh() # pylint: disable=no-member
4745+
updated = True
4746+
4747+
# Gateway configuration name is required for Istio egress gateway enablement
4748+
if not gateway_configuration_name:
4749+
raise RequiredArgumentMissingError("--gateway-configuration-name is required.")
4750+
4751+
if not istio_egressgateway_name:
4752+
raise RequiredArgumentMissingError("--istio-egressgateway-name is required.")
4753+
4754+
# ensure necessary fields
4755+
if new_profile.istio.components is None:
4756+
new_profile.istio.components = self.models.IstioComponents() # pylint: disable=no-member
4757+
updated = True
4758+
if new_profile.istio.components.egress_gateways is None:
4759+
new_profile.istio.components.egress_gateways = []
4760+
updated = True
4761+
# make update if the egress gateway already exists
4762+
egress_gateway_exists = False
4763+
for egress in new_profile.istio.components.egress_gateways:
4764+
if egress.name == istio_egressgateway_name and egress.namespace == istio_egressgateway_namespace:
4765+
if not egress.enabled and disable_egress_gateway:
4766+
raise ArgumentUsageError(
4767+
f'Egress gateway {istio_egressgateway_name} '
4768+
f'in namespace {istio_egressgateway_namespace} is already disabled.'
4769+
)
4770+
egress.enabled = enable_egress_gateway
4771+
# only update gateway configuration name for enabled egress gateways
4772+
if enable_egress_gateway:
4773+
egress.gateway_configuration_name = gateway_configuration_name
4774+
egress_gateway_exists = True
4775+
updated = True
4776+
break
4777+
4778+
# egress gateway doesn't exist, append
4779+
if not egress_gateway_exists:
4780+
if enable_egress_gateway:
4781+
new_profile.istio.components.egress_gateways.append(
4782+
self.models.IstioEgressGateway( # pylint: disable=no-member
4783+
enabled=enable_egress_gateway,
4784+
name=istio_egressgateway_name,
4785+
namespace=istio_egressgateway_namespace,
4786+
gateway_configuration_name=gateway_configuration_name,
4787+
)
4788+
)
4789+
elif disable_egress_gateway:
4790+
raise ArgumentUsageError(
4791+
f'Egress gateway {istio_egressgateway_name} '
4792+
f'in namespace {istio_egressgateway_namespace} does not exist, cannot disable.'
4793+
)
4794+
4795+
updated = True
4796+
4797+
return new_profile, updated
4798+
47154799
def _handle_enable_disable_asm(self, new_profile: ServiceMeshProfile) -> Tuple[ServiceMeshProfile, bool]:
47164800
updated = False
47174801
# enable/disable

0 commit comments

Comments
 (0)