Skip to content

Commit 2872c55

Browse files
authored
add az vmware script* (Azure#3722)
* custom action for script execution params * script-execution tests recorded * package and cmdlet tests passing * update help * add named outputs * recording are generated * mv .gitattributes to root * mv .gitattributes * it is in azext_vmware * fix style * fix linter errors * suppress cred scan false positive * remove credential test * raise InvalidArgumentValueError, RequiredArgumentMissingError
1 parent f2ad727 commit 2872c55

File tree

12 files changed

+875
-16
lines changed

12 files changed

+875
-16
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/vmware/azext_vmware/tests/latest/recordings/*.yaml linguist-generated=true

src/vmware/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Release History
22

3-
## 3.1.0 (2021-07)
3+
## 3.1.0 (2021-08)
44
- Add `az vmware cloud-link` command group
5+
- Add `az vmware script-cmdlet` command group
6+
- Add `az vmware script-execution` command group
7+
- Add `az vmware script-package` command group
58

69
## 3.0.0 (2021-07)
710
- [BREAKING CHANGE] `az vmware datastore create` has been removed. Please use `az vmware datastore netapp-volume create` or `az vmware datastore disk-pool-volume create` instead.

src/vmware/azext_vmware/_help.py

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -384,20 +384,12 @@
384384

385385
helps['vmware cloud-link create'] = """
386386
type: command
387-
short-summary: Create a cloud link in a private cloud.
387+
short-summary: Create or update a cloud link in a private cloud.
388388
examples:
389389
- name: Create a cloud link.
390390
text: az vmware cloud-link create --resource-group group1 --private-cloud cloud1 --name cloudLink1 --linked-cloud "/subscriptions/12341234-1234-1234-1234-123412341234/resourceGroups/mygroup/providers/Microsoft.AVS/privateClouds/cloud2"
391391
"""
392392

393-
helps['vmware cloud-link update'] = """
394-
type: command
395-
short-summary: Create a cloud link in a private cloud.
396-
examples:
397-
- name: Update a cloud link.
398-
text: az vmware cloud-link update --resource-group group1 --private-cloud cloud1 --name cloudLink1 --linked-cloud "/subscriptions/12341234-1234-1234-1234-123412341234/resourceGroups/mygroup/providers/Microsoft.AVS/privateClouds/cloud2"
399-
"""
400-
401393
helps['vmware cloud-link list'] = """
402394
type: command
403395
short-summary: List cloud links in a private cloud.
@@ -421,3 +413,82 @@
421413
- name: Delete a cloud link.
422414
text: az vmware cloud-link delete --resource-group group1 --private-cloud cloud1 --name cloudLink1
423415
"""
416+
417+
helps['vmware script-cmdlet'] = """
418+
type: group
419+
short-summary: Commands to list and show script cmdlet resources.
420+
"""
421+
422+
helps['vmware script-cmdlet list'] = """
423+
type: command
424+
short-summary: List script cmdlet resources available for a private cloud to create a script execution resource on a private cloud.
425+
examples:
426+
- name: List script cmdlet resources.
427+
text: az vmware script-cmdlet list --resource-group group1 --private-cloud cloud1 --script-package package1
428+
"""
429+
430+
helps['vmware script-cmdlet show'] = """
431+
type: command
432+
short-summary: Get information about a script cmdlet resource in a specific package on a private cloud.
433+
examples:
434+
- name: Show a script cmdlet.
435+
text: az vmware script-cmdlet show --resource-group group1 --private-cloud cloud1 --script-package package1 --name cmdlet1
436+
"""
437+
438+
helps['vmware script-package'] = """
439+
type: group
440+
short-summary: Commands to list and show script packages available to run on the private cloud.
441+
"""
442+
443+
helps['vmware script-package list'] = """
444+
type: command
445+
short-summary: List script packages available to run on the private cloud.
446+
examples:
447+
- name: List script packages.
448+
text: az vmware script-package list --resource-group group1 --private-cloud cloud1
449+
"""
450+
451+
helps['vmware script-package show'] = """
452+
type: command
453+
short-summary: Get a script package available to run on a private cloud.
454+
examples:
455+
- name: Show a script package.
456+
text: az vmware script-package show --resource-group group1 --private-cloud cloud1 --name package1
457+
"""
458+
459+
helps['vmware script-execution'] = """
460+
type: group
461+
short-summary: Commands to manage script executions in a private cloud.
462+
"""
463+
464+
helps['vmware script-execution create'] = """
465+
type: command
466+
short-summary: Create or update a script execution in a private cloud.
467+
examples:
468+
- name: Create a script execution.
469+
text: az vmware script-execution create --resource-group group1 --private-cloud cloud1 --name addSsoServer --script-cmdlet-id "/subscriptions/{subscription-id}/resourceGroups/group1/providers/Microsoft.AVS/privateClouds/cloud1/scriptPackages/[email protected]/scriptCmdlets/New-SsoExternalIdentitySource" --timeout P0Y0M0DT0H60M60S --retention P0Y0M60DT0H60M60S --parameter name=DomainName type=Value value=placeholderDomain.local --parameter name=BaseUserDN type=Value "value=DC=placeholder, DC=placeholder" --hidden-parameter name=Password type=SecureValue secureValue=PlaceholderPassword
470+
"""
471+
472+
helps['vmware script-execution list'] = """
473+
type: command
474+
short-summary: List script executions in a private cloud.
475+
examples:
476+
- name: List script executions.
477+
text: az vmware script-execution list --resource-group group1 --private-cloud cloud1
478+
"""
479+
480+
helps['vmware script-execution show'] = """
481+
type: command
482+
short-summary: Get an script execution by name in a private cloud.
483+
examples:
484+
- name: Show a script execution.
485+
text: az vmware script-execution show --resource-group group1 --private-cloud cloud1 --name addSsoServer
486+
"""
487+
488+
helps['vmware script-execution delete'] = """
489+
type: command
490+
short-summary: Delete a script execution in a private cloud.
491+
examples:
492+
- name: Delete a script execution.
493+
text: az vmware script-execution delete --resource-group group1 --private-cloud cloud1 --name addSsoServer
494+
"""

src/vmware/azext_vmware/_params.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# pylint: disable=line-too-long,too-many-statements
66

77

8+
from azext_vmware.action import ScriptExecutionNamedOutputAction, ScriptExecutionParameterAction
9+
10+
811
def load_arguments(self, _):
912

1013
from azure.cli.core.commands.parameters import tags_type
@@ -111,3 +114,23 @@ def load_arguments(self, _):
111114
with self.argument_context('vmware cloud-link') as c:
112115
c.argument('name', options_list=['--name', '-n'], help='The name of the cloud link.')
113116
c.argument('linked_cloud', help='Identifier of the other private cloud participating in the link.')
117+
118+
with self.argument_context('vmware script-package') as c:
119+
c.argument('name', options_list=['--name', '-n'], help='Name of the script package.')
120+
121+
with self.argument_context('vmware script-cmdlet') as c:
122+
c.argument('script_package', options_list=['--script-package', '-p'], help='Name of the script package.')
123+
c.argument('name', options_list=['--name', '-n'], help='Name of the script cmdlet.')
124+
125+
with self.argument_context('vmware script-execution') as c:
126+
c.argument('name', options_list=['--name', '-n'], help='Name of the script execution.')
127+
128+
with self.argument_context('vmware script-execution create') as c:
129+
c.argument('timeout', help='Time limit for execution.')
130+
c.argument('parameters', options_list=['--parameter', '-p'], action=ScriptExecutionParameterAction, nargs='*', help='Parameters the script will accept.')
131+
c.argument('hidden_parameters', options_list=['--hidden-parameter'], action=ScriptExecutionParameterAction, nargs='*', help='Parameters that will be hidden/not visible to ARM, such as passwords and credentials.')
132+
c.argument('failure_reason', help='Error message if the script was able to run, but if the script itself had errors or powershell threw an exception.')
133+
c.argument('retention', help='Time to live for the resource. If not provided, will be available for 60 days.')
134+
c.argument('out', help='Standard output stream from the powershell execution.')
135+
c.argument('named_outputs', action=ScriptExecutionNamedOutputAction, nargs='*', help='User-defined dictionary.')
136+
c.argument('script_cmdlet_id', help='A reference to the script cmdlet resource if user is running a AVS script.')

src/vmware/azext_vmware/action.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
# --------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for license information.
5+
# --------------------------------------------------------------------------------------------
6+
# pylint: disable=line-too-long, protected-access, too-few-public-methods
7+
8+
import argparse
9+
from typing import Dict, List
10+
from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError
11+
from knack.util import CLIError
12+
from azext_vmware.vendored_sdks.avs_client.models import ScriptExecutionParameter, ScriptExecutionParameterType, ScriptStringExecutionParameter, ScriptSecureStringExecutionParameter, PSCredentialExecutionParameter
13+
14+
15+
class ScriptExecutionNamedOutputAction(argparse._AppendAction):
16+
17+
def __call__(self, parser, namespace, values, option_string=None):
18+
namespace.named_outputs = script_execution_named_outputs(values)
19+
20+
21+
def script_execution_named_outputs(values: List[str]) -> Dict[str, str]:
22+
try:
23+
return dict(map(lambda x: x.split('=', 1), values))
24+
except ValueError as error:
25+
raise CLIError('parsing named output parameter \'{}\''.format(values)) from error
26+
27+
28+
class ScriptExecutionParameterAction(argparse._AppendAction):
29+
30+
def __call__(self, parser, namespace, values, option_string=None):
31+
parameter = script_execution_parameters(values)
32+
if namespace.parameters:
33+
namespace.parameters.append(parameter)
34+
else:
35+
namespace.parameters = [parameter]
36+
37+
38+
def script_execution_parameters(values: List[str]) -> ScriptExecutionParameter:
39+
values = dict(map(lambda x: x.split('=', 1), values))
40+
tp = require(values, "type")
41+
type_lower = tp.lower()
42+
43+
if type_lower == ScriptExecutionParameterType.VALUE.lower():
44+
try:
45+
return ScriptStringExecutionParameter(name=require(values, "name"), value=values.get("value"))
46+
except CLIError as error:
47+
raise InvalidArgumentValueError('parsing {} script execution parameter'.format(ScriptExecutionParameterType.VALUE)) from error
48+
49+
elif type_lower == ScriptExecutionParameterType.SECURE_VALUE.lower():
50+
try:
51+
return ScriptSecureStringExecutionParameter(name=require(values, "name"), secure_value=values.get("secureValue"))
52+
except CLIError as error:
53+
raise InvalidArgumentValueError('parsing {} script execution parameter'.format(ScriptExecutionParameterType.SECURE_VALUE)) from error
54+
55+
elif type_lower == ScriptExecutionParameterType.CREDENTIAL.lower():
56+
try:
57+
return PSCredentialExecutionParameter(name=require(values, "name"), username=values.get("username"), password=values.get("password"))
58+
except CLIError as error:
59+
raise InvalidArgumentValueError('parsing {} script execution parameter'.format(ScriptExecutionParameterType.CREDENTIAL)) from error
60+
61+
else:
62+
raise InvalidArgumentValueError('script execution paramater type \'{}\' not matched'.format(tp))
63+
64+
65+
def require(values: Dict[str, str], key: str) -> str:
66+
'''Gets the required script execution parameter or raises a CLIError.'''
67+
value = values.get(key)
68+
if value is None:
69+
raise RequiredArgumentMissingError('script execution parameter \'{}\' required'.format(key))
70+
return value

src/vmware/azext_vmware/commands.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,21 @@ def load_command_table(self, _):
8989
g.custom_show_command('show', 'globalreachconnection_show')
9090

9191
with self.command_group('vmware cloud-link', vmware_sdk, client_factory=cf_vmware) as g:
92-
g.custom_command('create', 'cloud_link_create_or_update')
93-
g.custom_command('update', 'cloud_link_create_or_update')
92+
g.custom_command('create', 'cloud_link_create')
9493
g.custom_command('list', 'cloud_link_list')
9594
g.custom_command('delete', 'cloud_link_delete')
9695
g.custom_show_command('show', 'cloud_link_show')
96+
97+
with self.command_group('vmware script-cmdlet', vmware_sdk, client_factory=cf_vmware) as g:
98+
g.custom_command('list', 'script_cmdlet_list')
99+
g.custom_show_command('show', 'script_cmdlet_show')
100+
101+
with self.command_group('vmware script-package', vmware_sdk, client_factory=cf_vmware) as g:
102+
g.custom_command('list', 'script_package_list')
103+
g.custom_show_command('show', 'script_package_show')
104+
105+
with self.command_group('vmware script-execution', vmware_sdk, client_factory=cf_vmware) as g:
106+
g.custom_command('create', 'script_execution_create')
107+
g.custom_command('list', 'script_execution_list')
108+
g.custom_command('delete', 'script_execution_delete')
109+
g.custom_show_command('show', 'script_execution_show')

src/vmware/azext_vmware/custom.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# --------------------------------------------------------------------------------------------
55
# pylint: disable=line-too-long
66

7+
from typing import List, Tuple
78
from azext_vmware.vendored_sdks.avs_client import AVSClient
89

910
LEGAL_TERMS = '''
@@ -274,7 +275,7 @@ def globalreachconnection_delete(client: AVSClient, resource_group_name, private
274275
return client.global_reach_connections.begin_delete(resource_group_name=resource_group_name, private_cloud_name=private_cloud, global_reach_connection_name=name)
275276

276277

277-
def cloud_link_create_or_update(client: AVSClient, resource_group_name, name, private_cloud, linked_cloud):
278+
def cloud_link_create(client: AVSClient, resource_group_name, name, private_cloud, linked_cloud):
278279
return client.cloud_links.begin_create_or_update(resource_group_name=resource_group_name, private_cloud_name=private_cloud, cloud_link_name=name, linked_cloud=linked_cloud)
279280

280281

@@ -288,3 +289,43 @@ def cloud_link_show(client: AVSClient, resource_group_name, private_cloud, name)
288289

289290
def cloud_link_delete(client: AVSClient, resource_group_name, private_cloud, name):
290291
return client.cloud_links.begin_delete(resource_group_name=resource_group_name, private_cloud_name=private_cloud, cloud_link_name=name)
292+
293+
294+
def script_cmdlet_list(client: AVSClient, resource_group_name, private_cloud, script_package):
295+
return client.script_cmdlets.list(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_package_name=script_package)
296+
297+
298+
def script_cmdlet_show(client: AVSClient, resource_group_name, private_cloud, script_package, name):
299+
return client.script_cmdlets.get(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_package_name=script_package, script_cmdlet_name=name)
300+
301+
302+
def script_package_list(client: AVSClient, resource_group_name, private_cloud):
303+
return client.script_packages.list(resource_group_name=resource_group_name, private_cloud_name=private_cloud)
304+
305+
306+
def script_package_show(client: AVSClient, resource_group_name, private_cloud, name):
307+
return client.script_packages.get(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_package_name=name)
308+
309+
310+
def script_execution_create(client: AVSClient, resource_group_name, private_cloud, name, timeout, script_cmdlet_id=None, parameters=None, hidden_parameters=None, failure_reason=None, retention=None, out=None, named_outputs: List[Tuple[str, str]] = None):
311+
from azext_vmware.vendored_sdks.avs_client.models import ScriptExecution
312+
if named_outputs is not None:
313+
named_outputs = dict(named_outputs)
314+
script_execution = ScriptExecution(timeout=timeout, script_cmdlet_id=script_cmdlet_id, parameters=parameters, hidden_parameters=hidden_parameters, failure_reason=failure_reason, retention=retention, output=out, named_outputs=named_outputs)
315+
return client.script_executions.begin_create_or_update(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_execution_name=name, script_execution=script_execution)
316+
317+
318+
def script_execution_list(client: AVSClient, resource_group_name, private_cloud):
319+
return client.script_executions.list(resource_group_name=resource_group_name, private_cloud_name=private_cloud)
320+
321+
322+
def script_execution_show(client: AVSClient, resource_group_name, private_cloud, name):
323+
return client.script_executions.get(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_execution_name=name)
324+
325+
326+
def script_execution_delete(client: AVSClient, resource_group_name, private_cloud, name):
327+
return client.script_executions.begin_delete(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_execution_name=name)
328+
329+
330+
def script_execution_logs(client: AVSClient, resource_group_name, private_cloud, name):
331+
return client.script_executions.get_execution_logs(resource_group_name=resource_group_name, private_cloud_name=private_cloud, script_execution_name=name)

0 commit comments

Comments
 (0)