Skip to content
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

Added FileShare commands. #84

Merged
merged 9 commits into from
May 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
Added FileShare commands.
  • Loading branch information
Haroon Feisal committed May 3, 2022
commit 708f3106657aadb4e41c7afb092038db2ead2b2c
118 changes: 118 additions & 0 deletions src/containerapp/azext_containerapp/_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,3 +784,121 @@ def list(cls, cmd, resource_group_name, environment_name, formatter=lambda x: x)
app_list.append(formatted)

return app_list


class StorageClient():
@classmethod
def create_or_update(cls, cmd, resource_group_name, env_name, name, storage_envelope, no_wait=False):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = STABLE_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/managedEnvironments/{}/storages/{}?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
env_name,
name,
api_version)

r = send_raw_request(cmd.cli_ctx, "PUT", request_url, body=json.dumps(storage_envelope))

if no_wait:
return r.json()
elif r.status_code == 201:
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/managedEnvironments/{}/storages/{}?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
env_name,
name,
api_version)
return poll(cmd, request_url, "waiting")

return r.json()

@classmethod
def delete(cls, cmd, resource_group_name, env_name, name, no_wait=False):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = STABLE_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/managedEnvironments/{}/storages/{}?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
env_name,
name,
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]:
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/managedEnvironments/{}/storages/{}?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
env_name,
name,
api_version)

if r.status_code == 202:
from azure.cli.core.azclierror import ResourceNotFoundError
try:
poll(cmd, request_url, "scheduledfordelete")
except ResourceNotFoundError:
pass
logger.warning('Containerapp environment successfully deleted')
return

@classmethod
def show(cls, cmd, resource_group_name, env_name, name):
management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = STABLE_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/managedEnvironments/{}/storages/{}?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
env_name,
name,
api_version)

r = send_raw_request(cmd.cli_ctx, "GET", request_url)
return r.json()

@classmethod
def list(cls, cmd, resource_group_name, env_name, formatter=lambda x: x):
env_list = []

management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager
api_version = STABLE_API_VERSION
sub_id = get_subscription_id(cmd.cli_ctx)
url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/managedEnvironments/{}/storages?api-version={}"
request_url = url_fmt.format(
management_hostname.strip('/'),
sub_id,
resource_group_name,
env_name,
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
7 changes: 7 additions & 0 deletions src/containerapp/azext_containerapp/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,10 @@
"tenantId": None, # str
"subscriptionId": None # str
}

AzureFileProperties = {
"accountName": None,
"accountKey": None,
"accessMode": None,
"shareName": None
}
runefa marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long, too-many-statements, consider-using-f-string

from wsgiref.validate import validator
from knack.arguments import CLIArgumentType

from azure.cli.core.commands.parameters import (resource_group_name_type, get_location_type,
Expand Down Expand Up @@ -147,6 +148,11 @@ def load_arguments(self, _):
with self.argument_context('containerapp env show') as c:
c.argument('name', name_type, help='Name of the Container Apps Environment.')

with self.argument_context('containerapp env storage') as c:
c.argument('managed_env', options_list=['--environment'], help="Name or resource ID of the container app's environment.", validator = None)
c.argument('name', id_part=None)
c.argument('access_mode', id_part=None, arg_type=get_enum_type(["ReadWrite", "ReadOnly"]))

with self.argument_context('containerapp identity') as c:
c.argument('user_assigned', nargs='+', help="Space-separated user identities.")
c.argument('system_assigned', help="Boolean indicating whether to assign system-assigned identity.")
Expand Down
6 changes: 6 additions & 0 deletions src/containerapp/azext_containerapp/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ def load_command_table(self, _):
g.custom_command('set', 'create_or_update_dapr_component')
g.custom_command('remove', 'remove_dapr_component')

with self.command_group('containerapp env storage') as g:
g.custom_show_command('show', 'show_storage')
g.custom_command('list', 'list_storage')
g.custom_command('set', 'create_or_update_storage', supports_no_wait=True, exception_handler=ex_handler_factory())
g.custom_command('remove', 'remove_storage', supports_no_wait=True, confirmation=True, exception_handler=ex_handler_factory())

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())
Expand Down
48 changes: 47 additions & 1 deletion src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long, consider-using-f-string, logging-format-interpolation, inconsistent-return-statements, broad-except, bare-except, too-many-statements, too-many-locals, too-many-boolean-expressions, too-many-branches, too-many-nested-blocks, pointless-statement, expression-not-assigned, unbalanced-tuple-unpacking

from os import access
import threading
import sys
import time
Expand All @@ -25,7 +26,7 @@
from msrest.exceptions import DeserializationError

from ._client_factory import handle_raw_exception
from ._clients import ManagedEnvironmentClient, ContainerAppClient, GitHubActionClient, DaprComponentClient
from ._clients import ManagedEnvironmentClient, ContainerAppClient, GitHubActionClient, DaprComponentClient, StorageClient
from ._github_oauth import get_github_access_token
from ._models import (
ManagedEnvironment as ManagedEnvironmentModel,
Expand Down Expand Up @@ -2201,3 +2202,48 @@ def containerapp_up_logic(cmd, resource_group_name, name, managed_env, image, en
return ContainerAppClient.create_or_update(cmd, resource_group_name, name, containerapp_def)
except Exception as e:
handle_raw_exception(e)


def show_storage(cmd, name, managed_env, resource_group_name):
_validate_subscription_registered(cmd, "Microsoft.App")

try:
return StorageClient.show(cmd, resource_group_name, managed_env, name)
except CLIError as e:
handle_raw_exception(e)

def list_storage(cmd, managed_env, resource_group_name):
_validate_subscription_registered(cmd, "Microsoft.App")

try:
return StorageClient.list(cmd, resource_group_name, managed_env)
except CLIError as e:
handle_raw_exception(e)

def create_or_update_storage(cmd, name, resource_group_name, managed_env, account_name, share_name, account_key, access_mode, type="AzureFile", no_wait=False):
_validate_subscription_registered(cmd, "Microsoft.App")
from ._models import AzureFileProperties as AzureFilePropertiesModel
if type.lower() != "azurefile":
raise ValidationError("Only AzureFile type is supported at this time.")

storage_def = AzureFilePropertiesModel
storage_def["accountKey"] = account_key
storage_def["accountName"] = account_name
storage_def["shareName"] = share_name
storage_def["accessMode"] = access_mode
storage_envelope = {}
storage_envelope["properties"] = {}
storage_envelope["properties"]["azureFile"] = storage_def

try:
return StorageClient.create_or_update(cmd, resource_group_name, managed_env, name, storage_envelope, no_wait)
except CLIError as e:
handle_raw_exception(e)

def remove_storage(cmd, name, managed_env, resource_group_name, no_wait=False):
_validate_subscription_registered(cmd, "Microsoft.App")

try:
return StorageClient.delete(cmd, resource_group_name, managed_env, name, no_wait)
except CLIError as e:
handle_raw_exception(e)