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
12 changes: 12 additions & 0 deletions src/spring-cloud/azext_spring_cloud/_app_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ def active_deployment_exist_under_app(cmd, namespace):
raise InvalidArgumentValueError(NO_PRODUCTION_DEPLOYMENT_SET_ERROR)


def ensure_not_active_deployment(cmd, namespace):
"""
Validate namespace.deployment is not active
"""
if not namespace.deployment or not namespace.resource_group or not namespace.service or not namespace.name:
return
client = cf_spring_cloud(cmd.cli_ctx)
deployment = _ensure_deployment_exist(client, namespace.resource_group, namespace.service, namespace.name, namespace.deployment)
if deployment.properties.active:
raise InvalidArgumentValueError('Deployment {} is already the production deployment'.format(deployment.name))


def _ensure_deployment_exist(client, resource_group, service, app, deployment):
try:
return client.deployments.get(resource_group, service, app, deployment)
Expand Down
7 changes: 7 additions & 0 deletions src/spring-cloud/azext_spring_cloud/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from .vendored_sdks.appplatform.v2020_11_01_preview import (
AppPlatformManagementClient as AppPlatformManagementClient_20201101preview
)
from .vendored_sdks.appplatform.v2022_01_01_preview import (
AppPlatformManagementClient as AppPlatformManagementClient_20220101preview
)
from .vendored_sdks.appplatform.v2021_06_01_preview import (
AppPlatformManagementClient as AppPlatformManagementClient_20210601preview
)
Expand All @@ -16,6 +19,10 @@
)


def cf_spring_cloud_20220101preview(cli_ctx, *_):
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient_20220101preview)


def cf_spring_cloud(cli_ctx, *_):
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient)

Expand Down
5 changes: 3 additions & 2 deletions src/spring-cloud/azext_spring_cloud/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
validate_tracing_parameters_asc_create, validate_tracing_parameters_asc_update,
validate_app_insights_parameters, validate_instance_count, validate_java_agent_parameters,
validate_jar)
from ._app_validator import (fulfill_deployment_param, active_deployment_exist, active_deployment_exist_under_app)
from ._app_validator import (fulfill_deployment_param, active_deployment_exist, active_deployment_exist_under_app,
ensure_not_active_deployment)
from ._utils import ApiType

from .vendored_sdks.appplatform.v2020_07_01.models import RuntimeVersion, TestKeyType
Expand Down Expand Up @@ -182,7 +183,7 @@ def prepare_logs_argument(c):

with self.argument_context('spring-cloud app set-deployment') as c:
c.argument('deployment', options_list=[
'--deployment', '-d'], help='Name of an existing deployment of the app.', validator=validate_deployment_name)
'--deployment', '-d'], help='Name of an existing deployment of the app.', validator=ensure_not_active_deployment)

for scope in ['spring-cloud app create', 'spring-cloud app update']:
with self.argument_context(scope) as c:
Expand Down
80 changes: 51 additions & 29 deletions src/spring-cloud/azext_spring_cloud/_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@


# pylint: disable=line-too-long
from azure.mgmt.core.tools import parse_resource_id


def transform_spring_cloud_table_output(result):
Expand All @@ -16,6 +17,7 @@ def transform_spring_cloud_table_output(result):
for item in result:
item['State'] = item['properties']['provisioningState']
item['tags'] = item['tags']
item['tier'] = item['sku']['tier']

return result if is_list else result[0]

Expand All @@ -27,53 +29,49 @@ def transform_app_table_output(result):
result = [result]

for item in result:
item['Production Deployment'] = item['properties']['activeDeploymentName']
item['Public Url'] = item['properties']['url']

if item['properties'].get('activeDeployment', None):
isStarted = item['properties']['activeDeployment']['properties']['status'].upper() == "RUNNING"
instance_count = item['properties']['activeDeployment']['sku']['capacity']
instances = item['properties']['activeDeployment']['properties']['instances']
if instances is None:
instances = []
up_number = len(
[x for x in instances if x['discoveryStatus'].upper() == 'UP' or x['discoveryStatus'].upper() == 'OUT_OF_SERVICE'])
running_number = len(
[x for x in instances if x['status'].upper() == "RUNNING"])
item['Provisioning Status'] = item['properties']['activeDeployment']['properties']['provisioningState']
item['CPU'] = item['properties']['activeDeployment']['properties']['deploymentSettings']['cpu']
item['Memory'] = item['properties']['activeDeployment']['properties']['deploymentSettings']['memoryInGb']
item['Running Instance'] = "{}/{}".format(running_number, instance_count) if isStarted else "Stopped"
item['Registered Instance'] = "{}/{}".format(up_number, instance_count) if isStarted else "Stopped"
if 'activeDeployment' in item['properties'] and item['properties']['activeDeployment']:
item['Production Deployment'] = item['properties']['activeDeployment']['name']
_apply_deployment_table(item, item['properties']['activeDeployment'])

persistentStorage = item['properties']['persistentDisk']
item['Persistent Storage'] = "{}/{} Gb".format(
persistentStorage['usedInGb'], persistentStorage['sizeInGb']) if persistentStorage['sizeInGb'] else "-"

if 'addonConfigs' in item['properties']:
addon = item['properties']['addonConfigs']
item['Bind Service Registry'] = _get_service_registry_binding(addon) or '-'
item['Bind Application Configuration Service'] = _get_acs_binding(addon) or '-'

return result if is_list else result[0]


def _get_service_registry_binding(addon):
return _parse_item_resource_id(addon, 'serviceRegistry', 'ServiceRegistry')


def _get_acs_binding(addon):
return _parse_item_resource_id(addon, 'applicationConfigurationService', 'ApplicationConfigurationService')


def _parse_item_resource_id(addon, key, secondary):
resource_id = (addon.get(key, None) or addon.get(secondary, {})).get('resourceId', None)
if not resource_id:
return None
resource_dict = parse_resource_id(resource_id)
return resource_dict.get('name', '')


def transform_spring_cloud_deployment_output(result):
is_list = isinstance(result, list)

if not is_list:
result = [result]

for item in result:
isStarted = item['properties']['status'].upper() == "RUNNING"
instance_count = item['sku']['capacity']
instances = item['properties']['instances']
if instances is None:
instances = []
up_number = len(
[x for x in instances if x['discoveryStatus'].upper() == 'UP' or x['discoveryStatus'].upper() == 'OUT_OF_SERVICE'])
running_number = len([x for x in instances if x['status'].upper() == "RUNNING"])
item['App Name'] = item['properties']["appName"]
item['Provisioning Status'] = item['properties']['provisioningState']
item['CPU'] = item['properties']['deploymentSettings']['cpu']
item['Memory'] = item['properties']['deploymentSettings']['memoryInGb']
item['Running Instance'] = "{}/{}".format(running_number, instance_count) if isStarted else "Stopped"
item['Registered Instance'] = "{}/{}".format(up_number, instance_count) if isStarted else "Stopped"
_apply_deployment_table(item, item)

return result if is_list else result[0]

Expand Down Expand Up @@ -108,3 +106,27 @@ def transform_spring_cloud_custom_domain_output(result):
item['Thumbprint'] = item['properties']['thumbprint']

return result if is_list else result[0]


def _get_registration_state(deployment):
if deployment['properties']['status'].upper() == 'STOPPED':
return 'Stopped'
instances = deployment['properties']['instances'] or []
if len(instances) > 0 and all(x['discoveryStatus'].upper() == 'N/A' for x in instances):
return 'N/A'
up_number = len(
[x for x in instances if x['discoveryStatus'].upper() == 'UP' or x['discoveryStatus'].upper() == 'OUT_OF_SERVICE'])
return "{}/{}".format(up_number, deployment['sku']['capacity'])


def _apply_deployment_table(item, deployment):
isStarted = deployment['properties']['status'].upper() == "RUNNING"
instance_count = deployment['sku']['capacity']
instances = deployment['properties']['instances'] or []
running_number = len(
[x for x in instances if x['status'].upper() == "RUNNING"])
item['Provisioning State'] = deployment['properties']['provisioningState']
item['CPU'] = deployment['properties']['deploymentSettings']['resourceRequests']['cpu']
item['Memory'] = deployment['properties']['deploymentSettings']['resourceRequests']['memory']
item['Running Instance'] = "{}/{}".format(running_number, instance_count) if isStarted else "Stopped"
item['Registered Instance'] = _get_registration_state(deployment)
6 changes: 3 additions & 3 deletions src/spring-cloud/azext_spring_cloud/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
from azure.cli.core.commands.validators import validate_tag
from azure.cli.core.azclierror import InvalidArgumentValueError
from ._utils import _get_file_type
from msrestazure.tools import is_valid_resource_id
from msrestazure.tools import parse_resource_id
from msrestazure.tools import resource_id
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
Expand Down
40 changes: 19 additions & 21 deletions src/spring-cloud/azext_spring_cloud/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
# pylint: disable=line-too-long
from azext_spring_cloud._utils import handle_asc_exception

from ._client_factory import (cf_app_services,
cf_spring_cloud,
from ._client_factory import (cf_spring_cloud_20220101preview,
cf_spring_cloud_20201101preview,
cf_spring_cloud_20210901preview,
cf_config_servers)
from ._transformers import (transform_spring_cloud_table_output,
transform_app_table_output,
Expand All @@ -20,17 +18,17 @@

# pylint: disable=too-many-statements
def load_command_table(self, _):
with self.command_group('spring-cloud', client_factory=cf_app_services,
with self.command_group('spring-cloud', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('create', 'spring_cloud_create', supports_no_wait=True, client_factory=cf_spring_cloud)
g.custom_command('update', 'spring_cloud_update', supports_no_wait=True, client_factory=cf_spring_cloud)
g.custom_command('create', 'spring_cloud_create', supports_no_wait=True)
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, client_factory=cf_spring_cloud_20210901preview)
g.custom_command('stop', 'spring_cloud_stop', supports_no_wait=True, client_factory=cf_spring_cloud_20210901preview)
g.custom_command('list', 'spring_cloud_list', client_factory=cf_spring_cloud_20210901preview, table_transformer=transform_spring_cloud_table_output)
g.custom_show_command('show', 'spring_cloud_get', client_factory=cf_spring_cloud_20210901preview, table_transformer=transform_spring_cloud_table_output)
g.custom_command('start', 'spring_cloud_start', supports_no_wait=True)
g.custom_command('stop', 'spring_cloud_stop', supports_no_wait=True)
g.custom_command('list', 'spring_cloud_list', table_transformer=transform_spring_cloud_table_output)
g.custom_show_command('show', 'spring_cloud_get', table_transformer=transform_spring_cloud_table_output)

with self.command_group('spring-cloud test-endpoint', client_factory=cf_spring_cloud,
with self.command_group('spring-cloud test-endpoint', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('enable ', 'enable_test_endpoint')
g.custom_show_command('disable ', 'disable_test_endpoint')
Expand All @@ -51,17 +49,17 @@ def load_command_table(self, _):
g.custom_command('repo update', 'config_repo_update')
g.custom_command('repo list', 'config_repo_list')

with self.command_group('spring-cloud app', client_factory=cf_spring_cloud_20210901preview,
with self.command_group('spring-cloud app', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('create', 'app_create')
g.custom_command('update', 'app_update')
g.custom_command('deploy', 'app_deploy', supports_no_wait=True)
g.custom_command('scale', 'app_scale', supports_no_wait=True)
g.custom_command('show-deploy-log', 'app_get_build_log')
g.custom_command('set-deployment', 'app_set_deployment',
supports_no_wait=True)
g.custom_command('unset-deployment', 'app_unset_deployment',
supports_no_wait=True)
g.custom_command('scale', 'app_scale', supports_no_wait=True)
g.custom_command('show-deploy-log', 'app_get_build_log')
g.custom_command('delete', 'app_delete')
g.custom_command('list', 'app_list',
table_transformer=transform_app_table_output)
Expand All @@ -74,18 +72,18 @@ def load_command_table(self, _):
g.custom_command('append-persistent-storage', 'app_append_persistent_storage')
g.custom_command('append-loaded-public-certificate', 'app_append_loaded_public_certificate')

with self.command_group('spring-cloud app identity', client_factory=cf_spring_cloud,
with self.command_group('spring-cloud app identity', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('assign', 'app_identity_assign')
g.custom_command('remove', 'app_identity_remove')
g.custom_show_command('show', 'app_identity_show')

with self.command_group('spring-cloud app log', client_factory=cf_spring_cloud,
with self.command_group('spring-cloud app log', client_factory=cf_spring_cloud_20220101preview,
deprecate_info=g.deprecate(redirect='az spring-cloud app logs', hide=True),
exception_handler=handle_asc_exception) as g:
g.custom_command('tail', 'app_tail_log')

with self.command_group('spring-cloud app deployment', client_factory=cf_spring_cloud_20210901preview,
with self.command_group('spring-cloud app deployment', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('create', 'deployment_create', supports_no_wait=True)
g.custom_command('list', 'deployment_list',
Expand All @@ -97,7 +95,7 @@ def load_command_table(self, _):
g.custom_command('generate-thread-dump', 'deployment_generate_thread_dump')
g.custom_command('start-jfr', 'deployment_start_jfr')

with self.command_group('spring-cloud app binding', client_factory=cf_spring_cloud,
with self.command_group('spring-cloud app binding', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('list', 'binding_list')
g.custom_show_command('show', 'binding_get')
Expand All @@ -109,7 +107,7 @@ def load_command_table(self, _):
g.custom_command('redis update', 'binding_redis_update')
g.custom_show_command('remove', 'binding_remove')

with self.command_group('spring-cloud storage', client_factory=cf_spring_cloud_20210901preview,
with self.command_group('spring-cloud storage', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('list', 'storage_list')
g.custom_show_command('show', 'storage_get')
Expand All @@ -118,15 +116,15 @@ def load_command_table(self, _):
g.custom_command('remove', 'storage_remove')
g.custom_command('list-persistent-storage', "storage_list_persistent_storage", table_transformer=transform_app_table_output)

with self.command_group('spring-cloud certificate', client_factory=cf_spring_cloud_20210901preview,
with self.command_group('spring-cloud certificate', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('add', 'certificate_add')
g.custom_show_command('show', 'certificate_show', table_transformer=transform_spring_cloud_certificate_output)
g.custom_command('list', 'certificate_list', table_transformer=transform_spring_cloud_certificate_output)
g.custom_command('remove', 'certificate_remove')
g.custom_command('list-reference-app', 'certificate_list_reference_app', table_transformer=transform_app_table_output)

with self.command_group('spring-cloud app custom-domain', client_factory=cf_spring_cloud,
with self.command_group('spring-cloud app custom-domain', client_factory=cf_spring_cloud_20220101preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('bind', 'domain_bind')
g.custom_show_command('show', 'domain_show', table_transformer=transform_spring_cloud_custom_domain_output)
Expand Down
Loading