Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
19892da
Updated to latest preview
dustin-wojciechowski Mar 24, 2025
c9da7de
Implementations for show and update
dustin-wojciechowski Mar 24, 2025
862a714
Test created
dustin-wojciechowski Apr 18, 2025
ded2bbe
Added restore-defaults
dustin-wojciechowski Apr 18, 2025
c776401
Added test for restore-defaults
dustin-wojciechowski Apr 18, 2025
1d80cb7
Cleanup, set, reset, tests
Tratcher Apr 22, 2025
8ed4907
Style
Tratcher Apr 22, 2025
3c70d18
History
Tratcher Apr 22, 2025
b041f9f
Lint
Tratcher Apr 22, 2025
557be61
Merge remote-tracking branch 'upstream/main' into ingress-configurati…
Tratcher Apr 22, 2025
c508477
Recording updates
Tratcher Apr 23, 2025
a765883
Recording updates
Tratcher Apr 23, 2025
e0df94c
Rename commands
Tratcher May 9, 2025
9b358d2
Update recording: test_containerapp_revision_labels_mode_e2e
Tratcher May 27, 2025
716dc61
Update src/containerapp/azext_containerapp/_params.py
Tratcher May 9, 2025
569366e
Revert "Recording updates"
Tratcher May 28, 2025
9d034e4
Revert "Recording updates"
Tratcher May 28, 2025
2696bd3
Merge remote-tracking branch 'upstream/main' into ingress-configurati…
Tratcher May 28, 2025
821976e
Test fixes
Tratcher May 29, 2025
9101c5a
Test fixes
Tratcher May 29, 2025
53ca52b
Remove unused variable.
Tratcher May 29, 2025
2956016
Remove redundant recording
Tratcher May 29, 2025
849c933
Update src/containerapp/azext_containerapp/_help.py
Greedygre May 30, 2025
6b50960
Update src/containerapp/azext_containerapp/_help.py
Greedygre May 30, 2025
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
1 change: 1 addition & 0 deletions src/containerapp/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Release History
===============
upcoming
++++++
* 'az containerapp env premium-ingress': New environment level ingress configuration.
* 'az containerapp sessionpool update': Support `--mi-system-assigned`, `--mi-user-assigned` and `--registry-identity`
* Upgrade api-version to 2025-02-02-preview

Expand Down
49 changes: 49 additions & 0 deletions src/containerapp/azext_containerapp/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -2366,3 +2366,52 @@
text: |
az containerapp env http-route-config delete -g MyResourceGroup -n MyEnvironment -r configname
"""

helps['containerapp env premium-ingress show'] = """
type: command
short-summary: Show the premium ingress settings for the environment.
examples:
- name: Show the premium ingress settings for the environment.
text: |
az containerapp env premium-ingress show -g MyResourceGroup -n MyEnvironment
"""

helps['containerapp env premium-ingress'] = """
type: group
short-summary: Configure premium ingress settings for the environment.
long-summary: |
Premium ingress settings apply to all applications in the environment. They allow moving the ingress instances to a workload profile and scaling them beyond the system defaults to enable high traffic workloads. Other settings include request idle timeouts, header count limits, and the termination grace period.
examples:
- name: Enable premium ingress for the environment.
text: |
az containerapp env premium-ingress add -g MyResourceGroup -n MyEnvironment -w WorkloadProfileName --min-replicas 2 --max-replicas 10
"""

helps['containerapp env premium-ingress add'] = """
type: command
short-summary: Enable the premium ingress settings for the environment.
long-summary: |
Unspecified optional parameters will be cleared from any existing configuration.
examples:
- name: Add the premium ingress settings for the environment.
text: |
az containerapp env premium-ingress add -g MyResourceGroup -n MyEnvironment -w WorkloadProfileName --min-replicas 2 --max-replicas 10
"""

helps['containerapp env premium-ingress update'] = """
type: command
short-summary: Update the premium ingress settings for the environment.
examples:
- name: Update the workload profile used for premium ingress.
text: |
az containerapp env premium-ingress update -g MyResourceGroup -n MyEnvironment -w WorkloadProfileName
"""

helps['containerapp env premium-ingress remove'] = """
type: command
short-summary: Remove the ingress settings and restores the system to default values.
examples:
- name: Reset the ingress settings for the environment to its default values
text: |
az containerapp env premium-ingress remove -g MyResourceGroup -n MyEnvironment
"""
14 changes: 12 additions & 2 deletions src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def load_arguments(self, _):
c.ignore('service_type')

with self.argument_context('containerapp create', arg_group='GitHub Repository', is_preview=True) as c:
c.argument('repo', help='Create an app via GitHub Actions in the format: https://github.com/owner/repository-name or owner/repository-name')
c.argument('repo', help='Create an app via GitHub Actions in the format: `https://github.com/owner/repository-name` or owner/repository-name')
c.argument('token', help='A Personal Access Token with write access to the specified repository. For more information: https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line. If not provided or not found in the cache (and using --repo), a browser page will be opened to authenticate with Github.')
c.argument('branch', options_list=['--branch', '-b'], help='Branch in the provided GitHub repository. Assumed to be the GitHub repository\'s default branch if not specified.')
c.argument('context_path', help='Path in the repository to run docker build. Defaults to "./". Dockerfile is assumed to be named "Dockerfile" and in this directory.')
Expand Down Expand Up @@ -264,7 +264,7 @@ def load_arguments(self, _):
c.argument('target_label', help="The label to apply to new revisions. Required for revisions-mode 'labels'.", is_preview=True)

with self.argument_context('containerapp up', arg_group='Github Repo') as c:
c.argument('repo', help='Create an app via Github Actions. In the format: https://github.com/owner/repository-name or owner/repository-name')
c.argument('repo', help='Create an app via Github Actions. In the format: `https://github.com/owner/repository-name` or owner/repository-name')
c.argument('token', help='A Personal Access Token with write access to the specified repository. For more information: https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line. If not provided or not found in the cache (and using --repo), a browser page will be opened to authenticate with Github.')
c.argument('branch', options_list=['--branch', '-b'], help='The branch of the Github repo. Assumed to be the Github repo\'s default branch if not specified.')
c.argument('context_path', help='Path in the repo from which to run the docker build. Defaults to "./". Dockerfile is assumed to be named "Dockerfile" and in this directory.')
Expand Down Expand Up @@ -510,3 +510,13 @@ def load_arguments(self, _):
with self.argument_context('containerapp revision set-mode') as c:
c.argument('mode', arg_type=get_enum_type(['single', 'multiple', 'labels']), help="The active revisions mode for the container app.")
c.argument('target_label', help="The label to apply to new revisions. Required for revision mode 'labels'.", is_preview=True)

with self.argument_context('containerapp env premium-ingress') as c:
c.argument('resource_group_name', arg_type=resource_group_name_type, id_part=None)
c.argument('name', options_list=['--name', '-n'], help="The name of the managed environment.")
c.argument('workload_profile_name', options_list=['--workload-profile-name', '-w'], help="The workload profile to run ingress replicas on. This profile must not be shared with any container app or job.")
c.argument('min_replicas', options_list=['--min-replicas'], type=int, help="Minimum number of replicas to run. Default 2, minimum 2.")
c.argument('max_replicas', options_list=['--max-replicas'], type=int, help="Maximum number of replicas to run. Default 10. The upper limit is the maximum cores available in the workload profile.")
c.argument('termination_grace_period', options_list=['--termination-grace-period', '-t'], type=int, help="Time in seconds to drain requests during ingress shutdown. Default 500, minimum 0, maximum 3600.")
c.argument('request_idle_timeout', options_list=['--request-idle-timeout'], type=int, help="Timeout in minutes for idle requests. Default 4, minimum 1.")
c.argument('header_count_limit', options_list=['--header-count-limit'], type=int, help="Limit of http headers per request. Default 100, minimum 1.")
6 changes: 6 additions & 0 deletions src/containerapp/azext_containerapp/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,9 @@ def load_command_table(self, args):
with self.command_group('containerapp revision label') as g:
g.custom_command('add', 'add_revision_label')
g.custom_command('remove', 'remove_revision_label')

with self.command_group('containerapp env premium-ingress', is_preview=True) as g:
g.custom_show_command('show', 'show_environment_premium_ingress')
g.custom_command('add', 'add_environment_premium_ingress')
g.custom_command('update', 'update_environment_premium_ingress')
g.custom_command('remove', 'remove_environment_premium_ingress', confirmation=True)
114 changes: 114 additions & 0 deletions src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -3807,3 +3807,117 @@ def remove_revision_label(cmd, resource_group_name, name, label, no_wait=False):
return r['properties']['configuration']['ingress']['traffic']
except Exception as e:
handle_raw_exception(e)


def show_environment_premium_ingress(cmd, name, resource_group_name):
_validate_subscription_registered(cmd, CONTAINER_APPS_RP)

try:
env = ManagedEnvironmentPreviewClient.show(cmd, resource_group_name, name)
ingress_config = safe_get(env, "properties", "ingressConfiguration")
if not ingress_config:
return {"message": "No premium ingress configuration found for this environment, using default values."}

return ingress_config
except Exception as e:
handle_raw_exception(e)


def add_environment_premium_ingress(cmd, name, resource_group_name, workload_profile_name, min_replicas, max_replicas, termination_grace_period=None, request_idle_timeout=None, header_count_limit=None, no_wait=False):
_validate_subscription_registered(cmd, CONTAINER_APPS_RP)

try:
ManagedEnvironmentPreviewClient.show(cmd, resource_group_name, name)
env_patch = {}
ingress_config = {}
safe_set(env_patch, "properties", "ingressConfiguration", value=ingress_config)
scale = {}
ingress_config["scale"] = scale

# Required
ingress_config["workloadProfileName"] = workload_profile_name
scale["minReplicas"] = min_replicas
scale["maxReplicas"] = max_replicas
# Optional, remove if None
ingress_config["terminationGracePeriodSeconds"] = termination_grace_period
ingress_config["requestIdleTimeout"] = request_idle_timeout
ingress_config["headerCountLimit"] = header_count_limit

result = ManagedEnvironmentPreviewClient.update(
cmd=cmd,
resource_group_name=resource_group_name,
name=name,
managed_environment_envelope=env_patch,
no_wait=no_wait
)

return safe_get(result, "properties", "ingressConfiguration")

except Exception as e:
handle_raw_exception(e)


def update_environment_premium_ingress(cmd, name, resource_group_name, workload_profile_name=None, min_replicas=None, max_replicas=None, termination_grace_period=None, request_idle_timeout=None, header_count_limit=None, no_wait=False):
_validate_subscription_registered(cmd, CONTAINER_APPS_RP)

try:
ManagedEnvironmentPreviewClient.show(cmd, resource_group_name, name)
env_patch = {}
ingress_config = {}
scale = {}

if workload_profile_name is not None:
ingress_config["workloadProfileName"] = workload_profile_name
if min_replicas is not None:
ingress_config["scale"] = scale
scale["minReplicas"] = min_replicas
if max_replicas is not None:
ingress_config["scale"] = scale
scale["maxReplicas"] = max_replicas
if termination_grace_period is not None:
ingress_config["terminationGracePeriodSeconds"] = termination_grace_period
if request_idle_timeout is not None:
ingress_config["requestIdleTimeout"] = request_idle_timeout
if header_count_limit is not None:
ingress_config["headerCountLimit"] = header_count_limit

# Only add ingressConfiguration to the patch if any values were specified
if ingress_config:
safe_set(env_patch, "properties", "ingressConfiguration", value=ingress_config)
else:
return {"message": "No changes specified for premium ingress configuration"}

# Update the environment with the patched ingress configuration
result = ManagedEnvironmentPreviewClient.update(
cmd=cmd,
resource_group_name=resource_group_name,
name=name,
managed_environment_envelope=env_patch,
no_wait=no_wait
)

return safe_get(result, "properties", "ingressConfiguration")

except Exception as e:
handle_raw_exception(e)


def remove_environment_premium_ingress(cmd, name, resource_group_name, no_wait=False):
_validate_subscription_registered(cmd, CONTAINER_APPS_RP)

try:
ManagedEnvironmentPreviewClient.show(cmd, resource_group_name, name)
env_patch = {}
# Remove the whole section to restore defaults
safe_set(env_patch, "properties", "ingressConfiguration", value=None)

ManagedEnvironmentPreviewClient.update(
cmd=cmd,
resource_group_name=resource_group_name,
name=name,
managed_environment_envelope=env_patch,
no_wait=no_wait
)

except Exception as e:
handle_raw_exception(e)
Loading
Loading