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
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def load_arguments(self, _):
help='get regions which support hosting web apps on Windows Container workers')
c.argument('linux_workers_enabled', action='store_true',
help='get regions which support hosting web apps on Linux workers')
c.argument('managed_instance_enabled', action='store_true', is_preview=True,
help='get regions which support hosting web apps on Managed Instance workers')
c.argument('sku', arg_type=sku_arg_type)

with self.argument_context('appservice plan') as c:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
# flake8: noqa

from .__cmd_group import *
from ._list_locations import *
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#
# Code generated by aaz-dev-tools
# --------------------------------------------------------------------------------------------

# pylint: skip-file
# flake8: noqa

from azure.cli.core.aaz import *


class ListLocations(AAZCommand):
"""List regions where a plan sku is available
"""

_aaz_info = {
"version": "2025-03-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/providers/microsoft.web/georegions", "2025-03-01"],
]
}

AZ_SUPPORT_PAGINATION = True

def _handler(self, command_args):
super()._handler(command_args)
return self.build_paging(self._execute_operations, self._output)

_args_schema = None

@classmethod
def _build_arguments_schema(cls, *args, **kwargs):
if cls._args_schema is not None:
return cls._args_schema
cls._args_schema = super()._build_arguments_schema(*args, **kwargs)

# define Arg Group ""

_args_schema = cls._args_schema
_args_schema.custom_mode_workers_enabled = AAZBoolArg(
options=["--custom-mode-workers-enabled"],
help="Specify true if you want to filter to only regions that support App Service Plans with IsCustomMode set to true.",
)
_args_schema.linux_dynamic_workers_enabled = AAZBoolArg(
options=["--linux-dynamic-workers-enabled"],
help="Specify true if you want to filter to only regions that support Linux Consumption Workers.",
)
_args_schema.linux_workers_enabled = AAZBoolArg(
options=["--linux-workers-enabled"],
help="Get regions which support hosting web apps on Linux workers.",
)
_args_schema.sku = AAZStrArg(
options=["--sku"],
help="Name of SKU used to filter the regions.",
enum={"Basic": "Basic", "Dynamic": "Dynamic", "ElasticIsolated": "ElasticIsolated", "ElasticPremium": "ElasticPremium", "FlexConsumption": "FlexConsumption", "Free": "Free", "Isolated": "Isolated", "IsolatedV2": "IsolatedV2", "Premium": "Premium", "PremiumContainer": "PremiumContainer", "PremiumV2": "PremiumV2", "PremiumV3": "PremiumV3", "Shared": "Shared", "Standard": "Standard"},
)
_args_schema.hyperv_workers_enabled = AAZBoolArg(
options=["--hyperv-workers-enabled"],
help="Get regions which support hosting web apps on Windows Container workers.",
)
return cls._args_schema

def _execute_operations(self):
self.pre_operations()
self.ListGeoRegions(ctx=self.ctx)()
self.post_operations()

@register_callback
def pre_operations(self):
pass

@register_callback
def post_operations(self):
pass

def _output(self, *args, **kwargs):
result = self.deserialize_output(self.ctx.vars.instance.value, client_flatten=True)
next_link = self.deserialize_output(self.ctx.vars.instance.next_link)
return result, next_link

class ListGeoRegions(AAZHttpOperation):
CLIENT_TYPE = "MgmtClient"

def __call__(self, *args, **kwargs):
request = self.make_request()
session = self.client.send_request(request=request, stream=False, **kwargs)
if session.http_response.status_code in [200]:
return self.on_200(session)

return self.on_error(session.http_response)

@property
def url(self):
return self.client.format_url(
"/subscriptions/{subscriptionId}/providers/Microsoft.Web/geoRegions",
**self.url_parameters
)

@property
def method(self):
return "GET"

@property
def error_format(self):
return "ODataV4Format"

@property
def url_parameters(self):
parameters = {
**self.serialize_url_param(
"subscriptionId", self.ctx.subscription_id,
required=True,
),
}
return parameters

@property
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"customModeWorkersEnabled", self.ctx.args.custom_mode_workers_enabled,
),
**self.serialize_query_param(
"linuxDynamicWorkersEnabled", self.ctx.args.linux_dynamic_workers_enabled,
),
**self.serialize_query_param(
"linuxWorkersEnabled", self.ctx.args.linux_workers_enabled,
),
**self.serialize_query_param(
"sku", self.ctx.args.sku,
),
**self.serialize_query_param(
"xenonWorkersEnabled", self.ctx.args.hyperv_workers_enabled,
),
**self.serialize_query_param(
"api-version", "2025-03-01",
required=True,
),
}
return parameters

@property
def header_parameters(self):
parameters = {
**self.serialize_header_param(
"Accept", "application/json",
),
}
return parameters

def on_200(self, session):
data = self.deserialize_http_content(session)
self.ctx.set_var(
"instance",
data,
schema_builder=self._build_schema_on_200
)

_schema_on_200 = None

@classmethod
def _build_schema_on_200(cls):
if cls._schema_on_200 is not None:
return cls._schema_on_200

cls._schema_on_200 = AAZObjectType()

_schema_on_200 = cls._schema_on_200
_schema_on_200.next_link = AAZStrType(
serialized_name="nextLink",
flags={"read_only": True},
)
_schema_on_200.value = AAZListType(
flags={"required": True},
)

value = cls._schema_on_200.value
value.Element = AAZObjectType()

_element = cls._schema_on_200.value.Element
_element.id = AAZStrType(
flags={"read_only": True},
)
_element.kind = AAZStrType()
_element.name = AAZStrType(
flags={"read_only": True},
)
_element.properties = AAZObjectType(
flags={"client_flatten": True},
)
_element.type = AAZStrType(
flags={"read_only": True},
)

properties = cls._schema_on_200.value.Element.properties
properties.description = AAZStrType(
flags={"read_only": True},
)
properties.display_name = AAZStrType(
serialized_name="displayName",
flags={"read_only": True},
)
properties.org_domain = AAZStrType(
serialized_name="orgDomain",
flags={"read_only": True},
)

return cls._schema_on_200


class _ListLocationsHelper:
"""Helper class for ListLocations"""


__all__ = ["ListLocations"]
35 changes: 29 additions & 6 deletions src/azure-cli/azure/cli/command_modules/appservice/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
get_resource_if_exists, repo_url_to_name, get_token,
app_service_plan_exists, is_centauri_functionapp, is_flex_functionapp,
_remove_list_duplicates, get_raw_functionapp,
register_app_provider)
register_app_provider,
is_sku_tier_enabled_for_managed_instance)
from ._create_util import (zip_contents_from_dir, get_runtime_version_details, create_resource_group, get_app_details,
check_resource_group_exists, set_location, get_site_availability,
get_regional_site_availability, get_profile_username,
Expand All @@ -100,6 +101,7 @@
from .aaz.latest.relay.hyco.authorization_rule import List as HycoAuthoList, Create as HycoAuthoCreate
from .aaz.latest.relay.hyco.authorization_rule.keys import List as HycoAuthoKeysList
from .aaz.latest.relay.namespace import List as NamespaceList
from .aaz.latest.appservice import ListLocations as AppServiceListLocations
from .aaz.latest.appservice.plan import (Show as AppServicePlanShow, Create as AppServicePlanCreate,
Update as AppServicePlanUpdate)
from .aaz.latest.appservice.plan.managed_instance import (ShowRdpPassword
Expand Down Expand Up @@ -8125,13 +8127,18 @@ def list_flexconsumption_zone_redundant_locations(cmd):
return [{'name': x.name.lower().replace(' ', '')} for x in regions]


def list_locations(cmd, sku, linux_workers_enabled=None, hyperv_workers_enabled=None):
def list_locations(cmd, sku, linux_workers_enabled=None, hyperv_workers_enabled=None, managed_instance_enabled=None):
web_client = web_client_factory(cmd.cli_ctx)
full_sku = get_sku_tier(sku)
# Temporary fix due to regression in this specific API with 2021-03-01, should be removed with the next SDK update
web_client_geo_regions = web_client.list_geo_regions(sku=full_sku,
linux_workers_enabled=linux_workers_enabled,
xenon_workers_enabled=hyperv_workers_enabled)

if managed_instance_enabled:
# managed_instance_enabled needs to be specially handled due to requiring version 2025-03-01
# and due to additional validation needed for SKU
web_client_geo_regions = _list_managed_instance_locations(cmd, full_sku)
else:
web_client_geo_regions = web_client.list_geo_regions(sku=full_sku,
linux_workers_enabled=linux_workers_enabled,
xenon_workers_enabled=hyperv_workers_enabled)

providers_client = providers_client_factory(cmd.cli_ctx)
providers_client_locations_list = getattr(providers_client.get('Microsoft.Web'), 'resource_types', [])
Expand All @@ -8143,6 +8150,22 @@ def list_locations(cmd, sku, linux_workers_enabled=None, hyperv_workers_enabled=
return [geo_region for geo_region in web_client_geo_regions if geo_region.name in providers_client_locations_list]


def _list_managed_instance_locations(cmd, sku_tier):
from types import SimpleNamespace

if not is_sku_tier_enabled_for_managed_instance(sku_tier):
return []

# SKU is validated separately above and not passed into API call
# due to how the API handles SKU for managed instance
list_locations_cmd = AppServiceListLocations(cli_ctx=cmd.cli_ctx)
locations = list_locations_cmd(command_args={
'custom_mode_workers_enabled': True
})

return [SimpleNamespace(**location) for location in locations]


def _check_zip_deployment_status(cmd, rg_name, name, deployment_status_url, slot, timeout=None):
import requests
from azure.cli.core.util import should_disable_connection_verify
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
---
# exclusions for the vm module

appservice list-locations:
parameters:
managed_instance_enabled:
rule_exclusions:
- option_length_too_long
appservice plan managed-instance instance connect:
rule_exclusions:
- missing_command_test_coverage
Expand Down
Loading