Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ def _resource_managementgroups_client_factory(cli_ctx, **_):
return get_mgmt_service_client(cli_ctx, ManagementGroupsAPI, subscription_bound=False)


def _resource_templatespecs_client_factory(cli_ctx, **_):
def _resource_templatespecs_client_factory(cli_ctx, subscription_id=None, **_):
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azure.cli.core.profiles import ResourceType
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS)
kwargs = {'subscription_id': subscription_id} if subscription_id is not None else {}
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, **kwargs)


def _resource_deploymentstacks_client_factory(cli_ctx, **_):
Expand Down
17 changes: 12 additions & 5 deletions src/azure-cli/azure/cli/command_modules/resource/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2309,7 +2309,9 @@ def get_template_spec(cmd, resource_group_name=None, name=None, version=None, te
version = id_parts.get('resource_name')
if version == name:
version = None
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx, subscription_id=id_parts.get('subscription'))
else:
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)
if version:
return rcf.template_spec_versions.get(resource_group_name, name, version)
retrieved_template = rcf.template_specs.get(resource_group_name, name, expand="versions")
Expand Down Expand Up @@ -2381,15 +2383,16 @@ 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, ui_form_definition_file=None):
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)

if template_spec:
id_parts = parse_resource_id(template_spec)
resource_group_name = id_parts.get('resource_group')
name = id_parts.get('name')
version = id_parts.get('resource_name')
if version == name:
version = None
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx, subscription_id=id_parts.get('subscription'))
else:
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)

existing_template, artifacts, input_ui_form_definition = None, None, None
if template_file:
Expand Down Expand Up @@ -2445,14 +2448,16 @@ def update_template_spec(cmd, resource_group_name=None, name=None, template_spec


def export_template_spec(cmd, output_folder, resource_group_name=None, name=None, version=None, template_spec=None):
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)
if template_spec:
id_parts = parse_resource_id(template_spec)
resource_group_name = id_parts.get('resource_group')
name = id_parts.get('name')
version = id_parts.get('resource_name')
if version == name:
version = None
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx, subscription_id=id_parts.get('subscription'))
else:
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)
if not version:
raise IncorrectUsageError('Please specify the template spec version for export')
exported_template = rcf.template_spec_versions.get(resource_group_name, name, version)
Expand All @@ -2461,14 +2466,16 @@ def export_template_spec(cmd, output_folder, resource_group_name=None, name=None


def delete_template_spec(cmd, resource_group_name=None, name=None, version=None, template_spec=None):
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)
if template_spec:
id_parts = parse_resource_id(template_spec)
resource_group_name = id_parts.get('resource_group')
name = id_parts.get('name')
version = id_parts.get('resource_name')
if version == name:
version = None
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx, subscription_id=id_parts.get('subscription'))
else:
rcf = _resource_templatespecs_client_factory(cmd.cli_ctx)
if version:
return rcf.template_spec_versions.delete(resource_group_name=resource_group_name, template_spec_name=name, template_spec_version=version)
return rcf.template_specs.delete(resource_group_name=resource_group_name, template_spec_name=name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,29 @@ def test_update_template_specs(self, resource_group, resource_group_location):
# clean up
self.cmd('ts delete --template-spec {template_spec_id} --yes')

@live_only()
@ResourceGroupPreparer(name_prefix="cli_test_ts_aux_update_", location="eastus2", subscription=AUX_SUBSCRIPTION)
def test_update_template_spec_with_aux_subscription(self, resource_group):
curr_dir = os.path.dirname(os.path.realpath(__file__))
template_spec_name = self.create_random_name('cli-test-ts-aux-update', 60)
self.kwargs.update({
"aux_rg": resource_group,
"aux_subscription": AUX_SUBSCRIPTION,
"template_spec_name": template_spec_name,
'tf': os.path.join(curr_dir, 'simple_deploy.json').replace('\\', '\\\\'),
'description': '"Updated description"',
})

result = self.cmd('ts create -g {aux_rg} -n {template_spec_name} -v 1.0 -l eastus2 -f "{tf}" --subscription {aux_subscription}').get_output_in_json()
self.kwargs['template_spec_version_id'] = result['id']
self.kwargs['template_spec_id'] = result['id'].replace('/versions/1.0', '')
self.assertIn(AUX_SUBSCRIPTION, result['id'])

ts_result = self.cmd('ts update --template-spec {template_spec_id} --description {description} --yes').get_output_in_json()
self.assertIn(AUX_SUBSCRIPTION, ts_result['id'])

self.cmd('ts delete --template-spec {template_spec_id} --yes --subscription {aux_subscription}')

@ResourceGroupPreparer(name_prefix='cli_test_template_specs', location='westus')
def test_show_template_spec(self, resource_group, resource_group_location):
curr_dir = os.path.dirname(os.path.realpath(__file__))
Expand Down Expand Up @@ -1047,6 +1070,46 @@ def test_show_template_spec(self, resource_group, resource_group_location):
# clean up
self.cmd('ts delete --template-spec {template_spec_id} --yes')

@live_only()
@ResourceGroupPreparer(name_prefix="cli_test_ts_aux_show_", location="eastus2", subscription=AUX_SUBSCRIPTION)
def test_template_spec_show_with_aux_subscription(self, resource_group, resource_group_location):
curr_dir = os.path.dirname(os.path.realpath(__file__))
template_spec_name = self.create_random_name('cli-test-ts-aux-show', 60)
self.kwargs.update({
"aux_rg": resource_group,
"aux_subscription": AUX_SUBSCRIPTION,
"template_spec_name": template_spec_name,
'tf': os.path.join(curr_dir, 'simple_deploy.json').replace('\\', '\\\\'),
'resource_group_location': resource_group_location,
})

result = self.cmd('ts create -g {aux_rg} -n {template_spec_name} -v 1.0 -l {resource_group_location} -f "{tf}" --subscription {aux_subscription}',
checks=[
self.check('name', '1.0'),
self.check('type', 'Microsoft.Resources/templateSpecs/versions')
]).get_output_in_json()
self.kwargs['template_spec_version_id'] = result['id']
self.kwargs['template_spec_id'] = result['id'].replace('/versions/1.0', '')
self.assertIn(AUX_SUBSCRIPTION, result['id'])

ts_result = self.cmd('ts show --template-spec {template_spec_id}',
checks=[
self.check('name', '{template_spec_name}'),
self.check('type', 'Microsoft.Resources/templateSpecs')
]).get_output_in_json()
self.assertIn(AUX_SUBSCRIPTION, ts_result['id'])
self.assertEqual(ts_result['name'], template_spec_name)

ts_version_result = self.cmd('ts show --template-spec {template_spec_version_id}',
checks=[
self.check('name', '1.0'),
self.check('type', 'Microsoft.Resources/templateSpecs/versions')
]).get_output_in_json()
self.assertIn(AUX_SUBSCRIPTION, ts_version_result['id'])
self.assertEqual(ts_version_result['name'], '1.0')

self.cmd('ts delete --template-spec {template_spec_id} --yes --subscription {aux_subscription}')

@ResourceGroupPreparer(name_prefix='cli_test_template_specs', location='westus')
def test_delete_template_spec(self, resource_group, resource_group_location):
curr_dir = os.path.dirname(os.path.realpath(__file__))
Expand Down Expand Up @@ -1076,6 +1139,25 @@ def test_delete_template_spec(self, resource_group, resource_group_location):
self.cmd('ts list -g {rg}',
checks=self.check("length([?id=='{template_spec_id}'])", 0))

@live_only()
@ResourceGroupPreparer(name_prefix="cli_test_ts_aux_delete_", location="eastus2", subscription=AUX_SUBSCRIPTION)
def test_delete_template_spec_with_aux_subscription(self, resource_group):
curr_dir = os.path.dirname(os.path.realpath(__file__))
template_spec_name = self.create_random_name('cli-test-ts-aux-delete', 60)
self.kwargs.update({
"aux_rg": resource_group,
"aux_subscription": AUX_SUBSCRIPTION,
"template_spec_name": template_spec_name,
'tf': os.path.join(curr_dir, 'simple_deploy.json').replace('\\', '\\\\'),
})

result = self.cmd('ts create -g {aux_rg} -n {template_spec_name} -v 1.0 -l eastus2 -f "{tf}" --subscription {aux_subscription}').get_output_in_json()
self.kwargs['template_spec_version_id'] = result['id']
self.kwargs['template_spec_id'] = result['id'].replace('/versions/1.0', '')
self.assertIn(AUX_SUBSCRIPTION, result['id'])

self.cmd('ts delete --template-spec {template_spec_id} --yes')

@ResourceGroupPreparer(name_prefix='cli_test_template_specs', location='westus')
def test_template_spec_create_and_update_with_tags(self, resource_group, resource_group_location):
curr_dir = os.path.dirname(os.path.realpath(__file__))
Expand Down Expand Up @@ -1197,6 +1279,32 @@ def test_template_spec_export_error_handling(self, resource_group, resource_grou
self.cmd('ts export -g {rg} --name {template_spec_name} --output-folder {output_folder}')
self.assertTrue('Please specify the template spec version for export' in str(err.exception))

@live_only()
@ResourceGroupPreparer(name_prefix="cli_test_ts_aux_export_", location="eastus2", subscription=AUX_SUBSCRIPTION)
def test_template_spec_export_with_aux_subscription(self, resource_group):
curr_dir = os.path.dirname(os.path.realpath(__file__))
dir_name = self.create_random_name('TemplateSpecExportAux', 30)
template_spec_name = self.create_random_name('cli-test-ts-aux-export', 60)
self.kwargs.update({
"aux_rg": resource_group,
"aux_subscription": AUX_SUBSCRIPTION,
"template_spec_name": template_spec_name,
'tf': os.path.join(curr_dir, 'simple_deploy.json').replace('\\', '\\\\'),
'output_folder': os.path.join(curr_dir, dir_name).replace('\\', '\\\\'),
})

result = self.cmd('ts create -g {aux_rg} -n {template_spec_name} -v 1.0 -l eastus2 -f "{tf}" --subscription {aux_subscription}').get_output_in_json()
self.kwargs['template_spec_version_id'] = result['id']
self.kwargs['template_spec_id'] = result['id'].replace('/versions/1.0', '')
self.assertIn(AUX_SUBSCRIPTION, result['id'])

os.makedirs(self.kwargs['output_folder'])
output_path = self.cmd('ts export --template-spec {template_spec_version_id} --output-folder {output_folder}').get_output_in_json()
template_file = os.path.join(output_path, (self.kwargs['template_spec_name'] + '.json'))
self.assertTrue(os.path.isfile(template_file))

self.cmd('ts delete --template-spec {template_spec_id} --yes --subscription {aux_subscription}')


class DeploymentTestsWithQueryString(LiveScenarioTest):
@ResourceGroupPreparer(name_prefix='cli_test_query_str_rg', location='eastus')
Expand Down
Loading