Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
3 changes: 3 additions & 0 deletions src/spring/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Release History
* Command `az spring create` and `az spring update` has new argument "--enable-log-stream-public-endpoint" to set whether assign public endpoint for log streaming in vnet injection instance.
* Command `az spring app create` and `az spring app update` has new argument "--assign_public_endpoint" to set whether assign endpoint URL which could be accessed out of virtual network for vnet injection instance app.
* Command `az spring app deploy` and `az spring app deployment create` has new argument "--build-cpu" and "--build-memory" to set cpu and memory during build process.
* Commands `az spring app create`, `az spring app update`, `az spring app deploy`, `spring app deployment create`
and `spring app deployment update` have new arguments "enable_liveness_probe", "enable_readiness_probe", "enable_startup_probe", "liveness_probe_config", "readiness_probe_config", "startup_probe_config" to customize the probe settings of user applications
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated


1.0.0
---
Expand Down
12 changes: 6 additions & 6 deletions src/spring/azext_spring/_app_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from msrestazure.azure_exceptions import CloudError
from azure.core.exceptions import (ResourceNotFoundError)
from ._resource_quantity import (validate_cpu as validate_cpu_value, validate_memory as validate_memory_value)
from ._client_factory import cf_spring_20220101preview
from ._client_factory import cf_spring_20220501preview


logger = get_logger(__name__)
Expand All @@ -21,7 +21,7 @@


def fulfill_deployment_param(cmd, namespace):
client = cf_spring_20220101preview(cmd.cli_ctx)
client = cf_spring_20220501preview(cmd.cli_ctx)
name = _get_app_name_from_namespace(namespace)
if not name or not namespace.service or not namespace.resource_group:
return
Expand All @@ -32,7 +32,7 @@ def fulfill_deployment_param(cmd, namespace):


def fulfill_deployment_param_or_warning(cmd, namespace):
client = cf_spring_20220101preview(cmd.cli_ctx)
client = cf_spring_20220501preview(cmd.cli_ctx)
name = _get_app_name_from_namespace(namespace)
if not name or not namespace.service or not namespace.resource_group:
return
Expand All @@ -48,7 +48,7 @@ def active_deployment_exist(cmd, namespace):
name = _get_app_name_from_namespace(namespace)
if not name or not namespace.service or not namespace.resource_group:
return
client = cf_spring_20220101preview(cmd.cli_ctx)
client = cf_spring_20220501preview(cmd.cli_ctx)
deployment = _get_active_deployment(client, namespace.resource_group, namespace.service, name)
if not deployment:
raise InvalidArgumentValueError(NO_PRODUCTION_DEPLOYMENT_SET_ERROR)
Expand All @@ -58,7 +58,7 @@ def active_deployment_exist_or_warning(cmd, namespace):
name = _get_app_name_from_namespace(namespace)
if not name or not namespace.service or not namespace.resource_group:
return
client = cf_spring_20220101preview(cmd.cli_ctx)
client = cf_spring_20220501preview(cmd.cli_ctx)
deployment = _get_active_deployment(client, namespace.resource_group, namespace.service, name)
if not deployment:
logger.warning(NO_PRODUCTION_DEPLOYMENT_SET_ERROR)
Expand All @@ -70,7 +70,7 @@ def ensure_not_active_deployment(cmd, namespace):
"""
if not namespace.deployment or not namespace.resource_group or not namespace.service or not namespace.name:
return
client = cf_spring_20220101preview(cmd.cli_ctx)
client = cf_spring_20220501preview(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))
Expand Down
93 changes: 89 additions & 4 deletions src/spring/azext_spring/_deployment_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

# pylint: disable=wrong-import-order
from azure.cli.core.azclierror import InvalidArgumentValueError
from azure.cli.core.util import get_file_json
from .vendored_sdks.appplatform.v2022_01_01_preview import models
from .vendored_sdks.appplatform.v2022_05_01_preview import models as models_20220501preview
from ._deployment_source_factory import source_selector


Expand All @@ -23,8 +25,8 @@ def validate_instance_count(self, instance_count):

def format_resource(self, sku=None, instance_count=None, active=None, **kwargs):
sku.capacity = instance_count
return models.DeploymentResource(
properties=models.DeploymentResourceProperties(
return models_20220501preview.DeploymentResource(
properties=models_20220501preview.DeploymentResourceProperties(
active=active,
source=self.format_source(**kwargs),
deployment_settings=self.format_settings(**kwargs)
Expand All @@ -33,13 +35,52 @@ def format_resource(self, sku=None, instance_count=None, active=None, **kwargs):
)

def format_settings(self, **kwargs):
return models.DeploymentSettings(
return models_20220501preview.DeploymentSettings(
resource_requests=self._format_resource_request(**kwargs),
container_probe_settings=self._format_container_probe(**kwargs),
environment_variables=self._get_env(**kwargs),
addon_configs=self._get_addon_configs(**kwargs)
addon_configs=self._get_addon_configs(**kwargs),
termination_grace_period_seconds=self._get_termination_grace_period_seconds(**kwargs),
startup_probe=self._format_startup_probe(**kwargs),
liveness_probe=self._format_liveness_probe(**kwargs),
readiness_probe=self._format_readiness_probe(**kwargs)
)

def _get_termination_grace_period_seconds(self, termination_seconds=None, **_):
if termination_seconds is None:
return None
return termination_seconds

def _format_startup_probe(self, enable_startup_probe=None, startup_probe_config_file_path=None, **_):
if enable_startup_probe is None:
return None

if not enable_startup_probe:
return models_20220501preview.Probe(disable_probe=True)

probe = self._load_probe_config(startup_probe_config_file_path)
return probe

def _format_liveness_probe(self, enable_liveness_probe=None, liveness_probe_config_file_path=None, **_):
if enable_liveness_probe is None:
return None

if not enable_liveness_probe:
return models_20220501preview.Probe(disable_probe=True)

probe = self._load_probe_config(liveness_probe_config_file_path)
return probe

def _format_readiness_probe(self, enable_readiness_probe=None, readiness_probe_config_file_path=None, **_):
if enable_readiness_probe is None:
return None

if not enable_readiness_probe:
return models_20220501preview.Probe(disable_probe=True)

probe = self._load_probe_config(readiness_probe_config_file_path)
return probe

def _format_container_probe(self, disable_probe=None, **_):
if disable_probe is None:
return None
Expand Down Expand Up @@ -101,6 +142,50 @@ def require_put_method(self, deployment_resource, source_type, **_):
return 'Container' in [source_type, deployment_resource.properties.source.type] and \
deployment_resource.properties.source.type != source_type

def _load_probe_config(self, probe_config=None, **_):
if not probe_config:
return
data = get_file_json(probe_config, throw_on_empty=False)
if not data:
return

if not data.get('probe'):
raise InvalidArgumentValueError("Probe must be provided in the json file")

invalidProperties = not data['probe'].get('probeAction') or \
not data['probe'].get('probeAction').get('type')
if invalidProperties:
raise InvalidArgumentValueError("probeAction, Type mast be provided in the json file")
probe_action = None
if data['probe']['probeAction']['type'].casefold() == "HTTPGetAction".casefold():
probe_action = models_20220501preview.HTTPGetAction(
type="HTTPGetAction",
path=data['probe']['probeAction']['path'] if 'path' in data['probe']['probeAction'] else None,
scheme=data['probe']['probeAction']['scheme'] if 'scheme' in data['probe']['probeAction'] else None,
)
elif data['probe']['probeAction']['type'].casefold() == "TCPSocketAction".casefold():
probe_action = models_20220501preview.TCPSocketAction(
type="TCPSocketAction",
)
elif data['probe']['probeAction']['type'].casefold() == "ExecAction".casefold():
probe_action = models_20220501preview.ExecAction(
type="ExecAction",
command=data['probe']['probeAction']['command'] if 'command' in data['probe']['probeAction'] else None,
)
else:
raise InvalidArgumentValueError("ProbeAction.Type is invalid")
probe_settings = models_20220501preview.Probe(
probe_action=probe_action,
disable_probe=False,
initial_delay_seconds=data['probe']['initialDelaySeconds'] if 'initialDelaySeconds' in data['probe'] else None,
period_seconds=data['probe']['periodSeconds'] if 'periodSeconds' in data['probe'] else None,
timeout_seconds=data['probe']['timeoutSeconds'] if 'timeoutSeconds' in data['probe'] else None,
failure_threshold=data['probe']['failureThreshold'] if 'failureThreshold' in data['probe'] else None,
success_threshold=data['probe']['successThreshold'] if 'successThreshold' in data['probe'] else None
)

return probe_settings


class EnterpriseDeployment(DefaultDeployment):
def _get_env(self, env, jvm_options, **_):
Expand Down
15 changes: 15 additions & 0 deletions src/spring/azext_spring/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,21 @@ def load_arguments(self, _):
c.argument('service', service_name_type)
c.argument('name', name_type, help='Name of app.')

for scope in ['spring app create', 'spring app update', 'spring app deploy', 'spring app deployment create', 'spring app deployment update']:
with self.argument_context(scope) as c:
c.argument('enable_liveness_probe', arg_type=get_three_state_flag(),
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated
help='If false, will disable the liveness probe of the app instance', arg_group='App Customization')
c.argument('enable_readiness_probe', arg_type=get_three_state_flag(),
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated
help='If false, will disable the readiness probe of the app instance', arg_group='App Customization')
c.argument('enable_startup_probe', arg_type=get_three_state_flag(),
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated
help='If false, will disable the startup probe of the app instance', arg_group='App Customization')
c.argument('liveness_probe_config', type=str,
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated
help='A json file path indicates the liveness probe config', arg_group='App Customization')
c.argument('readiness_probe_config', type=str,
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated
help='A json file path indicates the readiness probe config', arg_group='App Customization')
c.argument('startup_probe_config', type=str,
Comment thread
Caoxuyang marked this conversation as resolved.
Outdated
help='A json file path indicates the startup probe config', arg_group='App Customization')

with self.argument_context('spring app create') as c:
c.argument('assign_endpoint', arg_type=get_three_state_flag(),
help='If true, assign endpoint URL for direct access.', default=False,
Expand Down
50 changes: 49 additions & 1 deletion src/spring/azext_spring/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ def app_create(cmd, client, resource_group, service, name,
enable_persistent_storage=None,
persistent_storage=None,
assign_endpoint=None,
enable_liveness_probe=None,
enable_readiness_probe=None,
enable_startup_probe=None,
liveness_probe_config=None,
readiness_probe_config=None,
startup_probe_config=None,
assign_public_endpoint=None,
loaded_public_certificate_file=None):
'''app_create
Expand Down Expand Up @@ -92,6 +98,12 @@ def app_create(cmd, client, resource_group, service, name,
'env': env,
'runtime_version': runtime_version,
'jvm_options': jvm_options,
'enable_liveness_probe': enable_liveness_probe,
'enable_readiness_probe': enable_readiness_probe,
'enable_startup_probe': enable_startup_probe,
'liveness_probe_config_file_path': liveness_probe_config,
'readiness_probe_config_file_path': readiness_probe_config,
'startup_probe_config_file_path': startup_probe_config,
}
update_app_kwargs = {
'enable_persistent_storage': enable_persistent_storage,
Expand Down Expand Up @@ -145,6 +157,12 @@ def app_update(cmd, client, resource_group, service, name,
env=None,
disable_probe=None,
config_file_patterns=None,
enable_liveness_probe=None,
enable_readiness_probe=None,
enable_startup_probe=None,
liveness_probe_config=None,
readiness_probe_config=None,
startup_probe_config=None,
# general
no_wait=False):
'''app_update
Expand All @@ -171,7 +189,13 @@ def app_update(cmd, client, resource_group, service, name,
'runtime_version': runtime_version,
'jvm_options': jvm_options,
'main_entry': main_entry,
'source_type': deployment.properties.source.type if deployment else None
'source_type': deployment.properties.source.type if deployment else None,
'enable_liveness_probe': enable_liveness_probe,
'enable_readiness_probe': enable_readiness_probe,
'enable_startup_probe': enable_startup_probe,
'liveness_probe_config_file_path': liveness_probe_config,
'readiness_probe_config_file_path': readiness_probe_config,
'startup_probe_config_file_path': startup_probe_config,
}

app_kwargs = {
Expand Down Expand Up @@ -238,6 +262,12 @@ def app_deploy(cmd, client, resource_group, service, name,
env=None,
disable_probe=None,
config_file_patterns=None,
enable_liveness_probe=None,
enable_readiness_probe=None,
enable_startup_probe=None,
liveness_probe_config=None,
readiness_probe_config=None,
startup_probe_config=None,
# general
no_wait=False):
'''app_deploy
Expand Down Expand Up @@ -280,6 +310,12 @@ def app_deploy(cmd, client, resource_group, service, name,
'build_cpu': build_cpu,
'build_memory': build_memory,
'builder': builder,
'enable_liveness_probe': enable_liveness_probe,
'enable_readiness_probe': enable_readiness_probe,
'enable_startup_probe': enable_startup_probe,
'liveness_probe_config_file_path': liveness_probe_config,
'readiness_probe_config_file_path': readiness_probe_config,
'startup_probe_config_file_path': startup_probe_config,
'no_wait': no_wait
}

Expand Down Expand Up @@ -331,6 +367,12 @@ def deployment_create(cmd, client, resource_group, service, app, name,
env=None,
disable_probe=None,
config_file_patterns=None,
enable_liveness_probe=None,
enable_readiness_probe=None,
enable_startup_probe=None,
liveness_probe_config=None,
readiness_probe_config=None,
startup_probe_config=None,
# general
no_wait=False):
'''deployment_create
Expand Down Expand Up @@ -372,6 +414,12 @@ def deployment_create(cmd, client, resource_group, service, app, name,
'instance_count': instance_count,
'build_env': build_env,
'builder': builder,
'enable_liveness_probe': enable_liveness_probe,
'enable_readiness_probe': enable_readiness_probe,
'enable_startup_probe': enable_startup_probe,
'liveness_probe_config_file_path': liveness_probe_config,
'readiness_probe_config_file_path': readiness_probe_config,
'startup_probe_config_file_path': startup_probe_config,
'no_wait': no_wait
}

Expand Down
7 changes: 3 additions & 4 deletions src/spring/azext_spring/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def load_command_table(self, _):
g.custom_command('create', 'app_create')
g.custom_command('update', 'app_update', supports_no_wait=True)

with self.command_group('spring app', client_factory=cf_spring_20220101preview,
with self.command_group('spring app', client_factory=cf_spring_20220501preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('set-deployment', 'app_set_deployment',
supports_no_wait=True)
Expand All @@ -143,8 +143,7 @@ def load_command_table(self, _):
g.custom_command('list', 'app_list',
table_transformer=transform_app_table_output)
g.custom_show_command(
'show', 'app_get', table_transformer=transform_app_table_output,
client_factory=cf_spring_20220501preview)
'show', 'app_get', table_transformer=transform_app_table_output)
g.custom_command('start', 'app_start', supports_no_wait=True)
g.custom_command('stop', 'app_stop', supports_no_wait=True)
g.custom_command('restart', 'app_restart', supports_no_wait=True)
Expand Down Expand Up @@ -172,7 +171,7 @@ def load_command_table(self, _):
exception_handler=handle_asc_exception) as g:
g.custom_command('create', 'deployment_create', supports_no_wait=True)

with self.command_group('spring app deployment', client_factory=cf_spring_20220101preview,
with self.command_group('spring app deployment', client_factory=cf_spring_20220501preview,
exception_handler=handle_asc_exception) as g:
g.custom_command('list', 'deployment_list',
table_transformer=transform_spring_deployment_output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ interactions:
User-Agent:
- AZURECLI/2.34.1 azsdk-python-mgmt-appplatform/6.1.0 Python/3.9.5 (Windows-10-10.0.22000-SP0)
method: GET
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli/providers/Microsoft.AppPlatform/Spring/cli-unittest/apps/test-msi-app-1/deployments?api-version=2022-01-01-preview
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli/providers/Microsoft.AppPlatform/Spring/cli-unittest/apps/test-msi-app-1/deployments?api-version=2022-05-01-preview
response:
body:
string: '{"value":[{"properties":{"source":{"type":"Jar","relativePath":"<default>","runtimeVersion":"Java_8"},"deploymentSettings":{"resourceRequests":{"cpu":"1","memory":"1Gi"},"environmentVariables":null},"provisioningState":"Succeeded","status":"Running","active":true,"instances":[{"name":"test-msi-app-1-default-14-c64d57654-qkhf7","status":"Running","reason":"Unschedulable","discoveryStatus":"UNKNOWN","startTime":"2022-03-20T14:03:39Z"}]},"type":"Microsoft.AppPlatform/Spring/apps/deployments","sku":{"name":"S0","tier":"Standard","capacity":1},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli/providers/Microsoft.AppPlatform/Spring/cli-unittest/apps/test-msi-app-1/deployments/default","name":"default","systemData":{"createdBy":"jiec@microsoft.com","createdByType":"User","createdAt":"2022-03-20T14:03:34.571185Z","lastModifiedBy":"jiec@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2022-03-20T14:03:34.571185Z"}}]}'
Expand Down
Loading