Skip to content

Commit fb17f16

Browse files
committed
adding all the missing files
1 parent ab26157 commit fb17f16

9 files changed

Lines changed: 25754 additions & 0 deletions
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for license information.
5+
# --------------------------------------------------------------------------------------------
6+
# pylint: disable=line-too-long, broad-except, logging-format-interpolation, too-many-public-methods, too-many-boolean-expressions, logging-fstring-interpolation
7+
8+
from knack.log import get_logger
9+
import urllib
10+
from azure.cli.core.azclierror import ValidationError
11+
from azure.cli.command_modules.containerapp.base_resource import BaseResource
12+
from azure.cli.core.commands.client_factory import get_subscription_id
13+
from azure.cli.core.util import send_raw_request
14+
from ._transformers import transform_debug_command_output
15+
16+
from ._validators import validate_basic_arguments
17+
18+
logger = get_logger(__name__)
19+
20+
21+
class ContainerAppDebugCommandDecorator(BaseResource):
22+
"""Base decorator for Container App Debug Command Operations"""
23+
24+
def get_argument_resource_group_name(self):
25+
return self.get_param('resource_group_name')
26+
27+
def get_argument_container_app_name(self):
28+
return self.get_param('container_app_name')
29+
30+
def get_argument_revision_name(self):
31+
return self.get_param("revision_name")
32+
33+
def get_argument_replica_name(self):
34+
return self.get_param("replica_name")
35+
36+
def get_argument_container_name(self):
37+
return self.get_param("container_name")
38+
39+
def get_argument_command(self):
40+
return self.get_param("command")
41+
42+
def validate_arguments(self):
43+
validate_basic_arguments(
44+
resource_group_name=self.get_argument_resource_group_name(),
45+
container_app_name=self.get_argument_container_app_name(),
46+
revision_name=self.get_argument_revision_name(),
47+
replica_name=self.get_argument_replica_name(),
48+
container_name=self.get_argument_container_name(),
49+
command=self.get_argument_command()
50+
)
51+
52+
def _get_logstream_endpoint(self, cmd, resource_group_name, container_app_name, revision_name, replica_name, container_name):
53+
"""Get the logstream endpoint for the specified container in the replica"""
54+
containers = self.client.get_replica(cmd,
55+
resource_group_name,
56+
container_app_name, revision_name, replica_name)["properties"]["containers"]
57+
container_info = [c for c in containers if c["name"] == container_name]
58+
if not container_info:
59+
raise ValidationError(f"Error retrieving container in revision '{revision_name}' in the container app '{container_app_name}'.")
60+
return container_info[0]["logStreamEndpoint"]
61+
62+
def _get_url(self, cmd, resource_group_name, container_app_name, revision_name, replica_name, container_name, command):
63+
"""Get the debug url for the specified container in the replica"""
64+
base_url = self._get_logstream_endpoint(cmd, resource_group_name, container_app_name, revision_name, replica_name, container_name)
65+
proxy_api_url = base_url[:base_url.index("/subscriptions/")]
66+
sub = get_subscription_id(cmd.cli_ctx)
67+
encoded_cmd = urllib.parse.quote_plus(command)
68+
debug_url = (f"{proxy_api_url}/subscriptions/{sub}/resourceGroups/{resource_group_name}/containerApps/{container_app_name}"
69+
f"/revisions/{revision_name}/replicas/{replica_name}/debug"
70+
f"?targetContainer={container_name}&command={encoded_cmd}")
71+
return debug_url
72+
73+
def _get_auth_token(self, cmd, resource_group_name, container_app_name):
74+
token_response = self.client.get_auth_token(cmd, resource_group_name, container_app_name)
75+
return token_response["properties"]["token"]
76+
77+
def execute_Command(self, cmd):
78+
"""Execute the command in the specified container in the replica"""
79+
resource_group_name = self.get_argument_resource_group_name()
80+
container_app_name = self.get_argument_container_app_name()
81+
revision_name = self.get_argument_revision_name()
82+
replica_name = self.get_argument_replica_name()
83+
container_name = self.get_argument_container_name()
84+
command = self.get_argument_command()
85+
url = self._get_url(cmd, resource_group_name, container_app_name, revision_name, replica_name, container_name, command)
86+
token = self._get_auth_token(cmd, resource_group_name, container_app_name)
87+
headers = [f"Authorization=Bearer {token}"]
88+
r = send_raw_request(cmd.cli_ctx, "GET", url, headers=headers)
89+
return transform_debug_command_output(r.json())
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for license information.
5+
# --------------------------------------------------------------------------------------------
6+
# pylint: disable=line-too-long, broad-except, logging-format-interpolation
7+
8+
from knack.log import get_logger
9+
from azure.cli.core.azclierror import ValidationError
10+
from azure.cli.command_modules.containerapp.base_resource import BaseResource
11+
from ._client_factory import handle_raw_exception
12+
from ._validators import validate_basic_arguments, validate_revision_and_get_name, validate_functionapp_kind
13+
from ._utils import get_random_replica
14+
15+
logger = get_logger(__name__)
16+
17+
18+
class ContainerAppFunctionKeysDecorator(BaseResource):
19+
"""Base decorator for Container App Function Keys operations"""
20+
21+
def get_argument_function_name(self):
22+
return self.get_param("function_name")
23+
24+
def get_argument_revision(self):
25+
return self.get_param("revision_name")
26+
27+
def get_argument_key_type(self):
28+
return self.get_param("key_type")
29+
30+
def get_argument_name(self):
31+
return self.get_param("container_app_name")
32+
33+
def get_argument_key_name(self):
34+
return self.get_param("key_name")
35+
36+
def get_argument_key_value(self):
37+
return self.get_param("key_value")
38+
39+
def validate_common_arguments(self):
40+
"""Validate common arguments required for all function key operations"""
41+
resource_group_name = self.get_argument_resource_group_name()
42+
name = self.get_argument_name()
43+
revision_name = self.get_argument_revision()
44+
key_type = self.get_argument_key_type()
45+
46+
# Validate basic arguments
47+
validate_basic_arguments(
48+
resource_group_name=resource_group_name,
49+
container_app_name=name,
50+
key_type=key_type
51+
)
52+
53+
# Validate that the Container App has kind 'functionapp'
54+
validate_functionapp_kind(
55+
cmd=self.cmd,
56+
resource_group_name=resource_group_name,
57+
container_app_name=name
58+
)
59+
60+
# Validate revision and get the appropriate revision name
61+
revision_name = validate_revision_and_get_name(
62+
cmd=self.cmd,
63+
resource_group_name=resource_group_name,
64+
container_app_name=name,
65+
provided_revision_name=revision_name
66+
)
67+
68+
# Get a random replica for the revision
69+
replica_name, container_name = get_random_replica(
70+
cmd=self.cmd,
71+
resource_group_name=resource_group_name,
72+
container_app_name=name,
73+
revision_name=revision_name
74+
)
75+
76+
return resource_group_name, name, revision_name, key_type, replica_name, container_name
77+
78+
def validate_function_name_requirement(self, key_type):
79+
"""Validate function name is provided when required for functionKey type"""
80+
function_name = self.get_argument_function_name()
81+
82+
if key_type == "functionKey" and not function_name:
83+
raise ValidationError("Function name is required when key-type is 'functionKey'.")
84+
85+
return function_name
86+
87+
88+
class ContainerAppFunctionKeysShowDecorator(ContainerAppFunctionKeysDecorator):
89+
"""Decorator for showing specific function keys"""
90+
91+
def validate_show_arguments(self):
92+
"""Validate arguments required for showing function keys"""
93+
resource_group_name, name, revision_name, key_type, replica_name, container_name = self.validate_common_arguments()
94+
key_name = self.get_argument_key_name()
95+
function_name = self.validate_function_name_requirement(key_type)
96+
97+
if not key_name:
98+
raise ValidationError("Key name is required.")
99+
100+
return resource_group_name, name, revision_name, key_type, key_name, function_name, replica_name, container_name
101+
102+
def show_keys(self):
103+
"""Show specific key"""
104+
try:
105+
resource_group_name, name, revision_name, key_type, key_name, function_name, replica_name, container_name = self.validate_show_arguments()
106+
107+
return self.client.show_function_keys(
108+
cmd=self.cmd,
109+
resource_group_name=resource_group_name,
110+
name=name,
111+
key_type=key_type,
112+
key_name=key_name,
113+
function_name=function_name,
114+
revision_name=revision_name,
115+
replica_name=replica_name,
116+
container_name=container_name
117+
)
118+
except Exception as e:
119+
handle_raw_exception(e)
120+
121+
122+
class ContainerAppFunctionKeysListDecorator(ContainerAppFunctionKeysDecorator):
123+
"""Decorator for listing function keys"""
124+
125+
def validate_list_arguments(self):
126+
"""Validate arguments required for listing function keys"""
127+
resource_group_name, name, revision_name, key_type, replica_name, container_name = self.validate_common_arguments()
128+
function_name = self.validate_function_name_requirement(key_type)
129+
130+
return resource_group_name, name, revision_name, key_type, function_name, replica_name, container_name
131+
132+
def list_keys(self):
133+
"""List keys based on key type"""
134+
try:
135+
resource_group_name, name, revision_name, key_type, function_name, replica_name, container_name = self.validate_list_arguments()
136+
137+
return self.client.list_function_keys(
138+
cmd=self.cmd,
139+
resource_group_name=resource_group_name,
140+
name=name,
141+
key_type=key_type,
142+
function_name=function_name,
143+
revision_name=revision_name,
144+
replica_name=replica_name,
145+
container_name=container_name
146+
)
147+
except Exception as e:
148+
handle_raw_exception(e)
149+
150+
151+
class ContainerAppFunctionKeysSetDecorator(ContainerAppFunctionKeysDecorator):
152+
"""Decorator for creating/updating function keys"""
153+
154+
def validate_set_arguments(self):
155+
"""Validate arguments required for setting/updating function keys"""
156+
resource_group_name, name, revision_name, key_type, replica_name, container_name = self.validate_common_arguments()
157+
key_name = self.get_argument_key_name()
158+
key_value = self.get_argument_key_value()
159+
function_name = self.validate_function_name_requirement(key_type)
160+
161+
if not key_name:
162+
raise ValidationError("Key name is required.")
163+
164+
return resource_group_name, name, revision_name, key_type, key_name, key_value, function_name, replica_name, container_name
165+
166+
def set_keys(self):
167+
"""Create/Update keys based on key type"""
168+
try:
169+
resource_group_name, name, revision_name, key_type, key_name, key_value, function_name, replica_name, container_name = self.validate_set_arguments()
170+
171+
return self.client.set_function_keys(
172+
cmd=self.cmd,
173+
resource_group_name=resource_group_name,
174+
name=name,
175+
key_type=key_type,
176+
key_name=key_name,
177+
key_value=key_value,
178+
function_name=function_name,
179+
revision_name=revision_name,
180+
replica_name=replica_name,
181+
container_name=container_name
182+
)
183+
except Exception as e:
184+
handle_raw_exception(e)

0 commit comments

Comments
 (0)