Skip to content

Commit f73c7e9

Browse files
authored
[Containerapp] az containerapp: Move containerapp from CLI extension to core CLI (#27078)
1 parent a0b9405 commit f73c7e9

File tree

211 files changed

+572521
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

211 files changed

+572521
-5
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@
6565
/src/azure-cli/azure/cli/command_modules/synapse/ @jsntcy @idear1203 @zesluo @evelyn-ys
6666
/src/azure-cli/azure/cli/command_modules/util/ @jiasli @zhoxing-ms @evelyn-ys
6767
/src/azure-cli/azure/cli/command_modules/vm/ @zhoxing-ms @jsntcy @wangzelin007 @yanzhudd @Drewm3 @TravisCragg-MSFT @nikhilpatel909 @sandeepraichura @hilaryw29 @GabstaMSFT @ramankumarlive @ushnaarshadkhan
68+
/src/azure-cli/azure/cli/command_modules/containerapp/ @ruslany @sanchitmehta @ebencarek @JennyLawrance @howang-ms @vinisoto @chinadragon0515 @vturecek @torosent @pagariyaalok @Juliehzl @jijohn14 @Greedygre

doc/sphinx/azhelpgen/doc_source_map.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"configure": "src/azure-cli/azure/cli/command_modules/configure/_help.py",
2424
"consumption": "src/azure-cli/azure/cli/command_modules/consumption/_help.py",
2525
"container": "src/azure-cli/azure/cli/command_modules/container/_help.py",
26+
"containerapp": "src/azure-cli/azure/cli/command_modules/containerapp/_help.py",
2627
"cosmosdb": "src/azure-cli/azure/cli/command_modules/cosmosdb/_help.py",
2728
"databoxedge": "src/azure-cli/azure/cli/command_modules/databoxedge/_help.py",
2829
"deployment": "src/azure-cli/azure/cli/command_modules/resource/_help.py",

scripts/ci/credscan/CredScanSuppressions.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,30 @@
576576
"src\\azure-cli\\azure\\cli\\command_modules\\acs\\tests\\latest\\data\\setup_proxy.sh"
577577
],
578578
"_justification": "Dummy self-signed certificate + private key used for testing only."
579+
},
580+
{
581+
"placeholder": "\"sharedKey\":\"abc123\"",
582+
"_justification": "[containerapp] request body for create containerapp environment contains property sharedKey recognized as secret"
583+
},
584+
{
585+
"placeholder": "\"primarySharedKey\":\"abc123\"",
586+
"_justification": "[containerapp] Get log workspace primary sharedkey, response body contains sharedKey recognized as secret"
587+
},
588+
{
589+
"placeholder": "abc123",
590+
"_justification": "[containerapp] request body contains sharedKey recognized as secret"
591+
},
592+
{
593+
"placeholder": "test12",
594+
"_justification": "[containerapp] certificate password for load certificate file"
595+
},
596+
{
597+
"file": [
598+
"src\\azure-cli\\azure\\cli\\command_modules\\containerapp\\tests\\latest\\data\\cert.pfx",
599+
"src\\azure-cli\\azure\\cli\\command_modules\\containerapp\\tests\\latest\\data\\cert.pem",
600+
"src\\azure-cli\\azure\\cli\\command_modules\\containerapp\\tests\\latest\\data\\cert.txt"
601+
],
602+
"_justification": "[containerapp] Test certs"
579603
}
580604
]
581605
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
# pylint: disable=super-with-arguments
6+
7+
from azure.cli.core import AzCommandsLoader
8+
9+
from azure.cli.command_modules.containerapp._help import helps # pylint: disable=unused-import
10+
11+
12+
class ContainerappCommandsLoader(AzCommandsLoader):
13+
14+
def __init__(self, cli_ctx=None):
15+
from azure.cli.core.commands import CliCommandType
16+
containerapp_custom = CliCommandType(
17+
operations_tmpl='azure.cli.command_modules.containerapp.custom#{}',
18+
client_factory=None)
19+
super(ContainerappCommandsLoader, self).__init__(cli_ctx=cli_ctx,
20+
custom_command_type=containerapp_custom)
21+
22+
def load_command_table(self, args):
23+
from azure.cli.command_modules.containerapp.commands import load_command_table
24+
from azure.cli.core.aaz import load_aaz_command_table
25+
try:
26+
from . import aaz
27+
except ImportError:
28+
aaz = None
29+
if aaz:
30+
load_aaz_command_table(
31+
loader=self,
32+
aaz_pkg_name=aaz.__name__,
33+
args=args
34+
)
35+
load_command_table(self, args)
36+
return self.command_table
37+
38+
def load_arguments(self, command):
39+
from azure.cli.command_modules.containerapp._params import load_arguments
40+
load_arguments(self, command)
41+
42+
43+
COMMAND_LOADER_CLS = ContainerappCommandsLoader
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
# pylint: disable=line-too-long, consider-using-f-string
6+
7+
import time
8+
9+
from msrest import Deserializer
10+
from msrestazure.azure_exceptions import CloudError
11+
from azure.cli.core.profiles import ResourceType
12+
from azure.cli.command_modules.acr._constants import get_acr_task_models
13+
from azure.core.polling import PollingMethod, LROPoller
14+
15+
16+
def get_run_with_polling(cmd,
17+
client,
18+
run_id,
19+
registry_name,
20+
resource_group_name):
21+
deserializer = Deserializer(
22+
{k: v for k, v in get_acr_task_models(cmd).__dict__.items() if isinstance(v, type)})
23+
24+
def deserialize_run(response):
25+
return deserializer('Run', response)
26+
27+
return LROPoller(
28+
client=client,
29+
initial_response=client.get(
30+
resource_group_name, registry_name, run_id, cls=lambda x, y, z: x),
31+
deserialization_callback=deserialize_run,
32+
polling_method=RunPolling(
33+
cmd=cmd,
34+
registry_name=registry_name,
35+
run_id=run_id
36+
))
37+
38+
39+
class RunPolling(PollingMethod): # pylint: disable=too-many-instance-attributes
40+
41+
def __init__(self, cmd, registry_name, run_id, timeout=30):
42+
self._cmd = cmd
43+
self._registry_name = registry_name
44+
self._run_id = run_id
45+
self._timeout = timeout
46+
self._client = None
47+
self._response = None # Will hold latest received response
48+
self._url = None # The URL used to get the run
49+
self._deserialize = None # The deserializer for Run
50+
self.operation_status = ""
51+
self.operation_result = None
52+
53+
def initialize(self, client, initial_response, deserialization_callback):
54+
self._client = client._client # pylint: disable=protected-access
55+
self._response = initial_response
56+
self._url = initial_response.http_request.url
57+
self._deserialize = deserialization_callback
58+
59+
self._set_operation_status(initial_response)
60+
61+
def run(self):
62+
while not self.finished():
63+
time.sleep(self._timeout)
64+
self._update_status()
65+
66+
if self.operation_status not in get_succeeded_run_status(self._cmd):
67+
from knack.util import CLIError
68+
raise CLIError("The run with ID '{}' finished with unsuccessful status '{}'. "
69+
"Show run details by 'az acr task show-run -r {} --run-id {}'. "
70+
"Show run logs by 'az acr task logs -r {} --run-id {}'.".format(
71+
self._run_id,
72+
self.operation_status,
73+
self._registry_name,
74+
self._run_id,
75+
self._registry_name,
76+
self._run_id
77+
))
78+
79+
def status(self):
80+
return self.operation_status
81+
82+
def finished(self):
83+
return self.operation_status in get_finished_run_status(self._cmd)
84+
85+
def resource(self):
86+
return self.operation_result
87+
88+
def _set_operation_status(self, response):
89+
if response.http_response.status_code == 200:
90+
self.operation_result = self._deserialize(response)
91+
self.operation_status = self.operation_result.status
92+
return
93+
raise CloudError(response)
94+
95+
def _update_status(self):
96+
self._response = self._client._pipeline.run( # pylint: disable=protected-access
97+
self._client.get(self._url), stream=False)
98+
self._set_operation_status(self._response)
99+
100+
101+
def get_succeeded_run_status(cmd):
102+
RunStatus = cmd.get_models('RunStatus', resource_type=ResourceType.MGMT_CONTAINERREGISTRY, operation_group='task_runs')
103+
return [RunStatus.succeeded.value]
104+
105+
106+
def get_finished_run_status(cmd):
107+
RunStatus = cmd.get_models('RunStatus', resource_type=ResourceType.MGMT_CONTAINERREGISTRY, operation_group='task_runs')
108+
return [RunStatus.succeeded.value,
109+
RunStatus.failed.value,
110+
RunStatus.canceled.value,
111+
RunStatus.error.value,
112+
RunStatus.timeout.value]

0 commit comments

Comments
 (0)