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
99 changes: 99 additions & 0 deletions src/containerapp/azext_containerapp/_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,105 @@ def list_secrets(cls, cmd, resource_group_name, name):
r = send_raw_request(cmd.cli_ctx, "POST", request_url, body=None)
return r.json()

@classmethod
def list_revisions(cls, cmd, resource_group_name, name, formatter=lambda x: x):

revisions_list = []

management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = NEW_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerApps/{}/revisions?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
name,
api_version)

r = send_raw_request(cmd.cli_ctx, "GET", request_url)
j = r.json()
for app in j["value"]:
formatted = formatter(app)
revisions_list.append(formatted)

while j.get("nextLink") is not None:
request_url = j["nextLink"]
r = send_raw_request(cmd.cli_ctx, "GET", request_url)
j = r.json()
for app in j["value"]:
formatted = formatter(app)
revisions_list.append(formatted)

return revisions_list

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

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

@classmethod
def restart_revision(cls, cmd, resource_group_name, container_app_name, name):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = NEW_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerApps/{}/revisions/{}/restart?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
container_app_name,
name,
api_version)

r = send_raw_request(cmd.cli_ctx, "POST", request_url)
return r.json()

@classmethod
def activate_revision(cls, cmd, resource_group_name, container_app_name, name):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = NEW_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerApps/{}/revisions/{}/activate?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
container_app_name,
name,
api_version)

r = send_raw_request(cmd.cli_ctx, "POST", request_url)
return r.json()

@classmethod
def deactivate_revision(cls, cmd, resource_group_name, container_app_name, name):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = NEW_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerApps/{}/revisions/{}/deactivate?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
container_app_name,
name,
api_version)

r = send_raw_request(cmd.cli_ctx, "POST", request_url)
return r.json()

class ManagedEnvironmentClient():
@classmethod
Expand Down
51 changes: 51 additions & 0 deletions src/containerapp/azext_containerapp/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,57 @@
az containerapp list -g MyResourceGroup
"""

# Revision Commands
helps['containerapp revision'] = """
type: group
short-summary: Commands to manage a Containerapp's revisions.
"""

helps['containerapp revision show'] = """
type: command
short-summary: Show details of a Containerapp's revision.
examples:
- name: Show details of a Containerapp's revision.
text: |
az containerapp revision show --revision-name MyContainerappRevision -g MyResourceGroup
"""

helps['containerapp revision list'] = """
type: command
short-summary: List details of a Containerapp's revisions.
examples:
- name: List a Containerapp's revisions.
text: |
az containerapp revision list --revision-name MyContainerapp -g MyResourceGroup
"""

helps['containerapp revision restart'] = """
type: command
short-summary: Restart a Containerapps's revision.
examples:
- name: Restart a Containerapp's revision.
text: |
az containerapp revision restart --revision-name MyContainerappRevision -g MyResourceGroup
"""

helps['containerapp revision activate'] = """
type: command
short-summary: Activates Containerapp's revision.
examples:
- name: Activate a Containerapp's revision.
text: |
az containerapp revision activate --revision-name MyContainerappRevision -g MyResourceGroup
"""

helps['containerapp revision deactivate'] = """
type: command
short-summary: Deactivates Containerapp's revision.
examples:
- name: Deactivate a Containerapp's revision.
text: |
az containerapp revision deactivate --revision-name MyContainerappRevision -g MyResourceGroup
"""

# Environment Commands
helps['containerapp env'] = """
type: group
Expand Down
3 changes: 3 additions & 0 deletions src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ def load_arguments(self, _):

with self.argument_context('containerapp env show') as c:
c.argument('name', name_type, help='Name of the managed Environment.')

with self.argument_context('containerapp revision') as c:
c.argument('revision_name', type=str, help='Name of the revision')
10 changes: 10 additions & 0 deletions src/containerapp/azext_containerapp/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,13 @@ def _add_or_update_traffic_Weights(containerapp_def, list_weights):
"revisionName": key_val[0],
"weight": int(key_val[1])
})


def _get_app_from_revision(revision):
if not revision:
raise ValidationError('Invalid revision. Revision must not be empty')

revision = revision.split('--')
revision.pop()
revision = "--".join(revision)
return revision
21 changes: 21 additions & 0 deletions src/containerapp/azext_containerapp/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ def transform_containerapp_list_output(apps):
return [transform_containerapp_output(a) for a in apps]


def transform_revision_output(rev):
props = ['name', 'replicas', 'active', 'createdTime']
result = {k: rev[k] for k in rev if k in props}

if 'latestRevisionFqdn' in rev['template']:
result['fqdn'] = rev['template']['latestRevisionFqdn']

return result


def transform_revision_list_output(revs):
return [transform_revision_output(r) for r in revs]


def load_command_table(self, _):
with self.command_group('containerapp') as g:
g.custom_command('show', 'show_containerapp', table_transformer=transform_containerapp_output)
Expand All @@ -41,3 +55,10 @@ def load_command_table(self, _):
g.custom_command('create', 'create_managed_environment', supports_no_wait=True, exception_handler=ex_handler_factory())
# g.custom_command('update', 'update_managed_environment', supports_no_wait=True, exception_handler=ex_handler_factory())
g.custom_command('delete', 'delete_managed_environment', supports_no_wait=True, confirmation=True, exception_handler=ex_handler_factory())

with self.command_group('containerapp revision') as g:
g.custom_command('activate', 'activate_revision')
g.custom_command('deactivate', 'deactivate_revision')
g.custom_command('list', 'list_revisions', table_transformer=transform_revision_list_output, exception_handler=ex_handler_factory())
g.custom_command('restart', 'restart_revision')
g.custom_command('show', 'show_revision', table_transformer=transform_revision_output, exception_handler=ex_handler_factory())
50 changes: 49 additions & 1 deletion src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
parse_secret_flags, store_as_secret_and_return_secret_ref, parse_list_of_strings, parse_env_var_flags,
_generate_log_analytics_if_not_provided, _get_existing_secrets, _convert_object_from_snake_to_camel_case,
_object_to_dict, _add_or_update_secrets, _remove_additional_attributes, _remove_readonly_attributes,
_add_or_update_env_vars, _add_or_update_tags, update_nested_dictionary, _add_or_update_traffic_Weights)
_add_or_update_env_vars, _add_or_update_tags, update_nested_dictionary, _add_or_update_traffic_Weights,
_get_app_from_revision)

logger = get_logger(__name__)

Expand Down Expand Up @@ -891,3 +892,50 @@ def delete_managed_environment(cmd, name, resource_group_name, no_wait=False):
return ManagedEnvironmentClient.delete(cmd=cmd, name=name, resource_group_name=resource_group_name, no_wait=no_wait)
except CLIError as e:
handle_raw_exception(e)


def list_revisions(cmd, name, resource_group_name):
try:
return ContainerAppClient.list_revisions(cmd=cmd, resource_group_name=resource_group_name, name=name)
except CLIError as e:
handle_raw_exception(e)


def show_revision(cmd, resource_group_name, revision_name, name=None):
if not name:
name = _get_app_from_revision(revision_name)

try:
return ContainerAppClient.show_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name)
except CLIError as e:
handle_raw_exception(e)


def restart_revision(cmd, resource_group_name, revision_name, name=None):
if not name:
name = _get_app_from_revision(revision_name)

try:
return ContainerAppClient.restart_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name)
except CLIError as e:
handle_raw_exception(e)


def activate_revision(cmd, resource_group_name, revision_name, name=None):
if not name:
name = _get_app_from_revision(revision_name)

try:
return ContainerAppClient.activate_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name)
except CLIError as e:
handle_raw_exception(e)

def deactivate_revision(cmd, resource_group_name, revision_name, name=None):
if not name:
name = _get_app_from_revision(revision_name)

try:
return ContainerAppClient.deactivate_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name)
except CLIError as e:
handle_raw_exception(e)