Skip to content

Commit

Permalink
[App Service] az appservice plan create: Fix #22332 (#22820)
Browse files Browse the repository at this point in the history
  • Loading branch information
StrawnSC authored Jun 28, 2022
1 parent 9e22165 commit bdf2a8f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
9 changes: 3 additions & 6 deletions src/azure-cli/azure/cli/command_modules/appservice/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ def load_arguments(self, _):
# PARAMETER REGISTRATION
name_arg_type = CLIArgumentType(options_list=['--name', '-n'], metavar='NAME')
sku_arg_type = CLIArgumentType(
help='The pricing tiers, e.g., F1(Free), D1(Shared), B1(Basic Small), B2(Basic Medium), B3(Basic Large), S1(Standard Small), P1V2(Premium V2 Small), P1V3(Premium V3 Small), P2V3(Premium V3 Medium), P3V3(Premium V3 Large), PC2 (Premium Container Small), PC3 (Premium Container Medium), PC4 (Premium Container Large), I1 (Isolated Small), I2 (Isolated Medium), I3 (Isolated Large), I1v2 (Isolated V2 Small), I2v2 (Isolated V2 Medium), I3v2 (Isolated V2 Large), WS1 (Logic Apps Workflow Standard 1), WS2 (Logic Apps Workflow Standard 2), WS3 (Logic Apps Workflow Standard 3)',
help='The pricing tiers, e.g., F1(Free), D1(Shared), B1(Basic Small), B2(Basic Medium), B3(Basic Large), S1(Standard Small), P1V2(Premium V2 Small), P1V3(Premium V3 Small), P2V3(Premium V3 Medium), P3V3(Premium V3 Large), I1 (Isolated Small), I2 (Isolated Medium), I3 (Isolated Large), I1v2 (Isolated V2 Small), I2v2 (Isolated V2 Medium), I3v2 (Isolated V2 Large), WS1 (Logic Apps Workflow Standard 1), WS2 (Logic Apps Workflow Standard 2), WS3 (Logic Apps Workflow Standard 3)',
arg_type=get_enum_type(
['F1', 'FREE', 'D1', 'SHARED', 'B1', 'B2', 'B3', 'S1', 'S2', 'S3', 'P1V2', 'P2V2', 'P3V2', 'P1V3', 'P2V3', 'P3V3', 'PC2', 'PC3',
'PC4', 'I1', 'I2', 'I3', 'I1v2', 'I2v2', 'I3v2', 'WS1', 'WS2', 'WS3']))
['F1', 'FREE', 'D1', 'SHARED', 'B1', 'B2', 'B3', 'S1', 'S2', 'S3', 'P1V2', 'P2V2', 'P3V2', 'P1V3', 'P2V3', 'P3V3', 'I1', 'I2', 'I3', 'I1v2', 'I2v2', 'I3v2', 'WS1', 'WS2', 'WS3']))
webapp_name_arg_type = CLIArgumentType(configured_default='web', options_list=['--name', '-n'], metavar='NAME',
completer=get_resource_name_completion_list('Microsoft.Web/sites'),
id_part='name',
Expand Down Expand Up @@ -786,9 +785,7 @@ def load_arguments(self, _):
c.argument('zone_redundant', options_list=['--zone-redundant', '-z'], help='Enable zone redundancy for high availability. Cannot be changed after plan creation. Minimum instance count is 3.')
c.argument('sku', required=True, help='The SKU of the app service plan. e.g., F1(Free), D1(Shared), B1(Basic Small), '
'B2(Basic Medium), B3(Basic Large), S1(Standard Small), '
'P1V2(Premium V2 Small), PC2 (Premium Container Small), PC3 '
'(Premium Container Medium), PC4 (Premium Container Large), I1 '
'(Isolated Small), I2 (Isolated Medium), I3 (Isolated Large), K1 '
'P1V2(Premium V2 Small), I1 (Isolated Small), I2 (Isolated Medium), I3 (Isolated Large), K1 '
'(Kubernetes).')

with self.argument_context('functionapp plan update') as c:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def _validate_ase_is_v3(ase):


def _validate_ase_not_ilb(ase):
if ase.internal_load_balancing_mode != 0:
if (ase.internal_load_balancing_mode != 0) and (ase.internal_load_balancing_mode != "None"):
raise ValidationError("Internal Load Balancer (ILB) App Service Environments not supported")


Expand Down
29 changes: 27 additions & 2 deletions src/azure-cli/azure/cli/command_modules/appservice/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1755,13 +1755,38 @@ def create_functionapp_slot(cmd, resource_group_name, name, slot, configuration_
return result


def _resolve_storage_account_resource_group(cmd, name):
from azure.cli.command_modules.storage.operations.account import list_storage_accounts
accounts = [a for a in list_storage_accounts(cmd) if a.name == name]
if accounts:
return parse_resource_id(accounts[0].id).get("resource_group")


def _set_site_config_storage_keys(cmd, site_config):
from azure.cli.command_modules.storage._client_factory import cf_sa_for_keys

for _, acct in site_config.azure_storage_accounts.items():
if acct.access_key is None:
scf = cf_sa_for_keys(cmd.cli_ctx, None)
acct_rg = _resolve_storage_account_resource_group(cmd, acct.account_name)
keys = scf.list_keys(acct_rg, acct.account_name, logging_enable=False).keys
if keys:
key = keys[0]
logger.info("Retreived key %s", key.key_name)
acct.access_key = key.value


def update_slot_configuration_from_source(cmd, client, resource_group_name, webapp, slot, configuration_source=None,
deployment_container_image_name=None, docker_registry_server_password=None,
docker_registry_server_user=None, docker_registry_server_url=None):

clone_from_prod = configuration_source.lower() == webapp.lower()
site_config = get_site_configs(cmd, resource_group_name, webapp,
None if clone_from_prod else configuration_source)
if site_config.azure_storage_accounts:
logger.warning("The configuration source has storage accounts. Looking up their access keys...")
_set_site_config_storage_keys(cmd, site_config)

_generic_site_operation(cmd.cli_ctx, resource_group_name, webapp,
'update_configuration', slot, site_config)

Expand Down Expand Up @@ -1896,8 +1921,6 @@ def create_app_service_plan(cmd, resource_group_name, name, is_linux, hyper_v, p

client = web_client_factory(cmd.cli_ctx)
if app_service_environment:
if hyper_v:
raise ArgumentUsageError('Windows containers is not yet supported in app service environment')
ase_list = client.app_service_environments.list()
ase_found = False
ase = None
Expand All @@ -1910,6 +1933,8 @@ def create_app_service_plan(cmd, resource_group_name, name, is_linux, hyper_v, p
if not ase_found:
err_msg = "App service environment '{}' not found in subscription.".format(app_service_environment)
raise ResourceNotFoundError(err_msg)
if hyper_v and ase.kind in ('ASEV1', 'ASEV2'):
raise ArgumentUsageError('Windows containers are only supported on v3 App Service Environments v3 or newer')
else: # Non-ASE
ase_def = None
if location is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2475,5 +2475,33 @@ def test_proxy_unsafe_ssl(self):
self.assertEqual(http.connection_pool_kw['cert_reqs'], 'CERT_NONE')


class WebappSlotTest(ScenarioTest):
@live_only() # Uses storage account keys, so must be live_only to not fail credscan
@ResourceGroupPreparer(location=LINUX_ASP_LOCATION_WEBAPP)
def test_slot_create_from_configuration_source(self, resource_group):
webapp_name = self.create_random_name(prefix='webapp-e2e', length=24)
plan = self.create_random_name(prefix='webapp-e2e-plan', length=24)
storage_account = self.create_random_name(prefix='storage', length=24)
container = self.create_random_name(prefix='container', length=24)
store_id = "store"
store_type = "AzureBlob"

self.cmd(f'appservice plan create -g {resource_group} -n {plan} --sku S1 --is-linux')
self.cmd(f'webapp create -g {resource_group} -n {webapp_name} --plan {plan} --runtime "python|3.9"')
self.cmd(f'storage account create -n {storage_account} -g {resource_group} --location {LINUX_ASP_LOCATION_WEBAPP}')
self.cmd(f"storage container create -n {container} -g {resource_group} --account-name {storage_account}")
key = self.cmd(f"storage account keys list -n {storage_account}").get_output_in_json()[0]["value"]
self.cmd(f'webapp config storage-account add -g {resource_group} -n {webapp_name} -k {key} -a {storage_account} -i {store_id} --sn {container} -t {store_type}')

self.cmd(f'webapp deployment slot create -g {resource_group} -n {webapp_name} -s "slot" --configuration-source {webapp_name}')

self.cmd(f'webapp show -g {resource_group} -n {webapp_name} -s "slot"', checks=[
JMESPathCheck(f"siteConfig.azureStorageAccounts.{store_id}.accessKey", None),
JMESPathCheck(f"siteConfig.azureStorageAccounts.{store_id}.accountName", storage_account),
JMESPathCheck(f"siteConfig.azureStorageAccounts.{store_id}.state", "Ok"),
JMESPathCheck(f"siteConfig.azureStorageAccounts.{store_id}.type", store_type),
])


if __name__ == '__main__':
unittest.main()

0 comments on commit bdf2a8f

Please sign in to comment.