Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support probe feature in 0501-preview #4899

Merged
merged 18 commits into from
May 26, 2022
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
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved


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(),
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved
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(),
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved
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(),
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved
help='If false, will disable the startup probe of the app instance', arg_group='App Customization')
c.argument('liveness_probe_config', type=str,
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved
help='A json file path indicates the liveness probe config', arg_group='App Customization')
c.argument('readiness_probe_config', type=str,
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved
help='A json file path indicates the readiness probe config', arg_group='App Customization')
c.argument('startup_probe_config', type=str,
Caoxuyang marked this conversation as resolved.
Show resolved Hide resolved
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":"[email protected]","createdByType":"User","createdAt":"2022-03-20T14:03:34.571185Z","lastModifiedBy":"[email protected]","lastModifiedByType":"User","lastModifiedAt":"2022-03-20T14:03:34.571185Z"}}]}'
Expand Down
Loading