From 3e7d8a6aa7d46e0d21ef156201167f6d5dea4ec6 Mon Sep 17 00:00:00 2001 From: Yuwei Zhou Date: Wed, 22 Dec 2021 18:04:10 +0800 Subject: [PATCH 1/5] add spring-cloud create --sku Enterprise --- .../azext_spring_cloud/_enterprise.py | 23 +++++++ src/spring-cloud/azext_spring_cloud/_help.py | 7 +- .../azext_spring_cloud/_params.py | 3 +- .../azext_spring_cloud/_util_enterprise.py | 18 ++++++ src/spring-cloud/azext_spring_cloud/_utils.py | 18 +++++- .../azext_spring_cloud/_validators.py | 52 ++++++++++++--- .../azext_spring_cloud/commands.py | 11 +++- src/spring-cloud/azext_spring_cloud/custom.py | 42 +++++++----- .../tests/latest/test_asc_validator.py | 51 ++++++++++++++- .../tier_routing_spring_cloud.py | 64 +++++++++++++++++++ 10 files changed, 260 insertions(+), 29 deletions(-) create mode 100644 src/spring-cloud/azext_spring_cloud/_enterprise.py create mode 100644 src/spring-cloud/azext_spring_cloud/_util_enterprise.py create mode 100644 src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py diff --git a/src/spring-cloud/azext_spring_cloud/_enterprise.py b/src/spring-cloud/azext_spring_cloud/_enterprise.py new file mode 100644 index 00000000000..c694538c72c --- /dev/null +++ b/src/spring-cloud/azext_spring_cloud/_enterprise.py @@ -0,0 +1,23 @@ +from knack.log import get_logger +from .custom import (_create_service) + + +logger = get_logger(__name__) + + +def spring_cloud_create(cmd, client, resource_group, name, location=None, + vnet=None, service_runtime_subnet=None, app_subnet=None, reserved_cidr_range=None, + service_runtime_network_resource_group=None, app_network_resource_group=None, + app_insights_key=None, app_insights=None, sampling_rate=None, + disable_app_insights=None, enable_java_agent=None, + sku=None, tags=None, no_wait=False): + poller = _create_service(cmd, client, resource_group, name, + location=location, + service_runtime_subnet=service_runtime_subnet, + app_subnet=app_subnet, + reserved_cidr_range=reserved_cidr_range, + service_runtime_network_resource_group=service_runtime_network_resource_group, + app_network_resource_group=app_network_resource_group, + sku=sku, + tags=tags) + return poller diff --git a/src/spring-cloud/azext_spring_cloud/_help.py b/src/spring-cloud/azext_spring_cloud/_help.py index 7195cf9432b..a2a79194270 100644 --- a/src/spring-cloud/azext_spring_cloud/_help.py +++ b/src/spring-cloud/azext_spring_cloud/_help.py @@ -29,6 +29,11 @@ text: az spring-cloud create -n MyService -g MyResourceGroup --vnet MyVNet --app-subnet MyAppSubnet --service-runtime-subnet MyServiceRuntimeSubnet - name: Create a new Azure Spring Cloud with VNet-injected via giving subnets resource ID text: az spring-cloud create -n MyService -g MyResourceGroup --app-subnet /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyVnetRg/providers/Microsoft.Network/VirtualNetworks/test-vnet/subnets/app --service-runtime-subnet /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyVnetRg/providers/Microsoft.Network/VirtualNetworks/test-vnet/subnets/svc --reserved-cidr-range 10.0.0.0/16,10.1.0.0/16,10.2.0.1/16 + - name: Create a Azure Spring Cloud Enterprise instance if the Azure Subscription never hosts Azure Spring Cloud Enterprise instance + text: | + az provider register -n Microsoft.SaaS + az term accept --publisher vmware-inc --product azure-spring-cloud-vmware-tanzu-2 --plan tanzu-asc-ent-mtr + az spring-cloud create -n MyService -g MyResourceGroup --sku Enterprise """ helps['spring-cloud update'] = """ @@ -352,7 +357,7 @@ helps['spring-cloud config-server'] = """ type: group - short-summary: Commands to manage Config Server in Azure Spring Cloud. + short-summary: (Support Standard Tier and Basic Tier) Commands to manage Config Server in Azure Spring Cloud. """ helps['spring-cloud config-server show'] = """ diff --git a/src/spring-cloud/azext_spring_cloud/_params.py b/src/spring-cloud/azext_spring_cloud/_params.py index 7bcf861d5e7..acfa7da547b 100644 --- a/src/spring-cloud/azext_spring_cloud/_params.py +++ b/src/spring-cloud/azext_spring_cloud/_params.py @@ -40,6 +40,7 @@ def load_arguments(self, _): # https://dev.azure.com/msazure/AzureDMSS/_workitems/edit/11002857/ with self.argument_context('spring-cloud create') as c: c.argument('location', arg_type=get_location_type(self.cli_ctx), validator=validate_location) + c.argument('sku', arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, default='Standard', help='Name of SKU. Enterprise is still in Preview.') c.argument('reserved_cidr_range', help='Comma-separated list of IP address ranges in CIDR format. The IP ranges are reserved to host underlying Azure Spring Cloud infrastructure, which should be 3 at least /16 unused IP ranges, must not overlap with any Subnet IP ranges.', validator=validate_vnet_required_parameters) c.argument('vnet', help='The name or ID of an existing Virtual Network into which to deploy the Spring Cloud instance.', validator=validate_vnet_required_parameters) c.argument('app_subnet', help='The name or ID of an existing subnet in "vnet" into which to deploy the Spring Cloud app. Required when deploying into a Virtual Network. Smaller subnet sizes are supported, please refer: https://aka.ms/azure-spring-cloud-smaller-subnet-vnet-docs', validator=validate_vnet_required_parameters) @@ -72,6 +73,7 @@ def load_arguments(self, _): validator=validate_tracing_parameters_asc_create) with self.argument_context('spring-cloud update') as c: + c.argument('sku', arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, help='Name of SKU. Enterprise is still in Preview.') c.argument('app_insights_key', help="Connection string (recommended) or Instrumentation key of the existing Application Insights.", validator=validate_tracing_parameters_asc_update, @@ -98,7 +100,6 @@ def load_arguments(self, _): for scope in ['spring-cloud create', 'spring-cloud update']: with self.argument_context(scope) as c: - c.argument('sku', type=str, validator=validate_sku, help='Name of SKU, the value is "Basic" or "Standard"') c.argument('tags', arg_type=tags_type) with self.argument_context('spring-cloud test-endpoint renew-key') as c: diff --git a/src/spring-cloud/azext_spring_cloud/_util_enterprise.py b/src/spring-cloud/azext_spring_cloud/_util_enterprise.py new file mode 100644 index 00000000000..c735dccb947 --- /dev/null +++ b/src/spring-cloud/azext_spring_cloud/_util_enterprise.py @@ -0,0 +1,18 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=wrong-import-order + +from .vendored_sdks.appplatform.v2022_01_01_preview import AppPlatformManagementClient +from azure.cli.core.commands.client_factory import get_mgmt_service_client + + +def is_enterprise_tier(cmd, resource_group, name): + resource = get_client(cmd).services.get(resource_group, name) + return resource.sku.name == 'E0' + + +def get_client(cmd): + return get_mgmt_service_client(cmd.cli_ctx, AppPlatformManagementClient) diff --git a/src/spring-cloud/azext_spring_cloud/_utils.py b/src/spring-cloud/azext_spring_cloud/_utils.py index ce1a31a35f7..84158f7b2ff 100644 --- a/src/spring-cloud/azext_spring_cloud/_utils.py +++ b/src/spring-cloud/azext_spring_cloud/_utils.py @@ -5,6 +5,7 @@ import json from enum import Enum import os +from time import sleep import codecs import tarfile import tempfile @@ -222,6 +223,8 @@ def _get_sku_name(tier): # pylint: disable=too-many-return-statements return 'B0' if tier == 'STANDARD': return 'S0' + if tier == 'ENTERPRISE': + return 'E0' raise CLIError("Invalid sku(pricing tier), please refer to command help for valid values") @@ -231,6 +234,8 @@ def _get_persistent_disk_size(tier): # pylint: disable=too-many-return-statemen return 1 if tier == 'STANDARD': return 50 + if tier == 'ENTERPRISE': + return 50 return 50 @@ -243,11 +248,22 @@ def get_portal_uri(cli_ctx): return 'https://portal.azure.com' +def wait_till_end(cmd, *pollers): + if not pollers: + return + progress_bar = cmd.cli_ctx.get_progress_controller() + progress_bar.add(message='Running') + progress_bar.begin() + while any(x and not x.done() for x in pollers): + progress_bar.add(message='Running') + sleep(5) + + def handle_asc_exception(ex): try: raise CLIError(ex.inner_exception.error.message) except AttributeError: - if hasattr(ex, 'response'): + if hasattr(ex, 'response') and ex.response.internal_response.text: response_dict = json.loads(ex.response.internal_response.text) raise CLIError(response_dict["error"]["message"]) else: diff --git a/src/spring-cloud/azext_spring_cloud/_validators.py b/src/spring-cloud/azext_spring_cloud/_validators.py index cc8b261edd9..8b11d1be38e 100644 --- a/src/spring-cloud/azext_spring_cloud/_validators.py +++ b/src/spring-cloud/azext_spring_cloud/_validators.py @@ -13,13 +13,13 @@ from azure.cli.core.commands.client_factory import get_subscription_id from azure.cli.core.commands.validators import validate_tag from azure.cli.core.azclierror import InvalidArgumentValueError -from ._utils import _get_file_type +from knack.validators import DefaultStr from azure.mgmt.core.tools import is_valid_resource_id from azure.mgmt.core.tools import parse_resource_id from azure.mgmt.core.tools import resource_id from knack.log import get_logger -from ._utils import ApiType -from ._utils import _get_rg_location +from ._utils import (ApiType, _get_rg_location, _get_file_type, _get_sku_name) +from .vendored_sdks.appplatform.v2020_07_01 import models logger = get_logger(__name__) @@ -40,11 +40,37 @@ def validate_location(namespace): for piece in location_slice]) -def validate_sku(namespace): - if namespace.sku is not None: - namespace.sku = namespace.sku.upper() - if namespace.sku not in ['BASIC', 'STANDARD']: - raise InvalidArgumentValueError("The pricing tier only accepts value [Basic, Standard]") +def validate_sku(cmd, namespace): + if not namespace.sku: + return + if namespace.sku.lower() == 'enterprise': + _validate_saas_provider(cmd, namespace) + _validate_terms(cmd, namespace) + namespace.sku = models.Sku(name=_get_sku_name(namespace.sku), tier=namespace.sku) + + +def _validate_saas_provider(cmd, namespace): + from azure.cli.core.commands.client_factory import get_mgmt_service_client + from azure.cli.core.profiles import ResourceType + client = get_mgmt_service_client(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES).providers + if client.get('Microsoft.SaaS').registration_state != 'Registered': + raise InvalidArgumentValueError('Microsoft.SaaS resource provider is not registered.\n' + 'Run "az provider register -n Microsoft.SaaS" to register.') + + +def _validate_terms(cmd, namespace): + from azure.mgmt.marketplaceordering import MarketplaceOrderingAgreements + from azure.cli.core.commands.client_factory import get_mgmt_service_client + client = get_mgmt_service_client(cmd.cli_ctx, MarketplaceOrderingAgreements).marketplace_agreements + term = client.get(offer_type="virtualmachine", + publisher_id='vmware-inc', + offer_id='azure-spring-cloud-vmware-tanzu-2', + plan_id='tanzu-asc-ent-mtr') + if not term.accepted: + raise InvalidArgumentValueError('Terms for Azure Spring Cloud Enterprise is not accepted.\n' + 'Run "az term accept --publisher vmware-inc ' + '--product azure-spring-cloud-vmware-tanzu-2 ' + '--plan tanzu-asc-ent-mtr" to accept the term.') def validate_instance_count(namespace): @@ -429,7 +455,7 @@ def validate_vnet_required_parameters(namespace): not namespace.reserved_cidr_range and \ not namespace.vnet: return - if namespace.sku and namespace.sku.lower() == 'basic': + if namespace.sku and _parse_sku_name(namespace.sku) == 'basic': raise InvalidArgumentValueError('Virtual Network Injection is not supported for Basic tier.') if not namespace.app_subnet \ or not namespace.service_runtime_subnet: @@ -444,6 +470,14 @@ def validate_node_resource_group(namespace): _validate_resource_group_name(namespace.app_network_resource_group, 'app-network-resource-group') +def _parse_sku_name(sku): + if not sku: + return 'standard' + if type(sku) is str or type(sku) is DefaultStr: + return sku.lower() + return sku.tier.lower() + + def _validate_resource_group_name(name, message_name): if not name: return diff --git a/src/spring-cloud/azext_spring_cloud/commands.py b/src/spring-cloud/azext_spring_cloud/commands.py index df33732ec5a..cedfa23c292 100644 --- a/src/spring-cloud/azext_spring_cloud/commands.py +++ b/src/spring-cloud/azext_spring_cloud/commands.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long +from azure.cli.core.commands import CliCommandType from azext_spring_cloud._utils import handle_asc_exception from ._client_factory import (cf_spring_cloud_20220101preview, @@ -18,9 +19,17 @@ # pylint: disable=too-many-statements def load_command_table(self, _): - with self.command_group('spring-cloud', client_factory=cf_spring_cloud_20220101preview, + spring_cloud_routing_util = CliCommandType( + operations_tmpl='azext_spring_cloud.tier_routing_spring_cloud#{}', + client_factory=cf_spring_cloud_20220101preview + ) + + with self.command_group('spring-cloud', custom_command_type=spring_cloud_routing_util, exception_handler=handle_asc_exception) as g: g.custom_command('create', 'spring_cloud_create', supports_no_wait=True) + + with self.command_group('spring-cloud', client_factory=cf_spring_cloud_20220101preview, + exception_handler=handle_asc_exception) as g: g.custom_command('update', 'spring_cloud_update', supports_no_wait=True) g.custom_command('delete', 'spring_cloud_delete', supports_no_wait=True) g.custom_command('start', 'spring_cloud_start', supports_no_wait=True) diff --git a/src/spring-cloud/azext_spring_cloud/custom.py b/src/spring-cloud/azext_spring_cloud/custom.py index ae0b5aceb48..f7d8602da7b 100644 --- a/src/spring-cloud/azext_spring_cloud/custom.py +++ b/src/spring-cloud/azext_spring_cloud/custom.py @@ -16,8 +16,10 @@ import yaml # pylint: disable=import-error from time import sleep from ._stream_utils import stream_logs -from azure.mgmt.core.tools import parse_resource_id, is_valid_resource_id -from ._utils import _get_upload_local_file, _get_persistent_disk_size, get_portal_uri, get_azure_files_info +from azure.mgmt.core.tools import (parse_resource_id, is_valid_resource_id) +from ._utils import (_get_upload_local_file, _get_persistent_disk_size, + get_portal_uri, get_azure_files_info, + wait_till_end) from knack.util import CLIError from .vendored_sdks.appplatform.v2020_07_01 import models from .vendored_sdks.appplatform.v2020_11_01_preview import models as models_20201101preview @@ -36,7 +38,6 @@ from azure.cli.core.commands import cached_put from azure.core.exceptions import ResourceNotFoundError from ._utils import _get_rg_location -from ._utils import _get_sku_name from ._resource_quantity import validate_cpu, validate_memory from six.moves.urllib import parse from threading import Thread @@ -63,7 +64,7 @@ def spring_cloud_create(cmd, client, resource_group, name, location=None, service_runtime_network_resource_group=None, app_network_resource_group=None, app_insights_key=None, app_insights=None, sampling_rate=None, disable_app_insights=None, enable_java_agent=None, - sku='Standard', tags=None, no_wait=False): + sku=None, tags=None, no_wait=False): """ If app_insights_key, app_insights and disable_app_insights are all None, will still create an application insights and enable application insights. @@ -74,6 +75,25 @@ def spring_cloud_create(cmd, client, resource_group, name, location=None, # TODO (jiec) Deco this method when we deco parameter "--enable-java-agent" _warn_enable_java_agent(enable_java_agent) + poller = _create_service(cmd, client, resource_group, name, + location=location, + service_runtime_subnet=service_runtime_subnet, + app_subnet=app_subnet, + reserved_cidr_range=reserved_cidr_range, + service_runtime_network_resource_group=service_runtime_network_resource_group, + app_network_resource_group=app_network_resource_group, + sku=sku, + tags=tags) + _update_application_insights_asc_create(cmd, resource_group, name, location, + app_insights_key, app_insights, sampling_rate, + disable_app_insights, no_wait) + return poller + + +def _create_service(cmd, client, resource_group, name, location=None, + service_runtime_subnet=None, app_subnet=None, reserved_cidr_range=None, + service_runtime_network_resource_group=None, app_network_resource_group=None, + sku=None, tags=None): if location is None: location = _get_rg_location(cmd.cli_ctx, resource_group) properties = models.ClusterResourceProperties() @@ -87,19 +107,12 @@ def spring_cloud_create(cmd, client, resource_group, name, location=None, service_runtime_network_resource_group=service_runtime_network_resource_group ) - full_sku = models.Sku(name=_get_sku_name(sku), tier=sku) - - resource = models.ServiceResource(location=location, sku=full_sku, properties=properties, tags=tags) + resource = models.ServiceResource(location=location, sku=sku, properties=properties, tags=tags) poller = client.services.begin_create_or_update( resource_group, name, resource) logger.warning(" - Creating Service ..") - while poller.done() is False: - sleep(5) - - _update_application_insights_asc_create(cmd, resource_group, name, location, - app_insights_key, app_insights, sampling_rate, - disable_app_insights, no_wait) + wait_till_end(cmd, poller) return poller @@ -138,8 +151,7 @@ def spring_cloud_update(cmd, client, resource_group, name, app_insights_key=None # update service sku if sku is not None: - full_sku = models.Sku(name=_get_sku_name(sku), tier=sku) - updated_resource.sku = full_sku + updated_resource.sku = sku update_service_sku = True resource = client.services.get(resource_group, name) diff --git a/src/spring-cloud/azext_spring_cloud/tests/latest/test_asc_validator.py b/src/spring-cloud/azext_spring_cloud/tests/latest/test_asc_validator.py index f96ec9f4604..6039bb4ec3c 100644 --- a/src/spring-cloud/azext_spring_cloud/tests/latest/test_asc_validator.py +++ b/src/spring-cloud/azext_spring_cloud/tests/latest/test_asc_validator.py @@ -6,8 +6,9 @@ import copy from argparse import Namespace from azure.cli.core.util import CLIError +from azure.cli.core.azclierror import InvalidArgumentValueError from ..._validators import (validate_vnet, validate_vnet_required_parameters, _validate_cidr_range, - _set_default_cidr_range) + _set_default_cidr_range, validate_sku) try: import unittest.mock as mock @@ -277,3 +278,51 @@ def test_vnet_location(self): with self.assertRaises(CLIError) as context: validate_vnet(_get_test_cmd(), ns) self.assertTrue('--vnet and Azure Spring Cloud instance should be in the same location.' in str(context.exception)) + + +def _mock_term_client(accepted, registered): + def _mock_get(offer_type, publisher_id, offer_id, plan_id): + term = mock.MagicMock() + term.accepted = accepted + return term + def _mock_provider_get(namespace): + provider = mock.MagicMock() + provider.registration_state = 'Registered' if registered else 'NotRegistered' + return provider + client = mock.MagicMock() + client.marketplace_agreements = mock.MagicMock() + client.marketplace_agreements.get = _mock_get + client.providers = mock.MagicMock() + client.providers.get = _mock_provider_get + return client + +def _mock_happy_client(cli_ctx, client_type, **kwargs): + return _mock_term_client(True, True) + +def _mock_not_accepted_term_client(cli_ctx, client_type, **kwargs): + return _mock_term_client(False, True) + +def _mock_not_registered_client(cli_ctx, client_type, **kwargs): + return _mock_term_client(True, False) + +class TestSkuValidator(unittest.TestCase): + @mock.patch('azure.cli.core.commands.client_factory.get_mgmt_service_client', _mock_happy_client) + def test_happy_path(self): + ns = Namespace(sku='Enterprise') + validate_sku(_get_test_cmd(), ns) + self.assertEqual('Enterprise', ns.sku.tier) + + @mock.patch('azure.cli.core.commands.client_factory.get_mgmt_service_client', _mock_not_accepted_term_client) + def test_term_not_accept(self): + ns = Namespace(sku='Enterprise') + with self.assertRaises(InvalidArgumentValueError) as context: + validate_sku(_get_test_cmd(), ns) + self.assertTrue('Terms for Azure Spring Cloud Enterprise is not accepted.' in str(context.exception)) + + @mock.patch('azure.cli.core.commands.client_factory.get_mgmt_service_client', _mock_not_registered_client) + def test_provider_not_registered(self): + ns = Namespace(sku='Enterprise') + with self.assertRaises(InvalidArgumentValueError) as context: + validate_sku(_get_test_cmd(), ns) + self.assertTrue('Microsoft.SaaS resource provider is not registered.' in str(context.exception)) + diff --git a/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py b/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py new file mode 100644 index 00000000000..f5ff34360b7 --- /dev/null +++ b/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py @@ -0,0 +1,64 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=wrong-import-order +from ._validators import (_parse_sku_name) +from ._enterprise import (spring_cloud_create as create_enterprise) +from .custom import (spring_cloud_create as create_standard) +from knack.log import get_logger + +logger = get_logger(__name__) + + +def spring_cloud_create(cmd, client, resource_group, name, + location=None, + vnet=None, + service_runtime_subnet=None, + app_subnet=None, + reserved_cidr_range=None, + service_runtime_network_resource_group=None, + app_network_resource_group=None, + app_insights_key=None, + app_insights=None, + sampling_rate=None, + disable_app_insights=None, + enable_java_agent=None, + sku=None, + tags=None, + no_wait=False): + if _parse_sku_name(sku) == 'enterprise': + return create_enterprise(cmd, client, resource_group, name, + location=location, + vnet=vnet, + service_runtime_subnet=service_runtime_subnet, + app_subnet=app_subnet, + reserved_cidr_range=reserved_cidr_range, + service_runtime_network_resource_group=service_runtime_network_resource_group, + app_network_resource_group=app_network_resource_group, + app_insights_key=app_insights_key, + app_insights=app_insights, + sampling_rate=sampling_rate, + disable_app_insights=disable_app_insights, + enable_java_agent=enable_java_agent, + sku=sku, + tags=tags, + no_wait=no_wait) + else: + return create_standard(cmd, client, resource_group, name, + location=location, + vnet=vnet, + service_runtime_subnet=service_runtime_subnet, + app_subnet=app_subnet, + reserved_cidr_range=reserved_cidr_range, + service_runtime_network_resource_group=service_runtime_network_resource_group, + app_network_resource_group=app_network_resource_group, + app_insights_key=app_insights_key, + app_insights=app_insights, + sampling_rate=sampling_rate, + disable_app_insights=disable_app_insights, + enable_java_agent=enable_java_agent, + sku=sku, + tags=tags, + no_wait=no_wait) From 973933b8a00ee488f0b5e2108cb4732c85cd3ebf Mon Sep 17 00:00:00 2001 From: Yuwei Zhou Date: Wed, 22 Dec 2021 19:02:33 +0800 Subject: [PATCH 2/5] Add license --- src/spring-cloud/azext_spring_cloud/_enterprise.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/spring-cloud/azext_spring_cloud/_enterprise.py b/src/spring-cloud/azext_spring_cloud/_enterprise.py index c694538c72c..efa210bfbe9 100644 --- a/src/spring-cloud/azext_spring_cloud/_enterprise.py +++ b/src/spring-cloud/azext_spring_cloud/_enterprise.py @@ -1,3 +1,10 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=wrong-import-order + from knack.log import get_logger from .custom import (_create_service) From dc07bf0a27cb4d47cf6c3181d0309e8f0c8d76df Mon Sep 17 00:00:00 2001 From: Yuwei Zhou Date: Thu, 23 Dec 2021 13:08:53 +0800 Subject: [PATCH 3/5] address comment --- src/spring-cloud/azext_spring_cloud/_params.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/spring-cloud/azext_spring_cloud/_params.py b/src/spring-cloud/azext_spring_cloud/_params.py index acfa7da547b..f9430b7c33b 100644 --- a/src/spring-cloud/azext_spring_cloud/_params.py +++ b/src/spring-cloud/azext_spring_cloud/_params.py @@ -26,6 +26,7 @@ validator=validate_env, help="Space-separated environment variables in 'key[=value]' format.", nargs='*') service_name_type = CLIArgumentType(options_list=['--service', '-s'], help='Name of Azure Spring Cloud, you can configure the default service using az configure --defaults spring-cloud=.', configured_default='spring-cloud') app_name_type = CLIArgumentType(help='App name, you can configure the default app using az configure --defaults spring-cloud-app=.', validator=validate_app_name, configured_default='spring-cloud-app') +sku_type=CLIArgumentType(arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, help='Name of SKU. Enterprise is still in Preview.') # pylint: disable=too-many-statements @@ -40,7 +41,7 @@ def load_arguments(self, _): # https://dev.azure.com/msazure/AzureDMSS/_workitems/edit/11002857/ with self.argument_context('spring-cloud create') as c: c.argument('location', arg_type=get_location_type(self.cli_ctx), validator=validate_location) - c.argument('sku', arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, default='Standard', help='Name of SKU. Enterprise is still in Preview.') + c.argument('sku', arg_type=sku_type, default='Standard') c.argument('reserved_cidr_range', help='Comma-separated list of IP address ranges in CIDR format. The IP ranges are reserved to host underlying Azure Spring Cloud infrastructure, which should be 3 at least /16 unused IP ranges, must not overlap with any Subnet IP ranges.', validator=validate_vnet_required_parameters) c.argument('vnet', help='The name or ID of an existing Virtual Network into which to deploy the Spring Cloud instance.', validator=validate_vnet_required_parameters) c.argument('app_subnet', help='The name or ID of an existing subnet in "vnet" into which to deploy the Spring Cloud app. Required when deploying into a Virtual Network. Smaller subnet sizes are supported, please refer: https://aka.ms/azure-spring-cloud-smaller-subnet-vnet-docs', validator=validate_vnet_required_parameters) @@ -73,7 +74,7 @@ def load_arguments(self, _): validator=validate_tracing_parameters_asc_create) with self.argument_context('spring-cloud update') as c: - c.argument('sku', arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, help='Name of SKU. Enterprise is still in Preview.') + c.argument('sku', arg_type=sku_type) c.argument('app_insights_key', help="Connection string (recommended) or Instrumentation key of the existing Application Insights.", validator=validate_tracing_parameters_asc_update, From e03b1772696f097419844db2519bc192ea0b4d60 Mon Sep 17 00:00:00 2001 From: Yuwei Zhou Date: Thu, 23 Dec 2021 13:15:08 +0800 Subject: [PATCH 4/5] fix lint --- src/spring-cloud/azext_spring_cloud/_params.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spring-cloud/azext_spring_cloud/_params.py b/src/spring-cloud/azext_spring_cloud/_params.py index f9430b7c33b..c168136edf1 100644 --- a/src/spring-cloud/azext_spring_cloud/_params.py +++ b/src/spring-cloud/azext_spring_cloud/_params.py @@ -26,7 +26,7 @@ validator=validate_env, help="Space-separated environment variables in 'key[=value]' format.", nargs='*') service_name_type = CLIArgumentType(options_list=['--service', '-s'], help='Name of Azure Spring Cloud, you can configure the default service using az configure --defaults spring-cloud=.', configured_default='spring-cloud') app_name_type = CLIArgumentType(help='App name, you can configure the default app using az configure --defaults spring-cloud-app=.', validator=validate_app_name, configured_default='spring-cloud-app') -sku_type=CLIArgumentType(arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, help='Name of SKU. Enterprise is still in Preview.') +sku_type = CLIArgumentType(arg_type=get_enum_type(['Basic', 'Standard', 'Enterprise']), validator=validate_sku, help='Name of SKU. Enterprise is still in Preview.') # pylint: disable=too-many-statements From 196e739d228a8e7a23c9ca6bd33db937d70cd970 Mon Sep 17 00:00:00 2001 From: Yuwei Zhou Date: Thu, 23 Dec 2021 15:16:26 +0800 Subject: [PATCH 5/5] Add comments --- src/spring-cloud/azext_spring_cloud/_enterprise.py | 4 ++++ src/spring-cloud/azext_spring_cloud/custom.py | 3 +++ .../azext_spring_cloud/tier_routing_spring_cloud.py | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/src/spring-cloud/azext_spring_cloud/_enterprise.py b/src/spring-cloud/azext_spring_cloud/_enterprise.py index efa210bfbe9..a2c4f80d447 100644 --- a/src/spring-cloud/azext_spring_cloud/_enterprise.py +++ b/src/spring-cloud/azext_spring_cloud/_enterprise.py @@ -18,6 +18,10 @@ def spring_cloud_create(cmd, client, resource_group, name, location=None, app_insights_key=None, app_insights=None, sampling_rate=None, disable_app_insights=None, enable_java_agent=None, sku=None, tags=None, no_wait=False): + """ + This method creates Azure Spring Cloud enterprise tier instance, it also creates sub-component under the instance if + user enable these component. + """ poller = _create_service(cmd, client, resource_group, name, location=location, service_runtime_subnet=service_runtime_subnet, diff --git a/src/spring-cloud/azext_spring_cloud/custom.py b/src/spring-cloud/azext_spring_cloud/custom.py index f7d8602da7b..bc2c23f78d5 100644 --- a/src/spring-cloud/azext_spring_cloud/custom.py +++ b/src/spring-cloud/azext_spring_cloud/custom.py @@ -66,6 +66,9 @@ def spring_cloud_create(cmd, client, resource_group, name, location=None, disable_app_insights=None, enable_java_agent=None, sku=None, tags=None, no_wait=False): """ + Note: This is the command for create Spring-Cloud Standard and Basic tier. Refer tier_routing_spring_cloud.py for + the command definition. And _enteprise.py for Spring-Cloud Enterprise tier creation. + If app_insights_key, app_insights and disable_app_insights are all None, will still create an application insights and enable application insights. :param enable_java_agent: (TODO) In deprecation process, ignore the value now. Will delete this. diff --git a/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py b/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py index f5ff34360b7..2945f27822c 100644 --- a/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py +++ b/src/spring-cloud/azext_spring_cloud/tier_routing_spring_cloud.py @@ -28,6 +28,10 @@ def spring_cloud_create(cmd, client, resource_group, name, sku=None, tags=None, no_wait=False): + """ + Because Standard/Basic tier vs. Enterprise tier creation are very different. Here routes the command to different + implementation according to --sku parameters. + """ if _parse_sku_name(sku) == 'enterprise': return create_enterprise(cmd, client, resource_group, name, location=location,