Skip to content

Commit e4a423a

Browse files
authored
Add support for 0.5 core / 512 Mi resource requests for spring-cloud deployments (Azure#3486)
* update bundled SDK for spring-cloud * Add support for 0.5 core, 512 Mi resource requests in app deployment * Add support to format log streaming of structured JSON output * fix: default logging style * Add support to output Spring Boot flavored logger name * fix style and linter issue in new code * change new api-version from 2021-03-03-preview to 2021-06-01-preview * update to use 2021-06-01-preview api-version * fix resource quantity validation * bump the spring-cloud extension version to 2.5.0 * update according to review comments * refine comments for cpu/memory validation * fix: lint style for _resource_quantity.py * fix: fix reset cpu/memory settings on env update
1 parent ab3d44a commit e4a423a

40 files changed

+10413
-132
lines changed

src/spring-cloud/HISTORY.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
Release History
22
===============
3+
4+
2.6.0
5+
-----
6+
* Add support for 0.5 core, 512 Mi resource requests in app deployment
7+
38
2.5.1
49
-----
5-
* Revert `2.5.0` as a quick fix for incompatibility with old api-version.
10+
* Revert `2.5.0` as a quick fix for incompatibility with old api-version.
611

712
~~2.5.0~~
813
-----
Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,58 @@
1-
# --------------------------------------------------------------------------------------------
2-
# Copyright (c) Microsoft Corporation. All rights reserved.
3-
# Licensed under the MIT License. See License.txt in the project root for license information.
4-
# --------------------------------------------------------------------------------------------
5-
from azure.cli.core.commands.client_factory import get_mgmt_service_client
6-
from azure.cli.core.profiles import ResourceType
7-
from .vendored_sdks.appplatform.v2020_07_01 import AppPlatformManagementClient
8-
from .vendored_sdks.appplatform.v2020_11_01_preview import AppPlatformManagementClient as AppPlatformManagementClient_20201101preview
9-
10-
11-
def cf_spring_cloud(cli_ctx, *_):
12-
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient)
13-
14-
15-
def cf_spring_cloud_20201101preview(cli_ctx, *_):
16-
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient_20201101preview)
17-
18-
19-
def cf_resource_groups(cli_ctx, subscription_id=None):
20-
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES,
21-
subscription_id=subscription_id).resource_groups
22-
23-
24-
def cf_app_services(cli_ctx, *_):
25-
return cf_spring_cloud(cli_ctx).services
26-
27-
28-
def cf_apps(cli_ctx, *_):
29-
return cf_spring_cloud(cli_ctx).apps
30-
31-
32-
def cf_deployments(cli_ctx, *_):
33-
return cf_spring_cloud(cli_ctx).deployments
34-
35-
36-
def cf_bindings(cli_ctx, *_):
37-
return cf_spring_cloud(cli_ctx).bindings
38-
39-
40-
def cf_config_servers(cli_ctx, *_):
41-
return cf_spring_cloud(cli_ctx).config_servers
42-
43-
44-
def cf_certificates(cli_ctx, *_):
45-
return cf_spring_cloud(cli_ctx).certificates
46-
47-
48-
def cf_custom_domains(cli_ctx, *_):
49-
return cf_spring_cloud(cli_ctx).custom_domains
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
from azure.cli.core.commands.client_factory import get_mgmt_service_client
6+
from azure.cli.core.profiles import ResourceType
7+
from .vendored_sdks.appplatform.v2020_07_01 import AppPlatformManagementClient
8+
from .vendored_sdks.appplatform.v2020_11_01_preview import (
9+
AppPlatformManagementClient as AppPlatformManagementClient_20201101preview
10+
)
11+
from .vendored_sdks.appplatform.v2021_06_01_preview import (
12+
AppPlatformManagementClient as AppPlatformManagementClient_20210601preview
13+
)
14+
15+
16+
def cf_spring_cloud(cli_ctx, *_):
17+
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient)
18+
19+
20+
def cf_spring_cloud_20201101preview(cli_ctx, *_):
21+
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient_20201101preview)
22+
23+
24+
def cf_spring_cloud_20210601preview(cli_ctx, *_):
25+
return get_mgmt_service_client(cli_ctx, AppPlatformManagementClient_20210601preview)
26+
27+
28+
def cf_resource_groups(cli_ctx, subscription_id=None):
29+
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES,
30+
subscription_id=subscription_id).resource_groups
31+
32+
33+
def cf_app_services(cli_ctx, *_):
34+
return cf_spring_cloud(cli_ctx).services
35+
36+
37+
def cf_apps(cli_ctx, *_):
38+
return cf_spring_cloud(cli_ctx).apps
39+
40+
41+
def cf_deployments(cli_ctx, *_):
42+
return cf_spring_cloud(cli_ctx).deployments
43+
44+
45+
def cf_bindings(cli_ctx, *_):
46+
return cf_spring_cloud(cli_ctx).bindings
47+
48+
49+
def cf_config_servers(cli_ctx, *_):
50+
return cf_spring_cloud(cli_ctx).config_servers
51+
52+
53+
def cf_certificates(cli_ctx, *_):
54+
return cf_spring_cloud(cli_ctx).certificates
55+
56+
57+
def cf_custom_domains(cli_ctx, *_):
58+
return cf_spring_cloud(cli_ctx).custom_domains

src/spring-cloud/azext_spring_cloud/_params.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ def load_arguments(self, _):
7979
options_list=['--assign-endpoint', c.deprecate(target='--is-public', redirect='--assign-endpoint', hide=True)])
8080
c.argument('assign_identity', arg_type=get_three_state_flag(),
8181
help='If true, assign managed service identity.')
82-
c.argument('cpu', type=int, default=1,
83-
help='Number of virtual cpu cores per instance.')
84-
c.argument('memory', type=int, default=1,
85-
help='Number of GB of memory per instance.')
82+
c.argument('cpu', type=str, default="1",
83+
help='CPU resource quantity. Should be 500m or number of CPU cores.')
84+
c.argument('memory', type=str, default="1Gi",
85+
help='Memory resource quantity. Should be 512Mi or #Gi, e.g., 1Gi, 3Gi.')
8686
c.argument('instance_count', type=int,
8787
default=1, help='Number of instance.', validator=validate_instance_count)
8888

@@ -140,8 +140,8 @@ def prepare_logs_argument(c):
140140
c.argument('env', env_type)
141141

142142
with self.argument_context('spring-cloud app scale') as c:
143-
c.argument('cpu', type=int, help='Number of virtual cpu cores per instance.')
144-
c.argument('memory', type=int, help='Number of GB of memory per instance.')
143+
c.argument('cpu', type=str, help='CPU resource quantity. Should be 500m or number of CPU cores.')
144+
c.argument('memory', type=str, help='Memory resource quantity. Should be 512Mi or #Gi, e.g., 1Gi, 3Gi.')
145145
c.argument('instance_count', type=int, help='Number of instance.', validator=validate_instance_count)
146146

147147
for scope in ['spring-cloud app deploy', 'spring-cloud app deployment create']:
@@ -160,8 +160,8 @@ def prepare_logs_argument(c):
160160
with self.argument_context('spring-cloud app deployment create') as c:
161161
c.argument('skip_clone_settings', help='Create staging deployment will automatically copy settings from production deployment.',
162162
action='store_true')
163-
c.argument('cpu', type=int, help='Number of virtual cpu cores per instance.')
164-
c.argument('memory', type=int, help='Number of GB of memory per instance.')
163+
c.argument('cpu', type=str, help='CPU resource quantity. Should be 500m or number of CPU cores.')
164+
c.argument('memory', type=str, help='Memory resource quantity. Should be 512Mi or #Gi, e.g., 1Gi, 3Gi.')
165165
c.argument('instance_count', type=int, help='Number of instance.', validator=validate_instance_count)
166166

167167
with self.argument_context('spring-cloud app deployment') as c:
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
6+
7+
import re
8+
from knack.log import get_logger
9+
from azure.cli.core.azclierror import InvalidArgumentValueError
10+
11+
12+
logger = get_logger(__name__)
13+
14+
15+
def validate_cpu(cpu):
16+
'''
17+
CPU quantity should be either integer, or millis. Currently, 500m (aka 0.5) is the only allowed fractional value.
18+
Note that 1 can be represented as 1000m.
19+
'''
20+
if cpu is None:
21+
return None
22+
23+
# some digit(s) followed by an optional m
24+
if not re.match(r"^\d+m?$", cpu):
25+
raise InvalidArgumentValueError("CPU quantity should be millis (500m) or integer (1, 2, ...)")
26+
27+
return cpu
28+
29+
30+
def validate_memory(memory):
31+
'''
32+
Memory quantity should be in gigabytes (Gi) or megabytes (Mi). Currently, the only allowed fractional gigabytes
33+
quantity is 512Mi. Note that 1Gi can be specified with 1024Mi.
34+
35+
In the legacy extension, gigabytes is specified with integer. This will generate a warning now.
36+
'''
37+
if memory is None:
38+
return None
39+
40+
unified = memory
41+
try:
42+
# For backward compatibility, convert integer value to value with Gi unit
43+
int(memory)
44+
logger.warning("Memory quantity [--memory] should be specified with unit, such as 512Mi, 1Gi. "
45+
"Support for integer quantity will be dropped in future release.")
46+
unified = memory + "Gi"
47+
except ValueError:
48+
pass
49+
50+
# Some digit(s) followed by explicit unit (Mi or Gi)
51+
if not re.match(r"^\d+[MG]i$", unified):
52+
raise InvalidArgumentValueError("Memory quantity should be integer followed by unit (Mi/Gi)")
53+
54+
return unified

src/spring-cloud/azext_spring_cloud/commands.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
# --------------------------------------------------------------------------------------------
55

66
# pylint: disable=line-too-long
7-
from ._client_factory import (cf_app_services, cf_spring_cloud, cf_spring_cloud_20201101preview, cf_bindings, cf_config_servers)
7+
from ._client_factory import (cf_app_services,
8+
cf_spring_cloud,
9+
cf_spring_cloud_20201101preview,
10+
cf_spring_cloud_20210601preview,
11+
cf_bindings,
12+
cf_config_servers)
813
from ._transformers import (transform_spring_cloud_table_output,
914
transform_app_table_output,
1015
transform_spring_cloud_deployment_output,
@@ -40,7 +45,7 @@ def load_command_table(self, _):
4045
g.custom_command('repo update', 'config_repo_update')
4146
g.custom_command('repo list', 'config_repo_list')
4247

43-
with self.command_group('spring-cloud app', client_factory=cf_spring_cloud_20201101preview) as g:
48+
with self.command_group('spring-cloud app', client_factory=cf_spring_cloud_20210601preview) as g:
4449
g.custom_command('create', 'app_create')
4550
g.custom_command('update', 'app_update')
4651
g.custom_command('deploy', 'app_deploy', supports_no_wait=True)
@@ -69,7 +74,7 @@ def load_command_table(self, _):
6974
deprecate_info=g.deprecate(redirect='az spring-cloud app logs', hide=True)) as g:
7075
g.custom_command('tail', 'app_tail_log')
7176

72-
with self.command_group('spring-cloud app deployment', client_factory=cf_spring_cloud) as g:
77+
with self.command_group('spring-cloud app deployment', client_factory=cf_spring_cloud_20210601preview) as g:
7378
g.custom_command('create', 'deployment_create', supports_no_wait=True)
7479
g.custom_command('list', 'deployment_list',
7580
table_transformer=transform_spring_cloud_deployment_output)

0 commit comments

Comments
 (0)