Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions src/containerapp/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ upcoming
++++++
* Removed preview tag for some command groups and params (e.g. 'az containerapp job', 'az containerapp env storage', 'az containerapp env workload-profile')
* 'az containerapp env': --enable-workload-profiles allowed values:true, false
* 'az containerapp auth': support --token-store, --sas-url-secret, --sas-url-secret-name, --yes

0.3.37
++++++
Expand Down
2 changes: 2 additions & 0 deletions src/containerapp/azext_containerapp/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
SUCCEEDED_STATUS = "Succeeded"
UPDATING_STATUS = "Updating"

BLOB_STORAGE_TOKEN_STORE_SECRET_SETTING_NAME = "blob-storage-token-store-sasurl-secret"

MICROSOFT_SECRET_SETTING_NAME = "microsoft-provider-authentication-secret"
FACEBOOK_SECRET_SETTING_NAME = "facebook-provider-authentication-secret"
GITHUB_SECRET_SETTING_NAME = "github-provider-authentication-secret"
Expand Down
4 changes: 4 additions & 0 deletions src/containerapp/azext_containerapp/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ def load_arguments(self, _):
c.argument('consumer_secret_setting_name', options_list=['--consumer-secret-name', '--secret-name'], help='The consumer secret name that contains the app secret.')
c.argument('provider_name', required=True, help='The name of the custom OpenID Connect provider.')
c.argument('openid_configuration', help='The endpoint that contains all the configuration endpoints for the provider.')
c.argument('token_store', arg_type=get_three_state_flag(), help='Boolean indicating if token store is enabled for the app.')
c.argument('sas_url_secret', help='The blob storage SAS URL to be used for token store.')
c.argument('sas_url_secret_name', help='The secret name that contains blob storage SAS URL to be used for token store.')

# auth update
c.argument('set_string', options_list=['--set'], help='Value of a specific field within the configuration settings for the Azure App Service Authentication / Authorization feature.')
c.argument('config_file_path', help='The path of the config file containing auth settings if they come from a file.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

from ._client_factory import handle_raw_exception
from .base_resource import BaseResource
from ._constants import BLOB_STORAGE_TOKEN_STORE_SECRET_SETTING_NAME
from ._utils import safe_set
from knack.prompting import prompt_y_n
from azure.cli.core.azclierror import ArgumentUsageError


class ContainerAppAuthDecorator(BaseResource):
Expand Down Expand Up @@ -116,3 +120,40 @@ def get_argument_excluded_paths(self):
class ContainerAppPreviewAuthDecorator(ContainerAppAuthDecorator):
def construct_payload(self):
super().construct_payload()
self.set_up_token_store()

def set_up_token_store(self):
if self.get_argument_token_store() is None:
return

if self.get_argument_token_store() is False:
safe_set(self.existing_auth, "login", "tokenStore", "enabled", value=False)
return

safe_set(self.existing_auth, "login", "tokenStore", "enabled", value=True)

if self.get_argument_sas_url_secret() is None and self.get_argument_sas_url_secret_name() is None:
raise ArgumentUsageError('Usage Error: only blob storage token store is supported. --sas-url-secret and --sas-url-secret-name should provide exactly one when token store is enabled')
if self.get_argument_sas_url_secret() is not None and self.get_argument_sas_url_secret_name() is not None:
raise ArgumentUsageError('Usage Error: --sas-url-secret and --sas-url-secret-name cannot both be set')
if self.get_argument_sas_url_secret() is not None and not self.get_argument_yes():
msg = 'Configuring --sas-url-secret will add a secret to the containerapp. Are you sure you want to continue?'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it required to add prompt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if yes parameter is not passed, there is prompt to let user confirm it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same behavior as others. For example: az containerapp microsoft update xxx

if not prompt_y_n(msg, default="n"):
raise ArgumentUsageError('Usage Error: --sas-url-secret cannot be used without agreeing to add secret to the containerapp.')

sas_url_setting_name = BLOB_STORAGE_TOKEN_STORE_SECRET_SETTING_NAME
if self.get_argument_sas_url_secret_name() is not None:
sas_url_setting_name = self.get_argument_sas_url_secret_name()
safe_set(self.existing_auth, "login", "tokenStore", "azureBlobStorage", "sasUrlSettingName", value=sas_url_setting_name)

def get_argument_token_store(self):
return self.get_param("token_store")

def get_argument_sas_url_secret(self):
return self.get_param("sas_url_secret")

def get_argument_sas_url_secret_name(self):
return self.get_param("sas_url_secret_name")

def get_argument_yes(self):
return self.get_param("yes")
9 changes: 7 additions & 2 deletions src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@
NAME_INVALID, NAME_ALREADY_EXISTS, ACR_IMAGE_SUFFIX, HELLO_WORLD_IMAGE, LOG_TYPE_SYSTEM, LOG_TYPE_CONSOLE,
MANAGED_CERTIFICATE_RT, PRIVATE_CERTIFICATE_RT, PENDING_STATUS, SUCCEEDED_STATUS, DEV_POSTGRES_IMAGE, DEV_POSTGRES_SERVICE_TYPE,
DEV_POSTGRES_CONTAINER_NAME, DEV_REDIS_IMAGE, DEV_REDIS_SERVICE_TYPE, DEV_REDIS_CONTAINER_NAME, DEV_KAFKA_CONTAINER_NAME,
DEV_KAFKA_IMAGE, DEV_KAFKA_SERVICE_TYPE, DEV_MARIADB_CONTAINER_NAME, DEV_MARIADB_IMAGE, DEV_MARIADB_SERVICE_TYPE, DEV_SERVICE_LIST, CONTAINER_APPS_SDK_MODELS)
DEV_KAFKA_IMAGE, DEV_KAFKA_SERVICE_TYPE, DEV_MARIADB_CONTAINER_NAME, DEV_MARIADB_IMAGE, DEV_MARIADB_SERVICE_TYPE, DEV_SERVICE_LIST,
CONTAINER_APPS_SDK_MODELS, BLOB_STORAGE_TOKEN_STORE_SECRET_SETTING_NAME)

logger = get_logger(__name__)

Expand Down Expand Up @@ -5036,7 +5037,9 @@ def update_auth_config(cmd, resource_group_name, name, set_string=None, enabled=
runtime_version=None, config_file_path=None, unauthenticated_client_action=None,
redirect_provider=None, require_https=None,
proxy_convention=None, proxy_custom_host_header=None,
proxy_custom_proto_header=None, excluded_paths=None):
proxy_custom_proto_header=None, excluded_paths=None,
token_store=None, sas_url_secret=None, sas_url_secret_name=None,
yes=False):
raw_parameters = locals()
containerapp_auth_decorator = ContainerAppPreviewAuthDecorator(
cmd=cmd,
Expand All @@ -5046,6 +5049,8 @@ def update_auth_config(cmd, resource_group_name, name, set_string=None, enabled=
)

containerapp_auth_decorator.construct_payload()
if containerapp_auth_decorator.get_argument_token_store() and containerapp_auth_decorator.get_argument_sas_url_secret() is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not add it in construct_payload()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_secrets func is defined in this file, to avoid dependency loop, so place the logic here

Copy link
Contributor

@Greedygre Greedygre Aug 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Juliehzl
g.custom_command('set', 'set_secrets', exception_handler=ex_handler_factory())
1. set_secrets is a function support command
2. set_secrets will execute ContainerAppClient.create_or_update, I think if it add in construct_payload, maybe will execute twice in some scenario. It should be set in some place which not super() the GA function.

set_secrets(cmd, name, resource_group_name, secrets=[f"{BLOB_STORAGE_TOKEN_STORE_SECRET_SETTING_NAME}={containerapp_auth_decorator.get_argument_sas_url_secret()}"], no_wait=True, disable_max_length=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combine the method to depcorator to avoid duplicate usage when moving to GA and refine the logic to be same with facbook/microsoft... commands

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do it in next PR.

return containerapp_auth_decorator.create_or_update()


Expand Down
Loading