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
4 changes: 3 additions & 1 deletion src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,14 @@ def load_arguments(self, _):
c.argument('instrumentation_key', options_list=['--dapr-instrumentation-key'], help='Application Insights instrumentation key used by Dapr to export Service to Service communication telemetry')

with self.argument_context('containerapp env', arg_group='Virtual Network') as c:
c.argument('infrastructure_subnet_resource_id', options_list=['--infrastructure-subnet-resource-id'], help='Resource ID of a subnet for infrastructure components and user app containers.')
c.argument('infrastructure_subnet_resource_id', options_list=['--infrastructure-subnet-resource-id', '-s'], help='Resource ID of a subnet for infrastructure components and user app containers.')
c.argument('app_subnet_resource_id', options_list=['--app-subnet-resource-id'], help='Resource ID of a subnet that Container App containers are injected into. This subnet must be in the same VNET as the subnet defined in infrastructureSubnetResourceId.')
c.argument('docker_bridge_cidr', options_list=['--docker-bridge-cidr'], help='CIDR notation IP range assigned to the Docker bridge. It must not overlap with any Subnet IP ranges or the IP range defined in Platform Reserved CIDR, if defined')
c.argument('platform_reserved_cidr', options_list=['--platform-reserved-cidr'], help='IP range in CIDR notation that can be reserved for environment infrastructure IP addresses. It must not overlap with any other Subnet IP ranges')
c.argument('platform_reserved_dns_ip', options_list=['--platform-reserved-dns-ip'], help='An IP address from the IP range defined by Platform Reserved CIDR that will be reserved for the internal DNS server.')
c.argument('internal_only', arg_type=get_three_state_flag(), options_list=['--internal-only'], help='Boolean indicating the environment only has an internal load balancer. These environments do not have a public static IP resource, therefore must provide infrastructureSubnetResourceId if enabling this property')
with self.argument_context('containerapp env create') as c:
c.argument('zone_redundant', options_list=["--zone-redundant", "-z"], help="Enable zone redundancy on the environment. Cannot be used without --infrastructure-subnet-resource-id. If used with --location, the subnet's location must match")

with self.argument_context('containerapp env update') as c:
c.argument('name', name_type, help='Name of the Container Apps environment.')
Expand Down
11 changes: 11 additions & 0 deletions src/containerapp/azext_containerapp/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
from azure.cli.core.azclierror import (ValidationError, RequiredArgumentMissingError, CLIInternalError,
ResourceNotFoundError, ArgumentUsageError)
from azure.cli.core.commands.client_factory import get_subscription_id
from azure.cli.command_modules.appservice.utils import _normalize_location
from azure.cli.command_modules.network._client_factory import network_client_factory

from knack.log import get_logger
from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id

Expand All @@ -31,6 +34,14 @@ def validate_container_app_name(name):
f"Please shorten {name}")


def get_vnet_location(cmd, subnet_resource_id):
parsed_rid = parse_resource_id(subnet_resource_id)
vnet_client = network_client_factory(cmd.cli_ctx)
location = vnet_client.virtual_networks.get(resource_group_name=parsed_rid.get("resource_group"),
virtual_network_name=parsed_rid.get("name")).location
return _normalize_location(cmd, location)


# original implementation at azure.cli.command_modules.role.custom.create_service_principal_for_rbac
# reimplemented to remove incorrect warning statements
def create_service_principal_for_rbac( # pylint:disable=too-many-statements,too-many-locals, too-many-branches, unused-argument, inconsistent-return-statements
Expand Down
18 changes: 17 additions & 1 deletion src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
InvalidArgumentValueError)
from azure.cli.core.commands.client_factory import get_subscription_id
from azure.cli.core.util import open_page_in_browser
from azure.cli.command_modules.appservice.utils import _normalize_location
from knack.log import get_logger

from msrestazure.tools import parse_resource_id, is_valid_resource_id
Expand Down Expand Up @@ -55,7 +56,7 @@
_get_app_from_revision, raise_missing_token_suggestion, _infer_acr_credentials, _remove_registry_secret, _remove_secret,
_ensure_identity_resource_id, _remove_dapr_readonly_attributes, _remove_env_vars, _validate_traffic_sum,
_update_revision_env_secretrefs, _get_acr_cred, safe_get, await_github_action, repo_url_to_name,
validate_container_app_name, _update_weights)
validate_container_app_name, _update_weights, get_vnet_location)

from ._ssh_utils import (SSH_DEFAULT_ENCODING, WebSocketConnection, read_ssh, get_stdin_writer, SSH_CTRL_C_MSG,
SSH_BACKUP_ENCODING)
Expand Down Expand Up @@ -754,7 +755,21 @@ def create_managed_environment(cmd,
internal_only=False,
tags=None,
disable_warnings=False,
zone_redundant=False,
no_wait=False):
if zone_redundant:
if not infrastructure_subnet_resource_id:
raise RequiredArgumentMissingError("Cannot use --zone-redundant/-z without "
"--infrastructure-subnet-resource-id/-s")
if not is_valid_resource_id(infrastructure_subnet_resource_id):
raise ValidationError("--infrastructure-subnet-resource-id must be a valid resource id")
vnet_location = get_vnet_location(cmd, infrastructure_subnet_resource_id)
if location:
if _normalize_location(cmd, location) != vnet_location:
raise ValidationError(f"Location '{location}' does not match the subnet's location: '{vnet_location}'. "
"Please change either --location/-l or --infrastructure-subnet-resource-id/-s")
else:
location = vnet_location

location = location or _get_location_from_resource_group(cmd.cli_ctx, resource_group_name)

Expand All @@ -777,6 +792,7 @@ def create_managed_environment(cmd,
managed_env_def["properties"]["internalLoadBalancerEnabled"] = False
managed_env_def["properties"]["appLogsConfiguration"] = app_logs_config_def
managed_env_def["tags"] = tags
managed_env_def["properties"]["zoneRedundant"] = zone_redundant

if instrumentation_key is not None:
managed_env_def["properties"]["daprAIInstrumentationKey"] = instrumentation_key
Expand Down