Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
0bfdddd
Skeleton code
calvinsID Feb 3, 2022
16afa69
az containerapp env show
calvinsID Feb 3, 2022
2323591
List kube/managed environments
calvinsID Feb 3, 2022
9397d54
Create kube environment, wait doesn't work yet
calvinsID Feb 4, 2022
4fa3771
Update containerapp stubs (check if it is supported now)
calvinsID Feb 4, 2022
0d7ce56
Containerapp env delete, polling not working yet
calvinsID Feb 4, 2022
055907f
Added polling for create and delete
calvinsID Feb 4, 2022
31b2415
Use Microsoft.App RP for show, list, delete command
calvinsID Feb 5, 2022
232512f
Create containerapp env using Microsoft.App RP
calvinsID Feb 6, 2022
baf19b4
Add optional containerapp env create arguments
calvinsID Feb 8, 2022
76f62ba
Remove old kube environment code, naming fixes
calvinsID Feb 8, 2022
12524a7
Containerapp create almost done
calvinsID Feb 11, 2022
99a3d38
Done containerapp create, except for --yaml. Need to test
calvinsID Feb 11, 2022
1c74c2e
Containerapp show, list
calvinsID Feb 11, 2022
3c0c501
Fix helptext
calvinsID Feb 11, 2022
958facf
Containerapp delete
calvinsID Feb 11, 2022
2a230f0
Containerapp update. Needs secrets api to be implemented, and testing
calvinsID Feb 14, 2022
c65b264
Add scale command
calvinsID Feb 14, 2022
2901b61
Various validations, small fixes
calvinsID Feb 15, 2022
02cf535
listSecrets API for updates, autogen log analytics for env
calvinsID Feb 18, 2022
fbd6407
Use space delimiter for secrets and env variables
calvinsID Feb 24, 2022
6513981
Verify sub is registered to Microsoft.ContainerRegistration if creati…
calvinsID Feb 25, 2022
bacf864
Containerapp create --yaml
calvinsID Feb 23, 2022
9777c5f
Fix updating registry to do create or update
calvinsID Feb 23, 2022
71e9c9b
Fix containerapp update command. Add image-name parameter to support …
calvinsID Feb 23, 2022
5e3888a
started update with --yaml. Need to do create or update for when an a…
calvinsID Feb 23, 2022
b419f8d
use space delimiter for startup_command and args, instead of comma de…
calvinsID Feb 24, 2022
84c56b5
Traffic weights
calvinsID Mar 1, 2022
07cae9d
List and show revisions
calvinsID Feb 24, 2022
7df8730
az containerapp revision restart, activate, deactivate
calvinsID Feb 24, 2022
43897cc
Add ability for users to clear args/command in az containerapp update
calvinsID Mar 3, 2022
7a380e3
Various fixes, traffic weights fixes
calvinsID Mar 3, 2022
983af7c
Verify subnet subscription is registered to Microsoft.ContainerServices
calvinsID Mar 4, 2022
328683b
GitHub Actions Update (#17)
runefa Mar 8, 2022
0f582e0
Remove --location since location must be same as managed env
calvinsID Mar 8, 2022
d4272d8
Add options for flag names: --env-vars and --registry-srever
calvinsID Mar 8, 2022
42519dc
Empty string to clear env_vars
calvinsID Mar 8, 2022
8caebc7
Default revisions_mode to single
calvinsID Mar 8, 2022
11e7fe0
Infer acr credentials if it is acr and credentials are not provided
calvinsID Mar 8, 2022
85fd0f5
fix help msg
calvinsID Mar 8, 2022
6bf5a56
if image is hosted on acr, and no registry server is supplied, infer …
calvinsID Mar 9, 2022
25e1250
Added subgroups (Ingress, Registry, Secret) and updated revisions (#18)
runefa Mar 11, 2022
22e428c
More p0 fixes (#20)
calvinsID Mar 11, 2022
e12b19c
Update help text (#21)
anthonychu Mar 14, 2022
abece41
New 1.0.1 version
calvinsID Mar 14, 2022
7d8b9ba
Added identity commands + --assign-identity flag to containerapp crea…
runefa Mar 14, 2022
bc8c58b
Dapr Commands (#23)
runefa Mar 14, 2022
869c11b
Rename --image-name to --container-name
calvinsID Mar 14, 2022
0857b6b
Remove allowInsecure since it was messing with the api parsing
calvinsID Mar 14, 2022
a0acb01
Fix for env var being empty string
calvinsID Mar 14, 2022
0f4f385
Rename to --dapr-instrumentation-key, only infer ACR credentials if -…
calvinsID Mar 14, 2022
144ce57
Remove az containerapp scale
calvinsID Mar 14, 2022
3b01ec6
Fix delete containerapp errors
calvinsID Mar 14, 2022
b671af3
Remove ingress, dapr flags from az containerapp update/revision copy
calvinsID Mar 14, 2022
df1ae0b
Fix revision list -o table
calvinsID Mar 14, 2022
9962e29
Help text fix
calvinsID Mar 14, 2022
ef031f4
Bump extension to 0.1.2
calvinsID Mar 14, 2022
a26df8c
Update managed identities and Dapr help text (#25)
anthonychu Mar 15, 2022
ea45ec8
Env var options + various bug fixes (#26)
runefa Mar 16, 2022
43acd4b
Fixed style issues, various bug fixes (#27)
runefa Mar 18, 2022
a607ed9
Update src/containerapp/azext_containerapp/tests/latest/test_containe…
runefa Mar 18, 2022
9652f3e
Specific Error Types + Bugfixes (Help, remove app-subnet-resource-id,…
runefa Mar 21, 2022
46b5a94
Reset to 0.1.0 version, remove unneeded options-list
calvinsID Mar 21, 2022
a8e75ba
Update min cli core version
calvinsID Mar 21, 2022
c1288b7
Fixed style issues. (#30)
runefa Mar 21, 2022
d4fbdae
Fix linter issues
calvinsID Mar 21, 2022
48f2eb9
Use custom-show-command
calvinsID Mar 21, 2022
f19323f
Removed --ids from revision, secret, registry list.
Mar 21, 2022
0f402d8
Add linter exclusions
calvinsID Mar 21, 2022
8f006f1
Fix polling on delete containerapp
calvinsID Mar 21, 2022
f259b6f
Fix error handling
calvinsID Mar 21, 2022
c96f1e5
Add Container App Service
calvinsID Mar 21, 2022
3b823cf
Fix flake linter
calvinsID Mar 21, 2022
0e5552d
Fix help text
calvinsID Mar 22, 2022
51c540b
Mark extension as preview
calvinsID Mar 22, 2022
ff2ba40
Add python 3.9 and 3.10 as supported
calvinsID Mar 22, 2022
c45cbd0
Remove registries and secrets from az containerapp update, in favor o…
calvinsID Mar 22, 2022
126878c
Fix YAML not working
calvinsID Mar 22, 2022
e64cbef
Move import to inside deserialize function
calvinsID Mar 22, 2022
40d112c
Dapr moved from Template to Configuration
calvinsID Mar 22, 2022
bade2b1
Use aka.ms link for containerapps yaml
calvinsID Mar 22, 2022
0922c68
Updated dapr enable/disable to current spec.
Mar 22, 2022
2badc74
Fixed oversight.
Mar 22, 2022
2bf3686
Remove revisions-mode from containerapp update
calvinsID Mar 23, 2022
eec4e1a
Fixed dapr enable property names. (#47)
runefa Mar 23, 2022
c43d1ca
Fix exceptions with using --yaml in containerapp create/update
calvinsID Mar 23, 2022
a0e7ca1
Rename history msg
calvinsID Mar 24, 2022
5f68333
Include fqdn in containerapp table output
calvinsID Mar 24, 2022
0b6fb6f
Added ingress messages.
Mar 23, 2022
2f07b6e
Revert history msg
calvinsID Mar 24, 2022
ad6ff27
Add basic test case
calvinsID Mar 24, 2022
a4d1ec2
Remove managed-identity support for first release of CLI
calvinsID Mar 24, 2022
b0aab4f
Need to investigate test flakiness
calvinsID Mar 24, 2022
5d0bef3
Update _help.py
panchagnula Mar 25, 2022
03ed09a
Added prototype of container up.
Mar 29, 2022
5797a89
Fixed deploy from acr registry image infer credentials issue.
Mar 29, 2022
9910366
Tried to add source.
Mar 30, 2022
c8e460e
Added acr build.
Mar 31, 2022
52abab9
Finished acr build functionality.
Mar 31, 2022
4a71bb8
Added acr create functionality and pull registry from existing contai…
Mar 31, 2022
bcb1954
Fixed bugs.
Apr 1, 2022
7dae662
Check if rg exists and create one with name if it doesn't.
Apr 1, 2022
d94a36d
Added disable verbose. Moved utils into utils.py.
Apr 5, 2022
dadc702
Disable verbose now uses sdk poller so it gives running animation.
Apr 5, 2022
a7c880a
Added helps for params. Added error handling for non acr registry pas…
Apr 6, 2022
9eea137
Updated disable_warnings ignore. Removed disable_warnings from update…
Apr 6, 2022
5b2b3c6
Renamed silent to quiet.
Apr 7, 2022
bba0599
Fixed style issues.
Apr 7, 2022
b8315bc
Added workspace name and fqdn to dry_run_str. Added indicators of if …
Apr 8, 2022
0329a53
Check RP for location when not provided. Open Dockerfile and use EXPO…
Apr 8, 2022
51a868f
Removed print statement.
Apr 11, 2022
429fbaa
Updated dockerfile expose automatic ingress feature.
Apr 11, 2022
402f6df
Removed dry run str, added dry run obj instead.
Apr 11, 2022
8e81c93
Merged main.
Apr 12, 2022
f53be71
Fixed merge conflict.
Apr 12, 2022
2f3e8b3
Create env if name passed and it doesn't exist.
Apr 13, 2022
3380c63
Added prototype for new environment workflow.
Apr 13, 2022
8fbf360
Finished environment logic.
Apr 14, 2022
c65196f
Minor updates before demo.
Apr 15, 2022
2928d53
Worked on API change.
Apr 21, 2022
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
Prev Previous commit
Next Next commit
Added helps for params. Added error handling for non acr registry pas…
…sed with source. Ignore param disable_warnings for create and no_wait for up.
  • Loading branch information
Haroon Feisal committed Apr 6, 2022
commit a7c880a4158b125145506d4a6388e7e1e85a3f64
14 changes: 13 additions & 1 deletion src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def load_arguments(self, _):

with self.argument_context('containerapp create') as c:
c.argument('traffic_weights', nargs='*', options_list=['--traffic-weight'], help="A list of revision weight(s) for the container app. Space-separated values in 'revision_name=weight' format. For latest revision, use 'latest=weight'")
c.ignore('disable_warnings')

with self.argument_context('containerapp scale') as c:
c.argument('min_replicas', type=int, help="The minimum number of replicas.")
Expand Down Expand Up @@ -180,6 +181,17 @@ def load_arguments(self, _):
with self.argument_context('containerapp up') as c:
c.argument('resource_group_name', configured_default='resource_group_name')
c.argument('location', configured_default='location')
c.argument('name', configured_default='name')
c.argument('name', configured_default='name', id_part=None)
c.argument('managed_env', configured_default='managed_env')
c.argument('registry_server', configured_default='registry_server')
c.argument('disable_verbose', help="Disable verbose output from ACR build when using --source.")
c.argument('dockerfile', help="Name of the dockerfile.")
c.argument('dryrun', help="Show summary of the operation instead of executing it.")

with self.argument_context('containerapp up', arg_group='Log Analytics (Environment)') as c:
c.argument('logs_customer_id', type=str, options_list=['--logs-workspace-id'], help='Name or resource ID of the Log Analytics workspace to send diagnostics logs to. You can use \"az monitor log-analytics workspace create\" to create one. Extra billing may apply.')
c.argument('logs_key', type=str, options_list=['--logs-workspace-key'], help='Log Analytics workspace key to configure your Log Analytics workspace. You can use \"az monitor log-analytics workspace get-shared-keys\" to retrieve the key.')
c.ignore('no_wait')

with self.argument_context('containerapp', arg_group='Container') as c:
c.argument('source', type=str, help='Local directory path to upload to Azure container registry.')
16 changes: 10 additions & 6 deletions src/containerapp/azext_containerapp/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# pylint: disable=line-too-long, consider-using-f-string, no-else-return, duplicate-string-formatting-argument

from urllib.parse import urlparse
from azure.cli.core.azclierror import (ValidationError, RequiredArgumentMissingError)
from azure.cli.core.azclierror import (ValidationError, RequiredArgumentMissingError, CLIInternalError)
from azure.cli.core.commands.client_factory import get_subscription_id
from knack.log import get_logger
from msrestazure.tools import parse_resource_id
Expand Down Expand Up @@ -131,7 +131,7 @@ def _update_revision_env_secretrefs(containers, name):
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):
def store_as_secret_and_return_secret_ref(secrets_list, registry_user, registry_server, registry_pass, update_existing_secret=False, disable_warnings=False):
if registry_pass.startswith("secretref:"):
# If user passed in registry password using a secret

Expand Down Expand Up @@ -161,7 +161,8 @@ def store_as_secret_and_return_secret_ref(secrets_list, registry_user, registry_
raise ValidationError('Found secret with name \"{}\" but value does not equal the supplied registry password.'.format(registry_secret_name))
return registry_secret_name

# logger.warning('Adding registry password as a secret with name \"{}\"'.format(registry_secret_name)) # pylint: disable=logging-format-interpolation
if not disable_warnings:
logger.warning('Adding registry password as a secret with name \"{}\"'.format(registry_secret_name)) # pylint: disable=logging-format-interpolation
secrets_list.append({
"name": registry_secret_name,
"value": registry_pass
Expand Down Expand Up @@ -233,7 +234,7 @@ def _generate_log_analytics_workspace_name(resource_group_name):

def _generate_log_analytics_if_not_provided(cmd, logs_customer_id, logs_key, location, resource_group_name):
if logs_customer_id is None and logs_key is None:
# logger.warning("No Log Analytics workspace provided.")
logger.warning("No Log Analytics workspace provided.")
try:
_validate_subscription_registered(cmd, "Microsoft.OperationalInsights")
log_analytics_client = log_analytics_client_factory(cmd.cli_ctx)
Expand All @@ -250,7 +251,7 @@ def _generate_log_analytics_if_not_provided(cmd, logs_customer_id, logs_key, loc

workspace_name = _generate_log_analytics_workspace_name(resource_group_name)
workspace_instance = Workspace(location=log_analytics_location)
# logger.warning("Generating a Log Analytics workspace with name \"{}\"".format(workspace_name)) # pylint: disable=logging-format-interpolation
logger.warning("Generating a Log Analytics workspace with name \"{}\"".format(workspace_name)) # pylint: disable=logging-format-interpolation

poller = log_analytics_client.begin_create_or_update(resource_group_name, workspace_name, workspace_instance)
log_analytics_workspace = LongRunningOperation(cmd.cli_ctx)(poller)
Expand Down Expand Up @@ -288,7 +289,7 @@ def _generate_log_analytics_if_not_provided(cmd, logs_customer_id, logs_key, loc

logs_key = shared_keys.primary_shared_key

return logs_customer_id, logs_key
return logs_customer_id, logs_key, workspace_name


def _get_existing_secrets(cmd, resource_group_name, name, containerapp_def):
Expand Down Expand Up @@ -565,6 +566,7 @@ def _infer_acr_credentials(cmd, registry_server, disable_warnings=False):
# If registry is Azure Container Registry, we can try inferring credentials
if '.azurecr.io' not in registry_server:
raise RequiredArgumentMissingError('Registry username and password are required if not using Azure Container Registry.')
logger.warning("Infer acr credentials")
not disable_warnings and logger.warning('No credential was provided to access Azure Container Registry. Trying to look up credentials...')
parsed = urlparse(registry_server)
registry_name = (parsed.netloc if parsed.scheme else parsed.path).split('.')[0]
Expand Down Expand Up @@ -724,6 +726,8 @@ def queue_acr_build(cmd, registry_rg, registry_name, img_name, src_dir, dockerfi
lro_poller = get_run_with_polling(cmd, client_runs, run_id, registry_name, registry_rg)
acr = LongRunningOperation(cmd.cli_ctx)(lro_poller)
logger.warning("Build {}.".format(acr.status.lower()))
if acr.status.lower() != "succeeded":
raise CLIInternalError("ACR build {}.".format(acr.status.lower()))
return acr

return stream_logs(cmd, client_runs, run_id, registry_name, registry_rg, None, False, True)
Expand Down
58 changes: 29 additions & 29 deletions src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def create_containerapp(cmd,

if secrets_def is None:
secrets_def = []
registries_def["passwordSecretRef"] = store_as_secret_and_return_secret_ref(secrets_def, registry_user, registry_server, registry_pass)
registries_def["passwordSecretRef"] = store_as_secret_and_return_secret_ref(secrets_def, registry_user, registry_server, registry_pass, disable_warnings=disable_warnings)

dapr_def = None
if dapr_enabled:
Expand Down Expand Up @@ -1950,15 +1950,14 @@ def containerapp_up(cmd,
dockerfile="Dockerfile",
# compose=None,
ingress=None,
port=None,
registry_username=None,
registry_password=None,
target_port=None,
registry_user=None,
registry_pass=None,
env_vars=None,
dryrun=False,
logs_customer_id=None,
logs_key=None,
disable_verbose=False,
no_wait=False):
disable_verbose=False):
import os, json
src_dir = os.getcwd()
_src_path_escaped = "{}".format(src_dir.replace(os.sep, os.sep + os.sep))
Expand Down Expand Up @@ -2019,14 +2018,15 @@ def containerapp_up(cmd,
if not resource_group_name:
user = get_profile_username()
rg_name = get_randomized_name(user, resource_group_name) if custom_rg_name is None else custom_rg_name
not dryrun and logger.warning("Creating new resource group {}".format(rg_name))
not dryrun and create_resource_group(cmd, rg_name, location)
if not dryrun:
logger.warning("Creating new resource group {}".format(rg_name))
create_resource_group(cmd, rg_name, location)
resource_group_name = rg_name
if not managed_env:
env_name = "{}-env".format(name).replace("_","-")
if not dryrun:
logger.warning("Creating new managed environment {}".format(env_name))
managed_env = create_managed_environment(cmd, env_name, location = location, resource_group_name=resource_group_name, logs_key=logs_key, logs_customer_id=logs_customer_id, disable_warnings=True, no_wait=no_wait)["id"]
managed_env = create_managed_environment(cmd, env_name, location = location, resource_group_name=resource_group_name, logs_key=logs_key, logs_customer_id=logs_customer_id, disable_warnings=True)["id"]
else:
managed_env = env_name
else:
Expand All @@ -2035,17 +2035,17 @@ def containerapp_up(cmd,
env_name = containerapp_def["properties"]["managedEnvironmentId"].split('/')[8]
if logs_customer_id and logs_key:
if not dryrun:
managed_env = create_managed_environment(cmd, env_name, location = location, resource_group_name=resource_group_name, logs_key=logs_key, logs_customer_id=logs_customer_id, disable_warnings=True, no_wait=no_wait)["id"]
managed_env = create_managed_environment(cmd, env_name, location = location, resource_group_name=resource_group_name, logs_key=logs_key, logs_customer_id=logs_customer_id, disable_warnings=True)["id"]

if image is not None and "azurecr.io" in image and not dryrun:
if registry_username is None or registry_password is None:
if registry_user is None or registry_pass is None:
# If registry is Azure Container Registry, we can try inferring credentials
logger.warning('No credential was provided to access Azure Container Registry. Trying to look up...')
registry_server=image.split('/')[0]
parsed = urlparse(image)
registry_name = (parsed.netloc if parsed.scheme else parsed.path).split('.')[0]
try:
registry_username, registry_password = _get_acr_cred(cmd.cli_ctx, registry_name)
registry_user, registry_pass = _get_acr_cred(cmd.cli_ctx, registry_name)
except Exception as ex:
raise RequiredArgumentMissingError('Failed to retrieve credentials for container registry. Please provide the registry username and password') from ex

Expand All @@ -2056,25 +2056,24 @@ def containerapp_up(cmd,
registry_name = ""
registry_rg = ""
if registry_server:
if not dryrun and (registry_username is None or registry_password is None):
if "azurecr.io" in registry_server:
# If registry is Azure Container Registry, we can try inferring credentials
logger.warning('No credential was provided to access Azure Container Registry. Trying to look up...')
parsed = urlparse(registry_server)
registry_name = (parsed.netloc if parsed.scheme else parsed.path).split('.')[0]
try:
registry_username, registry_password, registry_rg = _get_acr_cred(cmd.cli_ctx, registry_name)
except Exception as ex:
raise RequiredArgumentMissingError('Failed to retrieve credentials for container registry. Please provide the registry username and password') from ex
else:
raise RequiredArgumentMissingError("Registry usename and password are required if using non-Azure registry.")
if "azurecr.io" not in registry_server:
raise ValidationError("Cannot supply non-Azure registry when using --source.")
elif not dryrun and (registry_user is None or registry_pass is None):
# If registry is Azure Container Registry, we can try inferring credentials
logger.warning('No credential was provided to access Azure Container Registry. Trying to look up...')
parsed = urlparse(registry_server)
registry_name = (parsed.netloc if parsed.scheme else parsed.path).split('.')[0]
try:
registry_user, registry_pass, registry_rg = _get_acr_cred(cmd.cli_ctx, registry_name)
except Exception as ex:
raise RequiredArgumentMissingError('Failed to retrieve credentials for container registry. Please provide the registry username and password') from ex
else:
registry_rg = resource_group_name
user = get_profile_username()
registry_name = "{}acr".format(name)
registry_name = registry_name + str(hash((registry_rg, user, name))).replace("-","")
not dryrun and logger.warning("Creating new acr {}".format(registry_name))
if not dryrun:
logger.warning("Creating new acr {}".format(registry_name))
registry_def = create_new_acr(cmd, registry_name, registry_rg, location)
registry_server = registry_def.login_server
else:
Expand All @@ -2085,7 +2084,8 @@ def containerapp_up(cmd,
now = datetime.now()
image_name += ":{}".format(str(now).replace(' ', '').replace('-','').replace('.','').replace(':',''))
image = registry_server + '/' + image_name
not dryrun and queue_acr_build(cmd, registry_rg, registry_name, image_name, source, dockerfile, disable_verbose)
if not dryrun:
queue_acr_build(cmd, registry_rg, registry_name, image_name, source, dockerfile, disable_verbose)
_set_webapp_up_default_args(cmd, resource_group_name, location, name, registry_server)

dry_run_str = r""" {
Expand All @@ -2098,10 +2098,10 @@ def containerapp_up(cmd,
"src_path" : "%s"
}
""" % (name, resource_group_name, location, env_name, registry_server, image, _src_path_escaped)

not dryrun and create_containerapp(cmd=cmd, name=name, resource_group_name=resource_group_name, image=image, managed_env=managed_env, target_port=port, registry_server=registry_server, registry_pass=registry_password, registry_user=registry_username, env_vars=env_vars, ingress=ingress, disable_warnings=True, no_wait=no_wait)

if dryrun:
logger.warning("Containerapp will be created with the below configuration, re-run command "
"without the --dryrun flag to create & deploy a new containerapp.")
else:
create_containerapp(cmd=cmd, name=name, resource_group_name=resource_group_name, image=image, managed_env=managed_env, target_port=target_port, registry_server=registry_server, registry_pass=registry_pass, registry_user=registry_user, env_vars=env_vars, ingress=ingress, disable_warnings=True)

return json.loads(dry_run_str)