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

[Spring] Add addon configs & allowedOriginPatterns & restart for Spring Cloud Gateway #6412

Merged
merged 4 commits into from
Jun 19, 2023
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
5 changes: 5 additions & 0 deletions src/spring/HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Release History
===============
1.13.3
---
* Add arguments `--allowed-origin-patterns`, `--addon-configs-json` and `--addon-configs-file` in `az spring gateway update`.
* Add new command `az spring gateway restart` to restart Spring Cloud Gateway.

1.13.2
---
* Add argument `--build-certificates` in `az spring app deploy`.
Expand Down
8 changes: 8 additions & 0 deletions src/spring/azext_spring/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,14 @@
text: az spring gateway update -s MyService -g MyResourceGroup --assign-endpoint true --https-only true
"""

helps['spring gateway restart'] = """
type: command
short-summary: Restart Spring Cloud Gateway.
examples:
- name: Restart Spring Cloud Gateway.
text: az spring gateway restart -s MyService -g MyResourceGroup
"""

helps['spring gateway sync-cert'] = """
type: command
short-summary: Sync certificate of gateway.
Expand Down
6 changes: 6 additions & 0 deletions src/spring/azext_spring/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,10 @@ def prepare_logs_argument(c):
help='Sensitive properties for environment variables. Once put, it will be encrypted and not returned.'
'Format "key[=value]" and separated by space.')
c.argument('allowed_origins', arg_group='Cross-origin Resource Sharing (CORS)', help="Comma-separated list of allowed origins to make cross-site requests. The special value `*` allows all domains.")
Copy link
Contributor

@zhoxing-ms zhoxing-ms Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, it is recommended to deprecate and hide the existing parameter --allowed-origins and replace it with a new parameter --allow-origins

It is recommended to keep the naming of parameter allowed_origins consistent with parameter allowed_origin_patterns

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As talked offline, we will keep the name consistent with other parameters first, which is referenced from VMware's product Spring Cloud Gateway. Later will consider to deprecate those parameters together.

c.argument('allowed_origin_patterns',
arg_group='Cross-origin Resource Sharing (CORS)',
options_list=['--allowed-origin-patterns', '--allow-origin-patterns'],
ninpan-ms marked this conversation as resolved.
Show resolved Hide resolved
help="Comma-separated list of allowed origin patterns to make cross-site requests.")
c.argument('allowed_methods', arg_group='Cross-origin Resource Sharing (CORS)', help="Comma-separated list of allowed HTTP methods on cross-site requests. The special value `*` allows all methods.")
c.argument('allowed_headers', arg_group='Cross-origin Resource Sharing (CORS)', help="Comma-separated list of allowed headers in cross-site requests. The special value `*` allows actual requests to send any header.")
c.argument('max_age', arg_group='Cross-origin Resource Sharing (CORS)', type=int,
Expand All @@ -873,6 +877,8 @@ def prepare_logs_argument(c):
options_list=['--enable-certificate-verification', '--enable-cert-verify'],
help='If true, will verify certificate in TLS connection from gateway to app.')
c.argument('certificate_names', arg_group='Client Certificate Authentication', help="Comma-separated list of certificate names in Azure Spring Apps.")
c.argument('addon_configs_json', arg_group='Add-on Configurations', help="JSON string of add-on configurations.")
c.argument('addon_configs_file', arg_group='Add-on Configurations', help="The file path of JSON string of add-on configurations.")

for scope in ['spring gateway custom-domain',
'spring api-portal custom-domain']:
Expand Down
1 change: 1 addition & 0 deletions src/spring/azext_spring/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ def load_command_table(self, _):
g.custom_command('clear', 'gateway_clear', supports_no_wait=True)
g.custom_command('create', 'gateway_create', table_transformer=transform_spring_cloud_gateway_output)
g.custom_command('delete', 'gateway_delete', confirmation=True)
g.custom_command('restart', 'gateway_restart', confirmation='Are you sure you want to perform this operation?', supports_no_wait=True)
g.custom_command('sync-cert', 'gateway_sync_cert', confirmation='Your gateway will be restarted to use the latest certificate.\n' +
'Are you sure you want to perform this operation?', supports_no_wait=True)

Expand Down
35 changes: 31 additions & 4 deletions src/spring/azext_spring/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from knack.log import get_logger

from .custom import LOG_RUNNING_PROMPT
from .vendored_sdks.appplatform.v2023_03_01_preview import models
from .vendored_sdks.appplatform.v2023_05_01_preview import models
from ._utils import get_spring_sku

logger = get_logger(__name__)
Expand Down Expand Up @@ -49,13 +49,16 @@ def gateway_update(cmd, client, resource_group, service,
properties=None,
secrets=None,
allowed_origins=None,
allowed_origin_patterns=None,
allowed_methods=None,
allowed_headers=None,
max_age=None,
allow_credentials=None,
exposed_headers=None,
enable_certificate_verification=None,
certificate_names=None,
addon_configs_json=None,
addon_configs_file=None,
no_wait=False
):
gateway = client.gateways.get(resource_group, service, DEFAULT_NAME)
Expand All @@ -77,7 +80,7 @@ def gateway_update(cmd, client, resource_group, service,
gateway.properties.api_metadata_properties, api_title, api_description, api_doc_location, api_version, server_url)

cors_properties = _update_cors(
gateway.properties.cors_properties, allowed_origins, allowed_methods, allowed_headers, max_age, allow_credentials, exposed_headers)
gateway.properties.cors_properties, allowed_origins, allowed_origin_patterns, allowed_methods, allowed_headers, max_age, allow_credentials, exposed_headers)

client_auth = _update_client_auth(client, resource_group, service,
gateway.properties.client_auth, enable_certificate_verification, certificate_names)
Expand All @@ -90,6 +93,8 @@ def gateway_update(cmd, client, resource_group, service,
update_apm_types = apm_types if apm_types is not None else gateway.properties.apm_types
environment_variables = _update_envs(gateway.properties.environment_variables, properties, secrets)

addon_configs = _update_addon_configs(gateway.properties.addon_configs, addon_configs_json, addon_configs_file)

model_properties = models.GatewayProperties(
public=assign_endpoint if assign_endpoint is not None else gateway.properties.public,
https_only=https_only if https_only is not None else gateway.properties.https_only,
Expand All @@ -99,6 +104,7 @@ def gateway_update(cmd, client, resource_group, service,
apm_types=update_apm_types,
environment_variables=environment_variables,
client_auth=client_auth,
addon_configs=addon_configs,
resource_requests=resource_requests)

sku = models.Sku(name=gateway.sku.name, tier=gateway.sku.tier,
Expand Down Expand Up @@ -126,6 +132,10 @@ def gateway_clear(cmd, client, resource_group, service, no_wait=False):
resource_group, service, DEFAULT_NAME, gateway_resource)


def gateway_restart(cmd, client, service, resource_group, no_wait=False):
return client.gateways.begin_restart(resource_group, service, DEFAULT_NAME)


def gateway_sync_cert(cmd, client, service, resource_group, no_wait=False):
return client.gateways.begin_restart(resource_group, service, DEFAULT_NAME)

Expand Down Expand Up @@ -209,12 +219,14 @@ def _update_api_metadata(existing, api_title, api_description, api_documentation
return api_metadata


def _update_cors(existing, allowed_origins, allowed_methods, allowed_headers, max_age, allow_credentials, exposed_headers):
if allowed_origins is None and allowed_methods is None and allowed_headers is None and max_age is None and allow_credentials is None and exposed_headers is None:
def _update_cors(existing, allowed_origins, allowed_origin_patterns, allowed_methods, allowed_headers, max_age, allow_credentials, exposed_headers):
if allowed_origins is None and allowed_origin_patterns is None and allowed_methods is None and allowed_headers is None and max_age is None and allow_credentials is None and exposed_headers is None:
return existing
cors = existing if existing is not None else models.GatewayCorsProperties()
if allowed_origins is not None:
cors.allowed_origins = allowed_origins.split(",") if allowed_origins else None
if allowed_origin_patterns is not None:
cors.allowed_origin_patterns = allowed_origin_patterns.split(",") if allowed_origin_patterns else None
if allowed_methods is not None:
cors.allowed_methods = allowed_methods.split(",") if allowed_methods else None
if allowed_headers is not None:
Expand Down Expand Up @@ -261,6 +273,21 @@ def _update_client_auth(client, resource_group, service, existing, enable_certif
return client_auth


def _update_addon_configs(existing, addon_configs_json, addon_configs_file):
if addon_configs_file is None and addon_configs_json is None:
return existing

raw_json = {}
if addon_configs_file is not None:
with open(addon_configs_file, 'r') as json_file:
raw_json = json.load(json_file)

if addon_configs_json is not None:
raw_json = json.loads(addon_configs_json)

return raw_json


def _validate_route_config_not_exist(client, resource_group, service, name):
route_configs = client.gateway_route_configs.list(
resource_group, service, DEFAULT_NAME)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"javaopts": "-Djava.awt.headless=true",
"sso": {
"rolesAttributeName": "role",
"inactiveSessionExpirationInMinutes": 1
},
"envs": [
{
"name": "xxx",
"value": "yyy"
},
{
"name": "xxx1",
"value": "yyy"
}
]
}
Loading