Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -2258,7 +2258,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
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 @@ -86,6 +86,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, min_api='2021-03-01', 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 @@ -541,6 +543,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.')
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 @@ -551,6 +554,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
43 changes: 25 additions & 18 deletions src/azure-cli/azure/cli/command_modules/resource/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1837,9 +1837,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 @@ -1849,15 +1847,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 @@ -1867,7 +1866,11 @@ 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)
if tags is None: # New version should inherit tags from parent if none are provided.
Expand All @@ -1879,8 +1882,8 @@ def create_template_spec(cmd, resource_group_name, name, template_file=None, loc
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, artifacts=artifacts, description=version_description, 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 @@ -1889,7 +1892,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 @@ -1899,38 +1902,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')

if ui_form_definition_file is None:
input_ui_form_definition = getattr(existing_template, 'formUiDefinition')
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, artifacts=artifacts, description=version_description, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"$schema": "createFormUI.schema.json",
"view": {
"kind": "Form",
"properties": {
"title": "titleFooMG",
"steps": [
{
"name": "basics",
"label": "Basics",
"elements": [
{
"name": "resourceScope",
"type": "Microsoft.Common.ResourceScope",
"subscription": {
"constraints": {
"validations": [
{
"isValid": "[expression for checking]",
"message": "Please select a valid subscription."
},
{
"permission": "<Resource Provider>/<Action>",
"message": "Must have correct permission to complete this step."
}
]
},
"resourceProviders": [
"<Resource Provider>"
]
},
"resourceGroup": {
"constraints": {
"validations": [
{
"isValid": "[expression for checking]",
"message": "Please select a valid resource group."
}
]
},
"allowExisting": true
},
"location": {
"label": "Custom label for location",
"toolTip": "provide a useful tooltip",
"resourceTypes": [
"Microsoft.Compute/virtualMachines"
],
"allowedValues": [
"eastus",
"westus2"
]
}
}
],
"description": "Customized description with **markdown**, see [more](https://www.microsoft.com)."
},
{
"name": "storageConfig",
"label": "Storage settings",
"elements": [
{
"name": "storageAccounts",
"type": "Microsoft.Storage.MultiStorageAccountCombo",
"label": {
"prefix": "Storage account name prefix",
"type": "Storage account type"
},
"defaultValue": {
"prefix": "stracct",
"type": "Standard_LRS"
},
"constraints": {
"allowedTypes": [
"Premium_LRS",
"Standard_LRS",
"Standard_GRS"
]
},
"count": 2,
"scope": {
"subscriptionId": "[steps('basics').resourceScope.subscription.subscriptionId]",
"resourceGroupName": "[steps('basics').resourceScope.resourceGroup.name]",
"location": "[steps('basics').resourceScope.location.name]"
}
}
]
},
{
"name": "tags",
"label": "Tags",
"elements": [
{
"name": "tagsByResource",
"type": "Microsoft.Common.TagsByResource",
"resources": [
"Microsoft.Storage/storageAccounts",
"Microsoft.Compute/virtualMachines"
]
}
]
}
]
},
"outputs": {
"parameters": {
"storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]",
"storageAccountType": "[steps('storageConfig').storageAccounts.type]",
"location": "[steps('basics').resourceScope.location.name]",
"tagsByResource": "[steps('tags').tagsByResource]"
},
"kind": "ManagementGroup",
"location": "[steps('basics').resourceScope.location.name]",
"managementGroupId": "[steps('basics').resourceScope.managementGroup.id]"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{
"$schema": "createFormUI.schema.json",
"view": {
"kind": "Form",
"properties": {
"title": "titleFooRG",
"steps": [
{
"name": "basics",
"label": "Basics",
"elements": [
{
"name": "resourceScope",
"type": "Microsoft.Common.ResourceScope",
"subscription": {
"constraints": {
"validations": [
{
"isValid": "[expression for checking]",
"message": "Please select a valid subscription."
},
{
"permission": "<Resource Provider>/<Action>",
"message": "Must have correct permission to complete this step."
}
]
},
"resourceProviders": [
"<Resource Provider>"
]
},
"resourceGroup": {
"constraints": {
"validations": [
{
"isValid": "[expression for checking]",
"message": "Please select a valid resource group."
}
]
},
"allowExisting": true
},
"location": {
"label": "Custom label for location",
"toolTip": "provide a useful tooltip",
"resourceTypes": [
"Microsoft.Compute/virtualMachines"
],
"allowedValues": [
"eastus",
"westus2"
]
}
}
],
"description": "Customized description with **markdown**, see [more](https://www.microsoft.com)."
},
{
"name": "storageConfig",
"label": "Storage settings",
"elements": [
{
"name": "storageAccounts",
"type": "Microsoft.Storage.MultiStorageAccountCombo",
"label": {
"prefix": "Storage account name prefix",
"type": "Storage account type"
},
"defaultValue": {
"prefix": "stracct",
"type": "Standard_LRS"
},
"constraints": {
"allowedTypes": [
"Premium_LRS",
"Standard_LRS",
"Standard_GRS"
]
},
"count": 2,
"scope": {
"subscriptionId": "[steps('basics').resourceScope.subscription.subscriptionId]",
"resourceGroupName": "[steps('basics').resourceScope.resourceGroup.name]",
"location": "[steps('basics').resourceScope.location.name]"
}
}
]
},
{
"name": "tags",
"label": "Tags",
"elements": [
{
"name": "tagsByResource",
"type": "Microsoft.Common.TagsByResource",
"resources": [
"Microsoft.Storage/storageAccounts",
"Microsoft.Compute/virtualMachines"
]
}
]
}
]
},
"outputs": {
"parameters": {
"storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]",
"storageAccountType": "[steps('storageConfig').storageAccounts.type]",
"location": "[steps('basics').resourceScope.location.name]",
"tagsByResource": "[steps('tags').tagsByResource]"
},
"kind": "ResourceGroup",
"location": "[steps('basics').resourceScope.location.name]",
"subscriptionId": "[steps('basics').resourceScope.subscription.id]",
"resourceGroupId": "[steps('basics').resourceScope.resourceGroup.id]"
}
}
}
Loading