-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
containerapp add containerapp-preview extension #6419
Merged
zhoxing-ms
merged 54 commits into
Azure:main
from
Greedygre:xinyu/add_create_containerapp_preview
Jul 12, 2023
Merged
Changes from 51 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
d0c524e
init containerapp-preview
Greedygre f7be550
add GA extension dependency
Greedygre d6d8f7c
add --environment-type
Greedygre 93c8960
fix bug for prompt
Greedygre 62debc5
warning for update extension
Greedygre a98d7d3
remove useless code
Greedygre 12820f4
fix
Greedygre d948cdf
remove
Greedygre 1bb1cea
remove setup
Greedygre 2afbe83
fix
Greedygre 42ab370
fix lint
Greedygre d6beff8
fix test
Greedygre 0cf803f
test tbd
Greedygre 9b9b237
test 0.0.0
Greedygre 7c34333
add create containerapp
Greedygre 1e81de8
fix
Greedygre ec88eb3
add env and environment type
Greedygre ac2c33c
set is preview
Greedygre bd96ab5
fix
Greedygre 724a381
support --yaml with extended-location
Greedygre 88eaa6a
fix extend
Greedygre 94eebe4
add show/delete/list containerapp in preview
Greedygre 6a4fb88
fix preview
Greedygre 2a4a168
fix error
Greedygre 8b17806
fix error
Greedygre c7410b7
rebase main
Greedygre 4c9f52e
fix delete
Greedygre 8cf2fc8
refactor client and make constants
Greedygre 368fae6
add test for environment type on arc
Greedygre 2618e94
set version
Greedygre 22bb79a
add test yaml
Greedygre 0f0ffb4
fix error
Greedygre 958e075
fix containerapp preview test
Greedygre c8662e2
add rely GA extension in test
Greedygre 5cd3762
fix test
Greedygre 44e6078
remove useless code
Greedygre 94be4f6
fix install for loading
Greedygre 8cf778f
Update verify_linter.py
wangzelin007 5446f32
fix recording and set version to 1.0.0b1
Greedygre 52533f7
fix static analysis: blank line at the end
Greedygre eb2b6e6
Update verify_linter.py
wangzelin007 fd55f66
fix comments
Greedygre 2e799d9
remove blank line
Greedygre 5faa2ca
remove python 3.6 support in setup and add more comments for command …
Greedygre 37147a9
add test for managed, add helps, parse resource type and compare
Greedygre 8ae8319
add blank line
Greedygre 18f613d
remove prompt logic
Greedygre fd90a41
fix
Greedygre c592553
fix
Greedygre 99e67f9
fix help
Greedygre 03aa729
raise error in _get_azext_module
Greedygre 26cf02c
fix comments
Greedygre a6d4f0d
add a blank line
Greedygre acecec6
rename _get_azext_containerapp_module
Greedygre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.. :changelog: | ||
|
||
Release History | ||
=============== | ||
|
||
1.0.0b1 | ||
++++++ | ||
* Initial containerapp-preview extension. | ||
* `az containerapp list/show/delete/create`: support for preview extension | ||
* `az containerapp create`: support --environment-type parameter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Microsoft Azure CLI 'containerapp-preview' Extension | ||
========================================== | ||
|
||
This package is for the 'containerapp-preview' extension. | ||
i.e. 'az containerapp' | ||
|
||
We have two extensions: containerapp and containerapp-preview. | ||
The containerapp-preview extension does not run independently, it requires the containerapp extension. | ||
The commands in containerapp-preview can override the same commands in containerapp. |
36 changes: 36 additions & 0 deletions
36
src/containerapp-preview/azext_containerapp_preview/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from azure.cli.core import AzCommandsLoader | ||
|
||
from azext_containerapp_preview._help import helps # pylint: disable=unused-import | ||
from azext_containerapp_preview._utils import (_get_azext_module) | ||
|
||
|
||
class ContainerappPreviewCommandsLoader(AzCommandsLoader): | ||
|
||
def __init__(self, cli_ctx=None): | ||
from azure.cli.core.commands import CliCommandType | ||
containerapp_preview_custom = CliCommandType( | ||
operations_tmpl='azext_containerapp_preview.custom#{}', | ||
client_factory=None) | ||
super(ContainerappPreviewCommandsLoader, self).__init__(cli_ctx=cli_ctx, | ||
custom_command_type=containerapp_preview_custom) | ||
|
||
def load_command_table(self, args): | ||
from azext_containerapp_preview.commands import load_command_table | ||
|
||
load_command_table(self, args) | ||
return self.command_table | ||
|
||
def load_arguments(self, command): | ||
from azext_containerapp_preview._params import load_arguments | ||
|
||
ga_params = _get_azext_module("azext_containerapp._params") | ||
Greedygre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ga_params.load_arguments(self, command) | ||
load_arguments(self, command) | ||
|
||
|
||
COMMAND_LOADER_CLS = ContainerappPreviewCommandsLoader |
190 changes: 190 additions & 0 deletions
190
src/containerapp-preview/azext_containerapp_preview/_clients.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
# coding=utf-8 | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
import json | ||
|
||
from azure.cli.core.azclierror import ResourceNotFoundError | ||
from azure.cli.core.util import send_raw_request | ||
from azure.cli.core.commands.client_factory import get_subscription_id | ||
from knack.log import get_logger | ||
|
||
from ._utils import (_get_azext_module) | ||
|
||
logger = get_logger(__name__) | ||
|
||
PREVIEW_API_VERSION = "2023-04-01-preview" | ||
HEADER_AZURE_ASYNC_OPERATION = "azure-asyncoperation" | ||
HEADER_LOCATION = "location" | ||
|
||
|
||
def poll_status(cmd, request_url): | ||
azext_client = _get_azext_module("azext_containerapp._clients") | ||
return azext_client.poll_status(cmd, request_url) | ||
|
||
|
||
def poll_results(cmd, request_url): | ||
azext_client = _get_azext_module("azext_containerapp._clients") | ||
return azext_client.poll_results(cmd, request_url) | ||
|
||
|
||
class ContainerAppClient(_get_azext_module("azext_containerapp._clients").ContainerAppClient): | ||
@classmethod | ||
def get_api_version(cls): | ||
return PREVIEW_API_VERSION | ||
|
||
|
||
class ManagedEnvironmentClient(_get_azext_module("azext_containerapp._clients").ManagedEnvironmentClient): | ||
@classmethod | ||
def get_api_version(cls): | ||
return PREVIEW_API_VERSION | ||
|
||
|
||
class ConnectedEnvironmentClient(): | ||
@classmethod | ||
def get_api_version(cls): | ||
return PREVIEW_API_VERSION | ||
|
||
@classmethod | ||
def create(cls, cmd, resource_group_name, name, connected_environment_envelope, no_wait=False): | ||
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
sub_id = get_subscription_id(cmd.cli_ctx) | ||
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/connectedEnvironments/{}?api-version={}" | ||
request_url = url_fmt.format( | ||
management_hostname.strip('/'), | ||
sub_id, | ||
resource_group_name, | ||
name, | ||
cls.get_api_version()) | ||
Greedygre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
r = send_raw_request(cmd.cli_ctx, "PUT", request_url, body=json.dumps(connected_environment_envelope)) | ||
|
||
if no_wait: | ||
return r.json() | ||
elif r.status_code == 201: | ||
operation_url = r.headers.get(HEADER_AZURE_ASYNC_OPERATION) | ||
poll_status(cmd, operation_url) | ||
r = send_raw_request(cmd.cli_ctx, "GET", request_url) | ||
|
||
return r.json() | ||
|
||
@classmethod | ||
def update(cls, cmd, resource_group_name, name, managed_environment_envelope, no_wait=False): | ||
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
sub_id = get_subscription_id(cmd.cli_ctx) | ||
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/connectedEnvironments/{}?api-version={}" | ||
request_url = url_fmt.format( | ||
management_hostname.strip('/'), | ||
sub_id, | ||
resource_group_name, | ||
name, | ||
cls.get_api_version()) | ||
|
||
r = send_raw_request(cmd.cli_ctx, "PATCH", request_url, body=json.dumps(managed_environment_envelope)) | ||
|
||
if no_wait: | ||
return | ||
elif r.status_code == 202: | ||
operation_url = r.headers.get(HEADER_LOCATION) | ||
response = poll_results(cmd, operation_url) | ||
if response is None: | ||
raise ResourceNotFoundError("Could not find a connected environment") | ||
else: | ||
return response | ||
|
||
return r.json() | ||
|
||
@classmethod | ||
def delete(cls, cmd, resource_group_name, name, no_wait=False): | ||
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
sub_id = get_subscription_id(cmd.cli_ctx) | ||
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/connectedEnvironments/{}?api-version={}" | ||
request_url = url_fmt.format( | ||
management_hostname.strip('/'), | ||
sub_id, | ||
resource_group_name, | ||
name, | ||
cls.get_api_version()) | ||
|
||
r = send_raw_request(cmd.cli_ctx, "DELETE", request_url) | ||
|
||
if no_wait: | ||
return # API doesn't return JSON (it returns no content) | ||
elif r.status_code in [200, 201, 202, 204]: | ||
if r.status_code == 202: | ||
operation_url = r.headers.get(HEADER_LOCATION) | ||
poll_results(cmd, operation_url) | ||
logger.warning('Connected environment successfully deleted') | ||
return | ||
|
||
@classmethod | ||
def show(cls, cmd, resource_group_name, name): | ||
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
sub_id = get_subscription_id(cmd.cli_ctx) | ||
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/connectedEnvironments/{}?api-version={}" | ||
request_url = url_fmt.format( | ||
management_hostname.strip('/'), | ||
sub_id, | ||
resource_group_name, | ||
name, | ||
cls.get_api_version()) | ||
|
||
r = send_raw_request(cmd.cli_ctx, "GET", request_url) | ||
return r.json() | ||
|
||
@classmethod | ||
def list_by_subscription(cls, cmd, formatter=lambda x: x): | ||
env_list = [] | ||
|
||
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
sub_id = get_subscription_id(cmd.cli_ctx) | ||
request_url = "{}/subscriptions/{}/providers/Microsoft.App/connectedEnvironments?api-version={}".format( | ||
management_hostname.strip('/'), | ||
sub_id, | ||
cls.get_api_version()) | ||
|
||
r = send_raw_request(cmd.cli_ctx, "GET", request_url) | ||
j = r.json() | ||
for env in j["value"]: | ||
formatted = formatter(env) | ||
env_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 env in j["value"]: | ||
formatted = formatter(env) | ||
env_list.append(formatted) | ||
|
||
return env_list | ||
|
||
@classmethod | ||
def list_by_resource_group(cls, cmd, resource_group_name, formatter=lambda x: x): | ||
env_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/connectedEnvironments?api-version={}" | ||
request_url = url_fmt.format( | ||
management_hostname.strip('/'), | ||
sub_id, | ||
resource_group_name, | ||
cls.get_api_version()) | ||
|
||
r = send_raw_request(cmd.cli_ctx, "GET", request_url) | ||
j = r.json() | ||
for env in j["value"]: | ||
formatted = formatter(env) | ||
env_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 env in j["value"]: | ||
formatted = formatter(env) | ||
env_list.append(formatted) | ||
|
||
return env_list |
12 changes: 12 additions & 0 deletions
12
src/containerapp-preview/azext_containerapp_preview/_constants.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# coding=utf-8 | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
MANAGED_ENVIRONMENT_TYPE = "managed" | ||
CONNECTED_ENVIRONMENT_TYPE = "connected" | ||
MANAGED_ENVIRONMENT_RESOURCE_TYPE = "managedEnvironments" | ||
CONNECTED_ENVIRONMENT_RESOURCE_TYPE = "connectedEnvironments" | ||
GA_CONTAINERAPP_EXTENSION_NAME = 'containerapp' | ||
MIN_GA_VERSION = '0.3.35' | ||
CONTAINERAPP_NAMESPACE = 'Microsoft.App' |
64 changes: 64 additions & 0 deletions
64
src/containerapp-preview/azext_containerapp_preview/_help.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# coding=utf-8 | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from knack.help_files import helps # pylint: disable=unused-import | ||
Greedygre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
helps['containerapp create'] = """ | ||
type: command | ||
short-summary: Create a container app. | ||
examples: | ||
- name: Create a container app and retrieve its fully qualified domain name. | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
--image myregistry.azurecr.io/my-app:v1.0 --environment MyContainerappEnv \\ | ||
--ingress external --target-port 80 \\ | ||
--registry-server myregistry.azurecr.io --registry-username myregistry --registry-password $REGISTRY_PASSWORD \\ | ||
--query properties.configuration.ingress.fqdn | ||
- name: Create a container app with resource requirements and replica count limits. | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
--image nginx --environment MyContainerappEnv \\ | ||
--cpu 0.5 --memory 1.0Gi \\ | ||
--min-replicas 4 --max-replicas 8 | ||
- name: Create a container app with secrets and environment variables. | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
--image my-app:v1.0 --environment MyContainerappEnv \\ | ||
--secrets mysecret=secretvalue1 anothersecret="secret value 2" \\ | ||
--env-vars GREETING="Hello, world" SECRETENV=secretref:anothersecret | ||
- name: Create a container app using a YAML configuration. Example YAML configuration - https://aka.ms/azure-container-apps-yaml | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
--environment MyContainerappEnv \\ | ||
--yaml "path/to/yaml/file.yml" | ||
- name: Create a container app with an http scale rule | ||
text: | | ||
az containerapp create -n myapp -g mygroup --environment myenv --image nginx \\ | ||
--scale-rule-name my-http-rule \\ | ||
--scale-rule-http-concurrency 50 | ||
- name: Create a container app with a custom scale rule | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
Greedygre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
--image my-queue-processor --environment MyContainerappEnv \\ | ||
--min-replicas 4 --max-replicas 8 \\ | ||
--scale-rule-name queue-based-autoscaling \\ | ||
--scale-rule-type azure-queue \\ | ||
--scale-rule-metadata "accountName=mystorageaccountname" \\ | ||
"cloud=AzurePublicCloud" \\ | ||
"queueLength": "5" "queueName": "foo" \\ | ||
--scale-rule-auth "connection=my-connection-string-secret-name" | ||
- name: Create a container app with secrets and mounts them in a volume. | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
--image my-app:v1.0 --environment MyContainerappEnv \\ | ||
--secrets mysecret=secretvalue1 anothersecret="secret value 2" \\ | ||
--secret-volume-mount "mnt/secrets" | ||
- name: Create a container app hosted on a Connected Environment. | ||
text: | | ||
az containerapp create -n MyContainerapp -g MyResourceGroup \\ | ||
--image my-app:v1.0 --environment MyContainerappConnectedEnv \\ | ||
--environment-type connected | ||
""" |
18 changes: 18 additions & 0 deletions
18
src/containerapp-preview/azext_containerapp_preview/_params.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
# pylint: disable=line-too-long | ||
from azure.cli.core.commands.parameters import get_enum_type | ||
|
||
from ._validators import validate_env_name_or_id | ||
|
||
|
||
# This method cannot directly rely on GA resources. | ||
# When the switch core.use_command_index is turned off, possibly unrelated commands may also trigger unnecessary loads. | ||
# It will throw a warning if the GA resource does not exist. | ||
def load_arguments(self, _): | ||
|
||
with self.argument_context('containerapp create') as c: | ||
c.argument('managed_env', validator=validate_env_name_or_id, options_list=['--environment'], help="Name or resource ID of the container app's environment.") | ||
c.argument('environment_type', arg_type=get_enum_type(["managed", "connected"]), help="Type of environment.", is_preview=True) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to remove containerapp when removing containerapp-preivew
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For pipeline linter test for containerapp-preview extension, need to install containerapp extension.
After completing the test need to remove containerapp.