Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0684cb1
Initial draft for formUiDefinition
TSunny007 Apr 3, 2021
f1bde75
Merge branch 'tsunkaraneni/formUiDefinition' of https://github.com/Ta…
Apr 26, 2021
7041975
Tested with generated SDK from https://github.com/Azure/sdk-release-r…
Apr 26, 2021
2987bbc
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
Apr 27, 2021
0e2af1c
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
Apr 27, 2021
1505239
TemplateSpecsVersion parameters artifacts and template have been repl…
Apr 27, 2021
b5f50da
Restored new lined at end of launch.json file
Apr 27, 2021
86ae0e9
reverting changes to setup.py until sdk release
Apr 27, 2021
27ec365
TemplateSpecs regression addressed https://github.com/Azure/azure-cli…
Apr 27, 2021
ea75cdc
Customer reported bug fix
Apr 27, 2021
2527128
Removed _packing_engine changes
Apr 27, 2021
14e274b
Re-recorded test cases with template specs
Apr 27, 2021
28f7fc1
Reviewer suggestion
Apr 27, 2021
9ee036b
Re-recorded template specs tests live
Apr 27, 2021
558976e
Merge branch 'daetienn/TemplateSpecsBug' of https://github.com/detien…
Apr 27, 2021
3ee714d
Fixed CLI Style
Apr 27, 2021
34ec85e
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
Apr 27, 2021
f6889ee
Merged with dev
May 12, 2021
5c5fd4b
Merged with dev
May 13, 2021
383f31f
Merged with dev
May 13, 2021
6c8964c
Removed merge conflicts
May 13, 2021
825026b
Removed merge conflicts
May 13, 2021
94b7fe4
Restored new line for launch.json
May 13, 2021
86a3a6c
Restored new lines at end of files
May 13, 2021
8a28879
Bump template specs SDK to latest release
May 13, 2021
99e0b69
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
May 19, 2021
f8a211f
Tested with new SDK
May 19, 2021
5dad915
Deployments Tests with new SDK
May 19, 2021
16c5923
SDK Bump to 18.0.0
May 19, 2021
5d91751
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
May 19, 2021
80f06a9
Tracking Linux requirements
May 19, 2021
4c0617b
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
May 20, 2021
e2123a3
Merged with dev and added changes from https://github.com/Azure/azure…
May 20, 2021
9157323
Merge branch 'dev' of https://github.com/Azure/azure-cli into daetien…
May 20, 2021
5f1a9e3
Rerecord test_nw_connection_monitor_v2_creation
May 20, 2021
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
2 changes: 1 addition & 1 deletion src/azure-cli-core/azure/cli/core/profiles/_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def default_api_version(self):
ResourceType.MGMT_RESOURCE_RESOURCES: '2020-10-01',
ResourceType.MGMT_RESOURCE_SUBSCRIPTIONS: '2019-11-01',
ResourceType.MGMT_RESOURCE_DEPLOYMENTSCRIPTS: '2020-10-01',
ResourceType.MGMT_RESOURCE_TEMPLATESPECS: '2019-06-01-preview',
ResourceType.MGMT_RESOURCE_TEMPLATESPECS: '2021-05-01',
ResourceType.MGMT_NETWORK_DNS: '2018-05-01',
ResourceType.MGMT_KEYVAULT: '2021-04-01-preview',
ResourceType.MGMT_AUTHORIZATION: SDKProfile('2020-04-01-preview', {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2331,7 +2331,7 @@
- name: Update the description of a template spec version with no prompt.
text: az ts update -g ExistingRG --name ExistingName -v 3.0 --version-description "New description" --yes
- name: Update all the properties of a template spec version.
text: az ts update -g ExistingRG --name ExistingName -v 3.0 -f updatedTemplate.json --display-name "New parent display name" --description "New parent description" --version-description "New child description"
text: az ts update -g ExistingRG --name ExistingName -v 3.0 -f updatedTemplate.json --display-name "New parent display name" --description "New parent description" --version-description "New child description" --ui-form-definition formDefinition.json
- name: Remove tag(s) from template spec version with no prompt.
text: az ts update -g ExistingRG --name ExistingName -v 3.0 -f updatedTemplate.json --tags --yes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _pack_artifacts(cmd, template_abs_file_path, context):
:type template_abs_file_path : str
:param context : The packing context of the current packing operation
:type content : PackingContext
:param artifactableTemplateObj : The packagable template object
:param artifactableTemplateObj : The packageable template object
:type artifactableTemplateObj : JSON
"""
original_directory = getattr(context, 'CurrentDirectory')
Expand Down Expand Up @@ -112,11 +112,11 @@ def _pack_artifacts(cmd, template_abs_file_path, context):
if os.path.samefile(prev_added_artifact, abs_local_path):
continue
_pack_artifacts(cmd, abs_local_path, context)
TemplateSpecTemplateArtifact = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS,
'TemplateSpecTemplateArtifact', mod='models')
LinkedTemplateArtifact = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS,
'LinkedTemplateArtifact', mod='models')
template_content = read_file_content(abs_local_path)
template_json = json.loads(json.dumps(process_template(template_content)))
artifact = TemplateSpecTemplateArtifact(path=as_relative_path, template=template_json)
artifact = LinkedTemplateArtifact(path=as_relative_path, template=template_json)
context.Artifact.append(artifact)
finally:
context.CurrentDirectory = original_directory
Expand All @@ -135,9 +135,9 @@ def _get_deployment_resource_objects(cmd, template_obj, includeNested=False):
results.append(deployment_resource_obj)
if(includeNested and 'properties' in deployment_resource_obj):
deployment_resource_props_obj = deployment_resource_obj['properties']
if 'template' in deployment_resource_props_obj:
if 'mainTemplate' in deployment_resource_props_obj:
results.extend(_get_deployment_resource_objects(cmd,
deployment_resource_props_obj['template'],
deployment_resource_props_obj['mainTemplate'],
includeNested=True))
return results

Expand Down Expand Up @@ -182,7 +182,7 @@ def _absolute_to_relative_path(root_dir_path, abs_file_path):

def unpack(cmd, exported_template, target_dir, template_file_name):

packaged_template = PackagedTemplate(exported_template.template, exported_template.artifacts)
packaged_template = PackagedTemplate(exported_template.main_template, exported_template.linked_templates)
# Ensure paths are normalized:
template_file_name = os.path.basename(template_file_name)
target_dir = os.path.abspath(target_dir).rstrip(os.sep).rstrip(os.altsep)
Expand All @@ -197,8 +197,8 @@ def unpack(cmd, exported_template, target_dir, template_file_name):
_normalize_directory_seperators_for_local_file_system(getattr(artifact, 'path')))
abs_local_path = os.path.abspath(local_path)
if os.path.commonpath([target_dir]) != os.path.commonpath([target_dir, abs_local_path]):
raise CLIError('Unable to unpack artifact ' + getattr(artifact, 'path') + 'because it would create a file' +
'outside of the target directory hierarchy of' + target_dir)
raise CLIError('Unable to unpack linked template ' + getattr(artifact, 'path') +
'because it would create a file outside of the target directory hierarchy of' + target_dir)

# Now that the artifact paths checkout...let's begin by writing our main template
# file and then processing each artifact:
Expand All @@ -208,11 +208,11 @@ def unpack(cmd, exported_template, target_dir, template_file_name):
with open(root_template_file_path, 'w') as root_file:
json.dump(getattr(packaged_template, 'RootTemplate'), root_file, indent=2)

TemplateSpecTemplateArtifact = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS,
'TemplateSpecTemplateArtifact', mod='models')
LinkedTemplateArtifact = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS,
'LinkedTemplateArtifact', mod='models')
for artifact in getattr(packaged_template, 'Artifacts'):
if not isinstance(artifact, TemplateSpecTemplateArtifact):
raise CLIError('Unknown artifact type encountered...')
if not isinstance(artifact, LinkedTemplateArtifact):
raise CLIError('Unknown linked template type encountered...')
artifact_path = _normalize_directory_seperators_for_local_file_system(getattr(artifact, 'path'))
abs_local_path = os.path.abspath(os.path.join(target_dir, artifact_path))
if not os.path.exists(os.path.dirname(abs_local_path)):
Expand Down
4 changes: 4 additions & 0 deletions src/azure-cli/azure/cli/command_modules/resource/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def load_arguments(self, _):
ts_display_name_type = CLIArgumentType(options_list=['--display-name', '-d'], help='The display name of the template spec')
ts_description_type = CLIArgumentType(options_list=['--description'], help='The description of the parent template spec.')
ts_version_description_type = CLIArgumentType(options_list=['--version-description'], help='The description of the template spec version.')
ui_form_definition_file_type = CLIArgumentType(options_list=['--ui-form-definition'], is_preview=True, completer=FilesCompleter(), type=file_type,
help="A path to a uiFormDefinition file in the file system")

_PROVIDER_HELP_TEXT = 'the resource namespace, aka \'provider\''

Expand Down Expand Up @@ -559,6 +561,7 @@ def load_arguments(self, _):
with self.argument_context('ts create') as c:
c.argument('resource_group', arg_type=resource_group_name_type, help='The resource group to store the template spec.')
c.argument('template_file', arg_type=deployment_template_file_type)
c.argument('ui_form_definition_file', arg_type=ui_form_definition_file_type, help='The uiFormDefinition file path in the file system for the template spec version.')
c.argument('location', options_list=['--location', '-l'], help='The location to store the template-spec and template-spec version(s). Cannot be changed after creation.')
c.argument('display_name', arg_type=ts_display_name_type)
c.argument('description', arg_type=ts_description_type)
Expand All @@ -569,6 +572,7 @@ def load_arguments(self, _):
with self.argument_context('ts update') as c:
c.argument('resource_group', arg_type=resource_group_name_type, help='The resource group to store the template spec.')
c.argument('template_spec', arg_type=deployment_template_spec_type)
c.argument('ui_form_definition_file', arg_type=ui_form_definition_file_type, help='The uiFormDefinition file path in the file system for the template spec version.')
c.argument('template_file', arg_type=deployment_template_file_type)
c.argument('display_name', arg_type=ts_display_name_type)
c.argument('description', arg_type=ts_description_type)
Expand Down
51 changes: 29 additions & 22 deletions src/azure-cli/azure/cli/command_modules/resource/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ def _prepare_deployment_properties_unmodified(cmd, deployment_scope, template_fi
# ResourceType.MGMT_RESOURCE_TEMPLATESPECS than our designated version. This ensures the api-version of all the rest requests for
# template_spec are consistent in the same profile:
api_version = get_api_version(cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS)
template_obj = show_resource(cmd=cmd, resource_ids=[template_spec], api_version=api_version).properties['template']
template_obj = show_resource(cmd=cmd, resource_ids=[template_spec], api_version=api_version).properties['mainTemplate']
else:
template_content = (
run_bicep_command(["build", "--stdout", template_file])
Expand Down Expand Up @@ -1827,9 +1827,7 @@ def get_template_spec(cmd, resource_group_name=None, name=None, version=None, te


def create_template_spec(cmd, resource_group_name, name, template_file=None, location=None, display_name=None,
description=None, version=None, version_description=None, tags=None, no_prompt=False):
artifacts = None
input_template = None
description=None, version=None, version_description=None, tags=None, no_prompt=False, ui_form_definition_file=None):
if location is None:
rcf = _resource_client_factory(cmd.cli_ctx)
location = rcf.resource_groups.get(resource_group_name).location
Expand All @@ -1839,15 +1837,16 @@ def create_template_spec(cmd, resource_group_name, name, template_file=None, loc
raise IncorrectUsageError('please provide --version if --template-file is specified')

if version:
Exists = False
input_template, artifacts, input_ui_form_definition = None, None, None
exists = False
if no_prompt is False:
try: # Check if child template spec already exists.
existing_ts = rcf.template_spec_versions.get(resource_group_name=resource_group_name, template_spec_name=name, template_spec_version=version)
from knack.prompting import prompt_y_n
confirmation = prompt_y_n("This will override {}. Proceed?".format(existing_ts))
if not confirmation:
return None
Exists = True
exists = True
except Exception: # pylint: disable=broad-except
pass

Expand All @@ -1857,20 +1856,24 @@ def create_template_spec(cmd, resource_group_name, name, template_file=None, loc
input_template = getattr(packed_template, 'RootTemplate')
artifacts = getattr(packed_template, 'Artifacts')

if not Exists:
if ui_form_definition_file:
ui_form_definition_content = _remove_comments_from_json(read_file_content(ui_form_definition_file))
input_ui_form_definition = json.loads(json.dumps(ui_form_definition_content))

if not exists:
try: # Check if parent template spec already exists.
exisiting_parent = rcf.template_specs.get(resource_group_name=resource_group_name, template_spec_name=name)
existing_parent = rcf.template_specs.get(resource_group_name=resource_group_name, template_spec_name=name)
if tags is None: # New version should inherit tags from parent if none are provided.
tags = getattr(exisiting_parent, 'tags')
tags = getattr(existing_parent, 'tags')
except Exception: # pylint: disable=broad-except
tags = tags or {}
TemplateSpec = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, 'TemplateSpec', mod='models')
template_spec_parent = TemplateSpec(location=location, description=description, display_name=display_name, tags=tags)
rcf.template_specs.create_or_update(resource_group_name, name, template_spec_parent)

TemplateSpecVersion = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, 'TemplateSpecVersion', mod='models')
template_spec_child = TemplateSpecVersion(location=location, artifacts=artifacts, description=version_description, template=input_template, tags=tags)
return rcf.template_spec_versions.create_or_update(resource_group_name, name, version, template_spec_child)
template_spec_version = TemplateSpecVersion(location=location, linked_templates=artifacts, description=version_description, main_template=input_template, tags=tags, ui_form_definition=input_ui_form_definition)
return rcf.template_spec_versions.create_or_update(resource_group_name, name, version, template_spec_version)

tags = tags or {}
TemplateSpec = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, 'TemplateSpec', mod='models')
Expand All @@ -1879,7 +1882,7 @@ def create_template_spec(cmd, resource_group_name, name, template_file=None, loc


def update_template_spec(cmd, resource_group_name=None, name=None, template_spec=None, template_file=None, display_name=None,
description=None, version=None, version_description=None, tags=None):
description=None, version=None, version_description=None, tags=None, ui_form_definition_file=None):
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)

if template_spec:
Expand All @@ -1889,38 +1892,42 @@ def update_template_spec(cmd, resource_group_name=None, name=None, template_spec
version = id_parts.get('resource_name')
if version == name:
version = None
existing_template = None
artifacts = None

existing_template, artifacts, input_ui_form_definition = None, None, None
if template_file:
from azure.cli.command_modules.resource._packing_engine import (pack)
packed_template = pack(cmd, template_file)
input_template = getattr(packed_template, 'RootTemplate')
artifacts = getattr(packed_template, 'Artifacts')

if ui_form_definition_file:
ui_form_definition_content = _remove_comments_from_json(read_file_content(ui_form_definition_file))
input_ui_form_definition = json.loads(json.dumps(ui_form_definition_content))

if version:
existing_template = rcf.template_spec_versions.get(resource_group_name=resource_group_name, template_spec_name=name, template_spec_version=version)

location = getattr(existing_template, 'location')

version_tags = tags
if tags is None: # Do not remove tags if not explicitely empty.
version_tags = getattr(existing_template, 'tags')
# Do not remove tags if not explicitly empty.
if tags is None:
tags = getattr(existing_template, 'tags')
if version_description is None:
version_description = getattr(existing_template, 'description')
if template_file is None:
input_template = getattr(existing_template, 'template')

input_template = getattr(existing_template, 'main_template')
if ui_form_definition_file is None:
input_ui_form_definition = getattr(existing_template, 'ui_form_definition')
TemplateSpecVersion = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, 'TemplateSpecVersion', mod='models')

updated_template_spec = TemplateSpecVersion(location=location, artifacts=artifacts, description=version_description, template=input_template, tags=version_tags)
updated_template_spec = TemplateSpecVersion(location=location, linked_templates=artifacts, description=version_description, main_template=input_template, tags=tags, ui_form_definition=input_ui_form_definition)
return rcf.template_spec_versions.create_or_update(resource_group_name, name, version, updated_template_spec)

existing_template = rcf.template_specs.get(resource_group_name=resource_group_name, template_spec_name=name)

location = getattr(existing_template, 'location')
version_tags = tags
if version_tags is None: # Do not remove tags if not explicitely empty.
# Do not remove tags if not explicitly empty.
if tags is None:
tags = getattr(existing_template, 'tags')
if display_name is None:
display_name = getattr(existing_template, 'display_name')
Expand Down
Loading