Skip to content

Commit d0251da

Browse files
authored
Add ACS related commands (Azure#18)
1 parent 9b6ae7b commit d0251da

File tree

4 files changed

+308
-0
lines changed

4 files changed

+308
-0
lines changed

src/spring-cloud/azext_spring_cloud/_help.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,3 +487,58 @@
487487
- name: Unbind an app to Service Registry.
488488
text: az spring-cloud service-registry unbind --app MyApp -s MyService -g MyResourceGroup
489489
"""
490+
491+
helps['spring-cloud application-configuration-service show'] = """
492+
type: command
493+
short-summary: Show provisioning status, runtime status and settings of Application Configuration Service.
494+
"""
495+
496+
helps['spring-cloud application-configuration-service clear'] = """
497+
type: command
498+
short-summary: Reset all Application Configuration Service settings.
499+
"""
500+
501+
helps['spring-cloud application-configuration-service git repo add'] = """
502+
type: command
503+
short-summary: Add an item of git property to Application Configuration Service settings.
504+
examples:
505+
- name: Add an item of git property.
506+
text: az spring-cloud application-configuration-service git repo add -s MyService -g MyResourceGroup --name MyName --patterns MyPattern --uri https://MyURI --label master
507+
"""
508+
509+
helps['spring-cloud application-configuration-service git repo update'] = """
510+
type: command
511+
short-summary: Update an existing item of git property to Application Configuration Service settings.
512+
examples:
513+
- name: Update an item of git property.
514+
text: az spring-cloud application-configuration-service git repo update -s MyService -g MyResourceGroup --name MyName --patterns MyPattern
515+
"""
516+
517+
helps['spring-cloud application-configuration-service git repo remove'] = """
518+
type: command
519+
short-summary: Delete an existing item of git property to Application Configuration Service settings.
520+
examples:
521+
- name: Delete an item of git property.
522+
text: az spring-cloud application-configuration-service git repo remove -s MyService -g MyResourceGroup --name MyName
523+
"""
524+
525+
helps['spring-cloud application-configuration-service git repo list'] = """
526+
type: command
527+
short-summary: List all git settings of Application Configuration Service.
528+
"""
529+
530+
helps['spring-cloud application-configuration-service bind'] = """
531+
type: command
532+
short-summary: Bind app to Application Configuration Service.
533+
examples:
534+
- name: Bind an app to Application Configuration Service.
535+
text: az spring-cloud application-configuration-service bind --app MyApp -s MyService -g MyResourceGroup
536+
"""
537+
538+
helps['spring-cloud application-configuration-service unbind'] = """
539+
type: command
540+
short-summary: Unbind app to Application Configuration Service.
541+
examples:
542+
- name: Unbind an app to Application Configuration Service.
543+
text: az spring-cloud application-configuration-service unbind --app MyApp -s MyService -g MyResourceGroup
544+
"""

src/spring-cloud/azext_spring_cloud/_params.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,30 @@ def prepare_logs_argument(c):
288288

289289
with self.argument_context('spring-cloud service-registry unbind') as c:
290290
c.argument('app', app_name_type, help='Name of app.', validator=validate_app_name)
291+
292+
with self.argument_context('spring-cloud application-configuration-service bind') as c:
293+
c.argument('app', app_name_type, help='Name of app.', validator=validate_app_name)
294+
295+
with self.argument_context('spring-cloud application-configuration-service unbind') as c:
296+
c.argument('app', app_name_type, help='Name of app.', validator=validate_app_name)
297+
298+
for scope in ['spring-cloud application-configuration-service git repo add',
299+
'spring-cloud application-configuration-service git repo update']:
300+
with self.argument_context(scope) as c:
301+
c.argument('patterns',
302+
help="Required patterns used to search in Git repositories. For each pattern, use format like {application} or {application}/{profile} instead of {application}-{profile}.yml, and separate them by comma."),
303+
c.argument('uri', help="Required Git URI."),
304+
c.argument('label', help="Required branch name to search in the Git repository."),
305+
c.argument('search_paths', help='search_paths of the added config, use , as delimiter for multiple paths.')
306+
c.argument('username', help='Username of the added config.')
307+
c.argument('password', help='Password of the added config.')
308+
c.argument('host_key', help='Host key of the added config.')
309+
c.argument('host_key_algorithm', help='Host key algorithm of the added config.')
310+
c.argument('private_key', help='Private_key of the added config.')
311+
c.argument('strict_host_key_checking', help='Strict_host_key_checking of the added config.')
312+
313+
for scope in ['spring-cloud application-configuration-service git repo add',
314+
'spring-cloud application-configuration-service git repo update',
315+
'spring-cloud application-configuration-service git repo remove']:
316+
with self.argument_context(scope) as c:
317+
c.argument('name', help="Required unique name to label each item of git configs.")
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
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+
# pylint: disable=unused-argument, logging-format-interpolation, protected-access, wrong-import-order, too-many-lines
7+
import json
8+
9+
from ._enterprise import app_get_enterprise
10+
from ._util_enterprise import (is_enterprise_tier, get_client)
11+
from .vendored_sdks.appplatform.v2022_05_01_preview import models as models
12+
from azure.cli.core.commands import cached_put
13+
from azure.cli.core.util import sdk_no_wait
14+
from knack.log import get_logger
15+
from knack.util import CLIError
16+
17+
APPLICATION_CONFIGURATION_SERVICE_NAME = "ApplicationConfigurationService"
18+
19+
logger = get_logger(__name__)
20+
21+
def application_configuration_service_show(cmd, client, service, resource_group):
22+
return client.configuration_services.get(resource_group, service)
23+
24+
25+
def application_configuration_service_clear(cmd, client, service, resource_group):
26+
properties = models.ConfigurationServiceGitProperty()
27+
acs_resource = models.ConfigurationServiceResource(properties=properties)
28+
return client.configuration_services.begin_create_or_update(resource_group, service, acs_resource)
29+
30+
31+
def application_configuration_service_git_add(cmd, client, service, resource_group,
32+
name, patterns, uri, label,
33+
search_paths=None,
34+
username=None,
35+
password=None,
36+
host_key=None,
37+
host_key_algorithm=None,
38+
private_key=None,
39+
strict_host_key_checking=None,
40+
no_wait=False):
41+
repo = models.ConfigurationServiceGitRepository(name=name, patterns=patterns, uri=uri, label=label)
42+
repo = _replace_repo_with_input(repo, patterns, uri, label, search_paths, username, password, host_key, host_key_algorithm, private_key, strict_host_key_checking)
43+
44+
acs_resource = _get_or_default_acs_resource(client, resource_group, service)
45+
repos = acs_resource.properties.settings.git_property.repositories
46+
if next((r for r in repos if r.name == name), None) is not None:
47+
raise CLIError("Repo '{}' already exists.".format(name))
48+
repos.append(repo)
49+
acs_resource.properties.settings.git_property.repositories = repos
50+
51+
_validate_acs_settings(client, resource_group, service, acs_resource.properties.settings)
52+
53+
logger.warning("[2/2] Adding item to Application Configuration Service settings, (this operation can take a while to complete)")
54+
return sdk_no_wait(no_wait, client.configuration_services.begin_create_or_update, resource_group, service, acs_resource)
55+
56+
57+
def application_configuration_service_git_update(cmd, client, service, resource_group, name,
58+
patterns=None,
59+
uri=None,
60+
label=None,
61+
search_paths=None,
62+
username=None,
63+
password=None,
64+
host_key=None,
65+
host_key_algorithm=None,
66+
private_key=None,
67+
strict_host_key_checking=None,
68+
no_wait=False):
69+
acs_resource = _get_or_default_acs_resource(client, resource_group, service)
70+
71+
repo = _get_existing_repo(acs_resource.properties.settings.git_property.repositories, name)
72+
repo = _replace_repo_with_input(repo, patterns, uri, label, search_paths, username, password, host_key, host_key_algorithm, private_key, strict_host_key_checking)
73+
74+
_validate_acs_settings(client, resource_group, service, acs_resource.properties.settings)
75+
76+
logger.warning("[2/2] Updating item of Application Configuration Service settings, (this operation can take a while to complete)")
77+
return sdk_no_wait(no_wait, client.configuration_services.begin_create_or_update, resource_group, service, acs_resource)
78+
79+
80+
def application_configuration_service_git_remove(cmd, client, service, resource_group, name, no_wait=False):
81+
acs_resource = _get_or_default_acs_resource(acs_resource)
82+
83+
repo = _get_existing_repo(acs_resource.properties.settings.git_property.repositories, name)
84+
acs_resource.properties.settings.git_property.repositories.remove(repo)
85+
86+
_validate_acs_settings(client, resource_group, service, acs_resource.properties.settings)
87+
88+
logger.warning("[2/2] Removing item of Application Configuration Service settings, (this operation can take a while to complete)")
89+
return sdk_no_wait(no_wait, client.configuration_services.begin_create_or_update, resource_group, service, acs_resource)
90+
91+
92+
def application_configuration_service_git_list(cmd, client, service, resource_group):
93+
acs_resource = client.configuration_services.get(resource_group, service)
94+
acs_settings = acs_resource.properties.settings
95+
96+
if not acs_settings or not acs_settings.git_property or not acs_settings.git_property.repositories:
97+
raise CLIError("Repos not found.")
98+
99+
return acs_settings.git_property.repositories
100+
101+
102+
def application_configuration_service_bind(cmd, client, service, resource_group, app):
103+
_acs_bind_or_unbind_app(cmd, client, service, resource_group, app, True)
104+
105+
106+
def application_configuration_service_unbind(cmd, client, service, resource_group, app):
107+
_acs_bind_or_unbind_app(cmd, client, service, resource_group, app, False)
108+
109+
110+
def _acs_bind_or_unbind_app(cmd, client, service, resource_group, app_name, enabled):
111+
app = client.apps.get(resource_group, service, app_name)
112+
app.properties.addon_configs = _get_app_addon_configs_with_acs(app.properties.addon_configs)
113+
114+
if app.properties.addon_configs[APPLICATION_CONFIGURATION_SERVICE_NAME].enabled == enabled:
115+
logger.warning('App "{}" has been {}binded'.format(app_name, '' if enabled else 'un'))
116+
return
117+
118+
app.properties.addon_configs[APPLICATION_CONFIGURATION_SERVICE_NAME].enabled = enabled
119+
return client.apps.begin_update(resource_group, service, app_name, app)
120+
121+
122+
def _get_app_addon_configs_with_acs(addon_configs):
123+
if addon_configs is None:
124+
addon_configs = {}
125+
if addon_configs.get(APPLICATION_CONFIGURATION_SERVICE_NAME) is None:
126+
addon_configs[APPLICATION_CONFIGURATION_SERVICE_NAME] = models.AddonProfile()
127+
return addon_configs
128+
129+
130+
def _replace_repo_with_input(repo, patterns, uri, label, search_paths, username, password, host_key, host_key_algorithm, private_key, strict_host_key_checking):
131+
if patterns:
132+
patterns = patterns.split(",")
133+
if search_paths:
134+
search_paths = search_paths.split(",")
135+
136+
repo.patterns = patterns or repo.patterns
137+
repo.uri = uri or repo.uri
138+
repo.label = label or repo.label
139+
repo.search_paths = search_paths or repo.search_paths
140+
repo.username = username or repo.username
141+
repo.password = password or repo.password
142+
repo.host_key = host_key or repo.host_key
143+
repo.host_key_algorithm = host_key_algorithm or repo.host_key_algorithm
144+
repo.private_key = private_key or repo.private_key
145+
repo.strict_host_key_checking = strict_host_key_checking or repo.strict_host_key_checking
146+
return repo
147+
148+
149+
def _get_existing_repo(repos, name):
150+
repo = next((r for r in repos if r.name == name), None)
151+
if not repo:
152+
raise CLIError("Repo '{}' not found.".format(name))
153+
return repo
154+
155+
156+
def _get_or_default_acs_resource(client, resource_group, service):
157+
acs_resource = client.configuration_services.get(resource_group, service)
158+
if acs_resource is None:
159+
acs_resource = models.ConfigurationServiceResource()
160+
acs_resource.properties = _get_acs_properties(acs_resource.properties)
161+
return acs_resource
162+
163+
164+
def _get_acs_properties(properties):
165+
if properties is None:
166+
properties = models.ConfigurationServiceProperties()
167+
properties.settings = _get_acs_settings(properties.settings)
168+
return properties
169+
170+
171+
def _get_acs_settings(acs_settings):
172+
if acs_settings is None:
173+
acs_settings = models.ConfigurationServiceSettings()
174+
acs_settings.git_property = _get_acs_git_property(acs_settings.git_property)
175+
return acs_settings
176+
177+
178+
def _get_acs_git_property(git_property):
179+
if git_property is None:
180+
git_property = models.ConfigurationServiceGitProperty()
181+
git_property.repositories = _get_acs_repos(git_property.repositories)
182+
return git_property
183+
184+
185+
def _get_acs_repos(repos):
186+
return repos or []
187+
188+
189+
def _validate_acs_settings(client, resource_group, service, acs_settings):
190+
logger.warning("[1/2] Validating Application Configuration Service settings")
191+
192+
if acs_settings is None or acs_settings.git_property is None:
193+
return
194+
195+
try:
196+
result = sdk_no_wait(False, client.configuration_services.begin_validate, resource_group, service, acs_settings).result()
197+
except Exception as err: # pylint: disable=broad-except
198+
raise CLIError("{0}. You may raise a support ticket if needed by the following link: https://docs.microsoft.com/azure/spring-cloud/spring-cloud-faq?pivots=programming-language-java#how-can-i-provide-feedback-and-report-issues".format(err))
199+
200+
if result is not None and result.git_property_validation_result is not None:
201+
git_result = result.git_property_validation_result
202+
if not git_result.is_valid:
203+
validation_result = git_result.git_repos_validation_result
204+
filter_result = [{'name':x.name, 'messages':x.messages} for x in validation_result if len(x.messages) > 0]
205+
raise CLIError("Application Configuration Service settings contain errors.\n{}".format(json.dumps(filter_result, indent=2)))

src/spring-cloud/azext_spring_cloud/commands.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ def load_command_table(self, _):
3737
client_factory=cf_spring_cloud_enterprise
3838
)
3939

40+
application_configuration_service_cmd_group = CliCommandType(
41+
operations_tmpl='azext_spring_cloud.application_configuration_service#{}',
42+
client_factory=cf_spring_cloud_enterprise
43+
)
44+
4045
with self.command_group('spring-cloud', client_factory=cf_app_services,
4146
exception_handler=handle_asc_exception) as g:
4247
g.custom_command('create', 'spring_cloud_create', supports_no_wait=True, client_factory=cf_spring_cloud)
@@ -150,5 +155,21 @@ def load_command_table(self, _):
150155
g.custom_command('bind', 'service_registry_bind')
151156
g.custom_command('unbind', 'service_registry_unbind')
152157

158+
with self.command_group('spring-cloud application-configuration-service',
159+
custom_command_type=application_configuration_service_cmd_group,
160+
exception_handler=handle_asc_exception) as g:
161+
g.custom_command('clear', 'application_configuration_service_clear')
162+
g.custom_command('show', 'application_configuration_service_show')
163+
g.custom_command('bind', 'application_configuration_service_bind')
164+
g.custom_command('unbind', 'application_configuration_service_unbind')
165+
166+
with self.command_group('spring-cloud application-configuration-service git repo',
167+
custom_command_type=application_configuration_service_cmd_group,
168+
exception_handler=handle_asc_exception) as g:
169+
g.custom_command('add', 'application_configuration_service_git_add')
170+
g.custom_command('update', 'application_configuration_service_git_update')
171+
g.custom_command('remove', 'application_configuration_service_git_remove')
172+
g.custom_command('list', 'application_configuration_service_git_list')
173+
153174
with self.command_group('spring-cloud', exception_handler=handle_asc_exception):
154175
pass

0 commit comments

Comments
 (0)