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
6 changes: 6 additions & 0 deletions linter_exclusions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ containerapp github-action add:
service_principal_tenant_id:
rule_exclusions:
- option_length_too_long
containerapp label-history show:
rule_exclusions:
- missing_command_test_coverage
containerapp label-history list:
rule_exclusions:
- missing_command_test_coverage
Comment on lines +404 to +409
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add some tests for these commands?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commands won't work properly until our next control plane deployment goes out, there was a change in the object structure. I can add tests after that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks~

costmanagement export create:
parameters:
definition_dataset_configuration:
Expand Down
4 changes: 4 additions & 0 deletions src/containerapp/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ upcoming
++++++
* 'az containerapp create/update': Fix an issue about `--bind`/`--unbind` when the cloud is not AzureCloud.
* 'az containerapp debug': Open an SSH-like interactive shell within a container app debug console.
* 'az containerapp create': New target-label option for Labels revision mode.
* 'az containerapp up/update': New revisions-mode and target-label options for Labels revision mode.
* 'az containerapp label-history': New list and show commands to see label revision assignment history.
* 'az containerapp revision set-mode': New target-label option for Labels revision mode.
* 'az containerapp connected-env certificate upload/remove': Support `--no-wait`.
* 'az containerapp connected-env dapr-component set/remove': Support `--no-wait`.
* 'az containerapp connected-env storage set/remove': Support `--no-wait`.
Expand Down
39 changes: 39 additions & 0 deletions src/containerapp/azext_containerapp/_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,45 @@ class ContainerAppPreviewClient(ContainerAppClient):
api_version = PREVIEW_API_VERSION


class LabelHistoryPreviewClient:
api_version = PREVIEW_API_VERSION

@classmethod
def list(cls, cmd, resource_group_name, name):
history_list = []
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerapps/{}/labelhistory?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
cls.api_version)

r = send_raw_request(cmd.cli_ctx, "GET", request_url, body=None)
j = r.json()
for route in j["value"]:
history_list.append(route)
return history_list

@classmethod
def show(cls, cmd, resource_group_name, name, label):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerapps/{}/labelhistory/{}?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
label,
cls.api_version)

r = send_raw_request(cmd.cli_ctx, "GET", request_url, body=None)
return r.json()


class ContainerAppsJobPreviewClient(ContainerAppsJobClient):
api_version = PREVIEW_API_VERSION
LOG_STREAM_API_VERSION = "2023-11-02-preview"
Expand Down
27 changes: 27 additions & 0 deletions src/containerapp/azext_containerapp/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -2199,6 +2199,33 @@
az containerapp debug -n MyContainerapp -g MyResourceGroup --revision MyRevision --replica MyReplica --container MyContainer
"""

helps['containerapp label-history'] = """
type: group
short-summary: Show the history for one or more labels on the Container App.
examples:
- name: Show Label History
text: |
az containerapp label-history show -n my-containerapp -g MyResourceGroup --label LabelName
"""

helps['containerapp label-history list'] = """
type: command
short-summary: List the history for all labels on the Container App.
examples:
- name: List All Label History
text: |
az containerapp label-history list -n my-containerapp -g MyResourceGroup
"""

helps['containerapp label-history show'] = """
type: command
short-summary: Show the history for a specific label on the Container App.
examples:
- name: Show Label History
text: |
az containerapp label-history show -n my-containerapp -g MyResourceGroup --label LabelName
"""

helps['containerapp env http-route-config'] = """
type: group
short-summary: Commands to manage environment level http routing.
Expand Down
18 changes: 18 additions & 0 deletions src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ def load_arguments(self, _):

name_type = CLIArgumentType(options_list=['--name', '-n'])

with self.argument_context('containerapp', arg_group='Configuration') as c:
c.argument('revisions_mode', arg_type=get_enum_type(['single', 'multiple', 'labels']), help="The active revisions mode for the container app.")

with self.argument_context('containerapp create') as c:
c.argument('source', help="Local directory path containing the application source and Dockerfile for building the container image. Preview: If no Dockerfile is present, a container image is generated using buildpacks. If Docker is not running or buildpacks cannot be used, Oryx will be used to generate the image. See the supported Oryx runtimes here: https://aka.ms/SourceToCloudSupportedVersions.", is_preview=True)
c.argument('artifact', help="Local path to the application artifact for building the container image. See the supported artifacts here: https://aka.ms/SourceToCloudSupportedArtifacts.", is_preview=True)
c.argument('build_env_vars', nargs='*', help="A list of environment variable(s) for the build. Space-separated values in 'key=value' format.",
validator=validate_build_env_vars, is_preview=True)
c.argument('max_inactive_revisions', type=int, help="Max inactive revisions a Container App can have.", is_preview=True)
c.argument('registry_identity', help="The managed identity with which to authenticate to the Azure Container Registry (instead of username/password). Use 'system' for a system-defined identity, Use 'system-environment' for an environment level system-defined identity or a resource id for a user-defined environment/containerapp level identity. The managed identity should have been assigned acrpull permissions on the ACR before deployment (use 'az role assignment create --role acrpull ...').")
c.argument('target_label', help="The label to apply to new revisions. Required for revisions-mode 'labels'.", is_preview=True)

# Springboard
with self.argument_context('containerapp create', arg_group='Service Binding', is_preview=True) as c:
Expand Down Expand Up @@ -63,6 +67,7 @@ def load_arguments(self, _):
c.argument('build_env_vars', nargs='*', help="A list of environment variable(s) for the build. Space-separated values in 'key=value' format.",
validator=validate_build_env_vars, is_preview=True)
c.argument('max_inactive_revisions', type=int, help="Max inactive revisions a Container App can have.", is_preview=True)
c.argument('target_label', help="The label to apply to new revisions. Required for revisions-mode 'labels'.", is_preview=True)

# Springboard
with self.argument_context('containerapp update', arg_group='Service Binding', is_preview=True) as c:
Expand Down Expand Up @@ -253,6 +258,8 @@ def load_arguments(self, _):
validator=validate_build_env_vars, is_preview=True)
c.argument('custom_location_id', options_list=['--custom-location'], help="Resource ID of custom location. List using 'az customlocation list'.", is_preview=True)
c.argument('connected_cluster_id', help="Resource ID of connected cluster. List using 'az connectedk8s list'.", configured_default='connected_cluster_id', is_preview=True)
c.argument('revisions_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 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')
Expand Down Expand Up @@ -470,3 +477,14 @@ def load_arguments(self, _):
help="The name of the container app revision. Default to the latest revision.")
c.argument('name', name_type, id_part=None, help="The name of the Containerapp.")
c.argument('resource_group_name', arg_type=resource_group_name_type, id_part=None)

with self.argument_context('containerapp label-history') as c:
c.argument('resource_group_name', arg_type=resource_group_name_type, id_part=None)
c.argument('name', name_type, id_part=None, help="The name of the Containerapp.")

with self.argument_context('containerapp label-history show') as c:
c.argument('label', help="The label name to show history for.")

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)
8 changes: 7 additions & 1 deletion src/containerapp/azext_containerapp/_up_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ def __init__(
registry_identity=None,
user_assigned=None,
system_assigned=None,
revisions_mode=None,
target_label=None,
):

super().__init__(cmd, name, resource_group, exists)
Expand All @@ -429,6 +431,8 @@ def __init__(
self.ingress = ingress
self.workload_profile_name = workload_profile_name
self.force_single_container_updates = force_single_container_updates
self.revisions_mode = revisions_mode
self.target_label = target_label

self.should_create_acr = False
self.acr: "AzureContainerRegistry" = None
Expand Down Expand Up @@ -465,7 +469,9 @@ def create(self, no_registry=False): # pylint: disable=arguments-differ
force_single_container_updates=self.force_single_container_updates,
registry_identity=self.registry_identity,
system_assigned=self.system_assigned,
user_assigned=self.user_assigned
user_assigned=self.user_assigned,
revisions_mode=self.revisions_mode,
target_label=self.target_label,
)

def set_force_single_container_updates(self, force_single_container_updates):
Expand Down
4 changes: 3 additions & 1 deletion src/containerapp/azext_containerapp/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@


# called directly from custom method bc otherwise it disrupts the --environment auto RID functionality
def validate_create(registry_identity, registry_pass, registry_user, registry_server, no_wait, source=None, artifact=None, repo=None, yaml=None, environment_type=None):
def validate_create(registry_identity, registry_pass, registry_user, registry_server, no_wait, revisions_mode=None, target_label=None, source=None, artifact=None, repo=None, yaml=None, environment_type=None):
if source and repo:
raise MutuallyExclusiveArgumentError("Usage error: --source and --repo cannot be used together. Can either deploy from a local directory or a GitHub repository")
if (source or repo) and yaml:
Expand All @@ -54,6 +54,8 @@ def validate_create(registry_identity, registry_pass, registry_user, registry_se
raise InvalidArgumentValueError("--registry-identity must be an identity resource ID or 'system' or 'system-environment'")
if registry_identity and ACR_IMAGE_SUFFIX not in (registry_server or ""):
raise InvalidArgumentValueError("--registry-identity: expected an ACR registry (*.azurecr.io) for --registry-server")
if target_label and (not revisions_mode or revisions_mode.lower() != 'labels'):
raise InvalidArgumentValueError("--target-label must only be specified with --revisions-mode labels.")


def validate_runtime(runtime, enable_java_metrics, enable_java_agent):
Expand Down
11 changes: 11 additions & 0 deletions src/containerapp/azext_containerapp/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,14 @@ def load_command_table(self, args):
g.custom_command('update', 'update_maintenance_config')
g.custom_command('remove', 'remove_maintenance_config', confirmation=True)
g.custom_show_command('list', 'list_maintenance_config')

with self.command_group('containerapp label-history', is_preview=True) as g:
g.custom_show_command('show', 'show_label_history')
g.custom_command('list', 'list_label_history')

with self.command_group('containerapp revision') as g:
g.custom_command('set-mode', 'set_revision_mode', exception_handler=ex_handler_factory())

with self.command_group('containerapp revision label') as g:
g.custom_command('add', 'add_revision_label')
g.custom_command('remove', 'remove_revision_label')
Loading