Skip to content

Commit

Permalink
Env var options + various bug fixes (Azure#26)
Browse files Browse the repository at this point in the history
* Moved dapr arguments to env as a subgroup.

* Added env variable options.

* Changed revision mode set to revision set-mode.

* Added env var options to revision copy.

* Fixed revision copy bug related to env secret refs.

* Changed registry and secret delete to remove. Added registry param helps. Removed replica from table output and added trafficWeight.

* Updating warning text.

* Updated warning text once more.

* Made name optional for revision copy if from-revision flag is passed.

Co-authored-by: Haroon Feisal <haroonfeisal@microsoft.com>
  • Loading branch information
2 people authored and calvinsID committed Mar 24, 2022
1 parent a26df8c commit ea45ec8
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 104 deletions.
102 changes: 49 additions & 53 deletions src/containerapp/azext_containerapp/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,13 @@
az containerapp revision deactivate -n MyContainerapp -g MyResourceGroup --revision-name MyContainerappRevision
"""

helps['containerapp revision mode set'] = """
helps['containerapp revision set-mode'] = """
type: command
short-summary: Set the revision mode of a container app.
examples:
- name: Set a container app to single revision mode.
text: |
az containerapp revision mode set-n MyContainerapp -g MyResourceGroup --mode Single
az containerapp revision set-mode -n MyContainerapp -g MyResourceGroup --mode Single
"""

helps['containerapp revision copy'] = """
Expand All @@ -164,15 +164,6 @@
--from-revision PreviousRevisionName --cpu 0.75 --memory 1.5Gi
"""

helps['containerapp revision mode set'] = """
type: command
short-summary: Set the revision mode of a Containerapp.
examples:
- name: Set the revision mode of a Containerapp.
text: |
az containerapp revision set --mode Single -n MyContainerapp -g MyResourceGroup
"""

helps['containerapp revision copy'] = """
type: command
short-summary: Create a revision based on a previous revision.
Expand Down Expand Up @@ -238,6 +229,47 @@
az containerapp env list -g MyResourceGroup
"""

helps['containerapp env dapr-component'] = """
type: group
short-summary: Commands to manage Container App environment dapr components.
"""

helps['containerapp env dapr-component list'] = """
type: command
short-summary: List dapr components for a Containerapp environment.
examples:
- name: List dapr components for a Containerapp environment.
text: |
az containerapp env dapr-component list -g MyResourceGroup --environment-name MyEnvironment
"""

helps['containerapp env dapr-component show'] = """
type: command
short-summary: Show the details of a dapr component.
examples:
- name: Show the details of a dapr component.
text: |
az containerapp env dapr-component show -g MyResourceGroup --dapr-component-name MyDaprComponenetName --environment-name MyEnvironment
"""

helps['containerapp env dapr-component set'] = """
type: command
short-summary: Create or update a dapr component.
examples:
- name: Create a dapr component.
text: |
az containerapp env dapr-component set -g MyResourceGroup --environment-name MyEnv --yaml MyYAMLPath --name MyDaprName
"""

helps['containerapp env dapr-component remove'] = """
type: command
short-summary: Remove a dapr componenet from a Containerapp environment.
examples:
- name: Remove a dapr componenet from a Containerapp environment.
text: |
az containerapp env dapr-component remove -g MyResourceGroup --dapr-component-name MyDaprComponenetName --environment-name MyEnvironment
"""

# Identity Commands
helps['containerapp identity'] = """
type: group
Expand Down Expand Up @@ -374,13 +406,13 @@
"""

helps['containerapp registry delete'] = """
helps['containerapp registry remove'] = """
type: command
short-summary: Remove a container registry's details.
examples:
- name: Remove a registry from a Containerapp.
text: |
az containerapp registry delete -n MyContainerapp -g MyResourceGroup --server MyContainerappRegistry.azurecr.io
az containerapp registry remove -n MyContainerapp -g MyResourceGroup --server MyContainerappRegistry.azurecr.io
"""

# Secret Commands
Expand All @@ -407,13 +439,13 @@
az containerapp secret list -n MyContainerapp -g MyResourceGroup
"""

helps['containerapp secret delete'] = """
helps['containerapp secret remove'] = """
type: command
short-summary: Delete secrets from a container app.
short-summary: Remove secrets from a container app.
examples:
- name: Delete secrets from a container app.
- name: Remove secrets from a container app.
text: |
az containerapp secret delete -n MyContainerapp -g MyResourceGroup --secret-names MySecret MySecret2
az containerapp secret remove -n MyContainerapp -g MyResourceGroup --secret-names MySecret MySecret2
"""

helps['containerapp secret set'] = """
Expand Down Expand Up @@ -504,39 +536,3 @@
text: |
az containerapp dapr disable -n MyContainerapp -g MyResourceGroup
"""

helps['containerapp dapr list'] = """
type: command
short-summary: List Dapr components.
examples:
- name: List Dapr components for a Container Apps environment.
text: |
az containerapp dapr list -g MyResourceGroup --environment-name MyEnvironment
"""

helps['containerapp dapr show'] = """
type: command
short-summary: Show the details of a Dapr component.
examples:
- name: Show the details of a Dapr component.
text: |
az containerapp dapr show -g MyResourceGroup --dapr-component-name MyDaprComponenetName --environment-name MyEnvironment
"""

helps['containerapp dapr set'] = """
type: command
short-summary: Create or update a Dapr component.
examples:
- name: Create a Dapr component.
text: |
az containerapp dapr set -g MyResourceGroup --environment-name MyEnv --yaml my-component.yaml --name MyDaprName
"""

helps['containerapp dapr remove'] = """
type: command
short-summary: Remove a Dapr component.
examples:
- name: Remove a Dapr component.
text: |
az containerapp dapr delete -g MyResourceGroup --dapr-component-name MyDaprComponenetName --environment-name MyEnvironment
"""
30 changes: 23 additions & 7 deletions src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ def load_arguments(self, _):
c.argument('args', nargs='*', options_list=['--args'], help="A list of container startup command argument(s). Space-separated values e.g. \"-c\" \"mycommand\". Empty string to clear existing values")
c.argument('revision_suffix', type=str, options_list=['--revision-suffix'], help='User friendly suffix that is appended to the revision name')

# Env vars
with self.argument_context('containerapp', arg_group='Environment variables (Creates new revision)') as c:
c.argument('set_env_vars', options_list=['--set-env-vars, --env-vars'], nargs='*', help="A list of environment variable(s) to add to the container. Space-separated values in 'key=value' format. If stored as a secret, value must start with \'secretref:\' followed by the secret name.")
c.argument('remove_env_vars', nargs='*', help="A list of environment variable(s) to remove from container. Space-separated env var name values.")
c.argument('replace_env_vars', nargs='*', help="A list of environment variable(s) to replace from the container. Space-separated values in 'key=value' format. If stored as a secret, value must start with \'secretref:\' followed by the secret name.")
c.argument('remove_all_env_vars', help="Option to remove all environment variable(s) from the container.")

# Scale
with self.argument_context('containerapp', arg_group='Scale (Creates new revision)') as c:
c.argument('min_replicas', type=int, options_list=['--min-replicas'], help="The minimum number of replicas.")
Expand Down Expand Up @@ -147,12 +154,21 @@ def load_arguments(self, _):
with self.argument_context('containerapp secret set') as c:
c.argument('secrets', nargs='+', options_list=['--secrets', '-s'], help="A list of secret(s) for the container app. Space-separated values in 'key=value' format.")

with self.argument_context('containerapp secret delete') as c:
with self.argument_context('containerapp secret remove') as c:
c.argument('secret_names', nargs='+', help="A list of secret(s) for the container app. Space-separated secret values names.")

with self.argument_context('containerapp dapr') as c:
c.argument('dapr_app_id', help="The Dapr app id.")
c.argument('dapr_app_port', help="The port Dapr uses to talk to the application.")
c.argument('dapr_app_protocol', help="The protocol Dapr uses to talk to the application. Allowed values: grpc, http.")
c.argument('dapr_component_name', help="The Dapr component name.")
c.argument('environment_name', help="The Container Apps environment name.")
with self.argument_context('containerapp env dapr-component') as c:
c.argument('dapr_app_id', help="The dapr app id.")
c.argument('dapr_app_port', help="The port of your app.")
c.argument('dapr_app_protocol', help="Tells Dapr which protocol your application is using. Allowed values: grpc, http.")
c.argument('dapr_component_name', help="The dapr component name.")
c.argument('environment_name', options_list=['--name','-n'], help="The environment name.")

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

with self.argument_context('containerapp registry') as c:
c.argument('server', help="The container registry server, e.g. myregistry.azurecr.io")
c.argument('username', help='The username of the registry. If using Azure Container Registry, we will try to infer the credentials if not supplied')
c.argument('password', help='The password of the registry. If using Azure Container Registry, we will try to infer the credentials if not supplied')

27 changes: 26 additions & 1 deletion src/containerapp/azext_containerapp/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ def parse_secret_flags(secret_list):

return secret_var_def

def _update_revision_env_secretrefs(containers, name):
for container in containers:
if "env" in container:
for var in container["env"]:
if "secretRef" in var:
var["secretRef"] = var["secretRef"].replace("{}-".format(name), "")

def store_as_secret_and_return_secret_ref(secrets_list, registry_user, registry_server, registry_pass, update_existing_secret=False):
if registry_pass.startswith("secretref:"):
Expand Down Expand Up @@ -328,14 +334,16 @@ def _remove_secret(containerapp_def, secret_name):
containerapp_def["properties"]["configuration"]["secrets"].pop(i)
break

def _add_or_update_env_vars(existing_env_vars, new_env_vars):
def _add_or_update_env_vars(existing_env_vars, new_env_vars, is_add=False):
for new_env_var in new_env_vars:

# Check if updating existing env var
is_existing = False
for existing_env_var in existing_env_vars:
if existing_env_var["name"].lower() == new_env_var["name"].lower():
is_existing = True
if is_add:
logger.warning("Environment variable {} already exists. Replacing environment variable value.".format(new_env_var["name"]))

if "value" in new_env_var:
existing_env_var["value"] = new_env_var["value"]
Expand All @@ -350,8 +358,25 @@ def _add_or_update_env_vars(existing_env_vars, new_env_vars):

# If not updating existing env var, add it as a new env var
if not is_existing:
if not is_add:
logger.warning("Environment variable {} does not exist. Adding as new environment variable.".format(new_env_var["name"]))
existing_env_vars.append(new_env_var)

def _remove_env_vars(existing_env_vars, remove_env_vars):
for old_env_var in remove_env_vars:

# Check if updating existing env var
is_existing = False
for i in range(0, len(existing_env_vars)):
existing_env_var = existing_env_vars[i]
if existing_env_var["name"].lower() == old_env_var.lower():
is_existing = True
existing_env_vars.pop(i)
break

# If not updating existing env var, add it as a new env var
if not is_existing:
logger.warning("Environment variable {} does not exist.".format(old_env_var))

def _add_or_update_tags(containerapp_def, tags):
if 'tags' not in containerapp_def:
Expand Down
21 changes: 9 additions & 12 deletions src/containerapp/azext_containerapp/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def transform_containerapp_list_output(apps):


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

if 'name' in rev:
Expand All @@ -50,21 +50,24 @@ def load_command_table(self, _):
g.custom_command('update', 'update_containerapp', supports_no_wait=True, exception_handler=ex_handler_factory())
g.custom_command('delete', 'delete_containerapp', exception_handler=ex_handler_factory())


with self.command_group('containerapp env') as g:
g.custom_command('show', 'show_managed_environment')
g.custom_command('list', 'list_managed_environments')
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 env dapr-component') as g:
g.custom_command('list', 'list_dapr_components')
g.custom_command('show', 'show_dapr_component')
g.custom_command('set', 'create_or_update_dapr_component')
g.custom_command('remove', 'remove_dapr_component')

with self.command_group('containerapp identity') as g:
g.custom_command('assign', 'assign_managed_identity', supports_no_wait=True, exception_handler=ex_handler_factory())
g.custom_command('remove', 'remove_managed_identity', supports_no_wait=True, exception_handler=ex_handler_factory())
g.custom_command('show', 'show_managed_identity')


with self.command_group('containerapp github-action') as g:
g.custom_command('add', 'create_or_update_github_action', exception_handler=ex_handler_factory())
g.custom_command('show', 'show_github_action', exception_handler=ex_handler_factory())
Expand All @@ -77,9 +80,7 @@ def load_command_table(self, _):
g.custom_command('restart', 'restart_revision')
g.custom_command('show', 'show_revision', table_transformer=transform_revision_output, exception_handler=ex_handler_factory())
g.custom_command('copy', 'copy_revision', exception_handler=ex_handler_factory())

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

with self.command_group('containerapp ingress') as g:
g.custom_command('enable', 'enable_ingress', exception_handler=ex_handler_factory())
Expand All @@ -94,19 +95,15 @@ def load_command_table(self, _):
g.custom_command('set', 'set_registry', exception_handler=ex_handler_factory())
g.custom_command('show', 'show_registry')
g.custom_command('list', 'list_registry')
g.custom_command('delete', 'delete_registry', exception_handler=ex_handler_factory())
g.custom_command('remove', 'remove_registry', exception_handler=ex_handler_factory())

with self.command_group('containerapp secret') as g:
g.custom_command('list', 'list_secrets')
g.custom_command('show', 'show_secret')
g.custom_command('delete', 'delete_secrets', exception_handler=ex_handler_factory())
g.custom_command('remove', 'remove_secrets', exception_handler=ex_handler_factory())
g.custom_command('set', 'set_secrets', exception_handler=ex_handler_factory())

with self.command_group('containerapp dapr') as g:
g.custom_command('enable', 'enable_dapr', exception_handler=ex_handler_factory())
g.custom_command('disable', 'disable_dapr', exception_handler=ex_handler_factory())
g.custom_command('list', 'list_dapr_components')
g.custom_command('show', 'show_dapr_component')
g.custom_command('set', 'create_or_update_dapr_component')
g.custom_command('remove', 'remove_dapr_component')

Loading

0 comments on commit ea45ec8

Please sign in to comment.