From 46d40d76f855ba795f93a1eafca364a8eb0490e5 Mon Sep 17 00:00:00 2001 From: Dania Etienne Date: Fri, 16 Jul 2021 12:04:07 -0400 Subject: [PATCH 1/3] Removed preview tag from template specs, fixed iteration bug --- .../resource/_packing_engine.py | 53 ++++++++++--------- .../cli/command_modules/resource/_params.py | 6 +-- .../cli/command_modules/resource/commands.py | 2 +- .../cli/command_modules/resource/custom.py | 4 +- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py b/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py index 6130690ced6..9deeaf54a03 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py +++ b/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py @@ -39,7 +39,7 @@ def process_template(template, preserve_order=True, file_path=None): try: return shell_safe_json_parse(result, preserve_order) except CLIError: - # Because the processing of removing comments and compression will lead to misplacement of error location, + # The processing of removing comments and compression will lead to misplacement of error location, # so the error message should be wrapped. if file_path: raise CLIError("Failed to parse '{}', please check whether it is a valid JSON format".format(file_path)) @@ -63,7 +63,7 @@ def pack(cmd, template_file): def _pack_artifacts(cmd, template_abs_file_path, context): """ Recursively packs the specified template and its referenced artifacts and - adds the artifacts to the current packing context. + adds the artifact(s) to the current packing context. :param template_abs_file_path: The path to the template spec .json file to pack. :type template_abs_file_path : str @@ -189,34 +189,39 @@ def unpack(cmd, exported_template, target_dir, template_file_name): root_template_file_path = os.path.join(target_dir, template_file_name) # TODO: Directory/file existence checks.. - # Go through each artifact ad make sure it's not going to place artifacts + # Iterate through artifacts to ensure no artifact will be placed # outside of the target directory: - for artifact in getattr(packaged_template, 'Artifacts'): - local_path = os.path.join(target_dir, - _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 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: + artifacts = getattr(packaged_template, 'Artifacts') + if artifacts is not None: + for artifact in artifacts: + local_path = os.path.join(target_dir, + _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 linked template ' + getattr(artifact, 'path') + + 'because it would create a file outside of the target directory hierarchy of' + + target_dir) + + # Process each artifact: + + LinkedTemplateArtifact = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, + 'LinkedTemplateArtifact', mod='models') + for artifact in artifacts: + 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)): + os.makedirs(os.path.dirname(abs_local_path)) + with open(abs_local_path, 'w') as artifact_file: + json.dump(getattr(artifact, 'template'), artifact_file, indent=2) + + # Write our main template file if not os.path.exists(target_dir): os.makedirs(os.path.dirname(target_dir)) with open(root_template_file_path, 'w') as root_file: json.dump(getattr(packaged_template, 'RootTemplate'), root_file, indent=2) - LinkedTemplateArtifact = get_sdk(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_TEMPLATESPECS, - 'LinkedTemplateArtifact', mod='models') - for artifact in getattr(packaged_template, 'Artifacts'): - 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)): - os.makedirs(os.path.dirname(abs_local_path)) - with open(abs_local_path, 'w') as artifact_file: - json.dump(getattr(artifact, 'template'), artifact_file, indent=2) return target_dir diff --git a/src/azure-cli/azure/cli/command_modules/resource/_params.py b/src/azure-cli/azure/cli/command_modules/resource/_params.py index 71fcd5554f2..499a78668d3 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/_params.py +++ b/src/azure-cli/azure/cli/command_modules/resource/_params.py @@ -52,8 +52,8 @@ def load_arguments(self, _): deployment_template_file_type = CLIArgumentType(options_list=['--template-file', '-f'], completer=FilesCompleter(), type=file_type, help="a path to a template file or Bicep file in the file system") deployment_template_uri_type = CLIArgumentType(options_list=['--template-uri', '-u'], help='a uri to a remote template file') - deployment_template_spec_type = CLIArgumentType(options_list=['--template-spec', '-s'], is_preview=True, min_api='2019-06-01', help="The template spec resource id.") - deployment_query_string_type = CLIArgumentType(options_list=['--query-string', '-q'], is_preview=True, help="The query string (a SAS token) to be used with the template-uri in the case of linked templates.") + deployment_template_spec_type = CLIArgumentType(options_list=['--template-spec', '-s'], min_api='2019-06-01', help="The template spec resource id.") + deployment_query_string_type = CLIArgumentType(options_list=['--query-string', '-q'], help="The query string (a SAS token) to be used with the template-uri in the case of linked templates.") deployment_parameters_type = CLIArgumentType(options_list=['--parameters', '-p'], action='append', nargs='+', completer=FilesCompleter(), help='the deployment parameters') filter_type = CLIArgumentType(options_list=['--filter'], is_preview=True, help='Filter expression using OData notation. You can use --filter "provisioningState eq \'{state}\'" to filter provisioningState. ' @@ -88,7 +88,7 @@ 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, + ui_form_definition_file_type = CLIArgumentType(options_list=['--ui-form-definition'], completer=FilesCompleter(), type=file_type, help="A path to a uiFormDefinition file in the file system") _PROVIDER_HELP_TEXT = 'the resource namespace, aka \'provider\'' diff --git a/src/azure-cli/azure/cli/command_modules/resource/commands.py b/src/azure-cli/azure/cli/command_modules/resource/commands.py index ed35ca1dba1..181da2ede34 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/commands.py +++ b/src/azure-cli/azure/cli/command_modules/resource/commands.py @@ -304,7 +304,7 @@ def load_command_table(self, _): g.custom_command('show-log', 'get_deployment_script_logs') g.custom_command('delete', 'delete_deployment_script', confirmation=True) - with self.command_group('ts', resource_templatespecs_sdk, resource_type=ResourceType.MGMT_RESOURCE_TEMPLATESPECS, is_preview=True, min_api='2019-06-01-preview') as g: + with self.command_group('ts', resource_templatespecs_sdk, resource_type=ResourceType.MGMT_RESOURCE_TEMPLATESPECS, min_api='2019-06-01-preview') as g: g.custom_command('create', 'create_template_spec', validator=process_ts_create_or_update_namespace) g.custom_command('update', 'update_template_spec', validator=process_ts_create_or_update_namespace, confirmation=True) g.custom_command('export', 'export_template_spec', validator=_validate_template_spec_out) diff --git a/src/azure-cli/azure/cli/command_modules/resource/custom.py b/src/azure-cli/azure/cli/command_modules/resource/custom.py index 432c6400eb2..bb5049d4ce9 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/custom.py +++ b/src/azure-cli/azure/cli/command_modules/resource/custom.py @@ -814,8 +814,8 @@ def _what_if_deploy_arm_template_core(cli_ctx, what_if_poller, no_pretty_print, try: if cli_ctx.enable_color: - # Diabling colorama since it will silently strip out the Xterm 256 color codes the What-If formatter - # is using. Unfortuanately, the colors that colorama supports are very limited, which doesn't meet our needs. + # Disabling colorama since it will silently strip out the Xterm 256 color codes the What-If formatter + # is using. Unfortunately, the colors that colorama supports are very limited, which doesn't meet our needs. from colorama import deinit deinit() From 62472a7e46c1b58fb5ee67839869b25408f9afd2 Mon Sep 17 00:00:00 2001 From: Dania Etienne Date: Fri, 23 Jul 2021 12:45:15 -0400 Subject: [PATCH 2/3] Specified error in packing engine --- .../azure/cli/command_modules/resource/_packing_engine.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py b/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py index 9deeaf54a03..7b8d90dc520 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py +++ b/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py @@ -6,6 +6,7 @@ import re import json from knack.util import CLIError +from azure.cli.core.azclierror import BadRequestError from azure.cli.core.util import read_file_content, shell_safe_json_parse from azure.cli.command_modules.resource.custom import _remove_comments_from_json from azure.cli.core.profiles import ResourceType, get_sdk @@ -97,7 +98,7 @@ def _pack_artifacts(cmd, template_abs_file_path, context): if(not os.path.commonpath([getattr(context, 'RootTemplateDirectory')]) == os.path.commonpath([getattr(context, 'RootTemplateDirectory'), abs_local_path])): - raise CLIError('Unable to handle the reference to file ' + abs_local_path + 'from ' + + raise BadRequestError('Unable to handle the reference to file ' + abs_local_path + 'from ' + template_abs_file_path + 'because it exists outside of the root template directory of ' + getattr(context, 'RootTemplateDirectory')) @@ -199,8 +200,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 linked template ' + getattr(artifact, 'path') + - 'because it would create a file outside of the target directory hierarchy of' + + raise BadRequestError('Unable to unpack linked template ' + getattr(artifact, 'path') + + 'because it would create a file outside of the target directory hierarchy of ' + target_dir) # Process each artifact: From 4ad65703714647235a1441361021485c5daeba6c Mon Sep 17 00:00:00 2001 From: Dania Etienne Date: Thu, 29 Jul 2021 06:25:22 -0400 Subject: [PATCH 3/3] Fixed styling error --- .vscode/launch.json | 7 ++++++- .../cli/command_modules/resource/_packing_engine.py | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c2a47d74891..daa798d1bd3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,12 @@ "program": "${workspaceRoot}/src/azure-cli/azure/cli/__main__.py", "cwd": "${workspaceRoot}", "args": [ - "--help" + "ts", + "export", + "-s", + "/subscriptions/a1bfa635-f2bf-42f1-86b5-848c674fc321/resourceGroups/Gokul-TestRG4/providers/Microsoft.Resources/templateSpecs/testTS/versions/1", + "--output-folder", + "C:\\Users\\daetienn\\Desktop\\ExportBugOutput2" ], "console": "integratedTerminal", "debugOptions": [ diff --git a/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py b/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py index 7b8d90dc520..d5ef2e565cb 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py +++ b/src/azure-cli/azure/cli/command_modules/resource/_packing_engine.py @@ -99,8 +99,9 @@ def _pack_artifacts(cmd, template_abs_file_path, context): if(not os.path.commonpath([getattr(context, 'RootTemplateDirectory')]) == os.path.commonpath([getattr(context, 'RootTemplateDirectory'), abs_local_path])): raise BadRequestError('Unable to handle the reference to file ' + abs_local_path + 'from ' + - template_abs_file_path + 'because it exists outside of the root template directory of ' + - getattr(context, 'RootTemplateDirectory')) + template_abs_file_path + + 'because it exists outside of the root template directory of ' + + getattr(context, 'RootTemplateDirectory')) # Convert the template relative path to one that is relative to our root # directory path, and then if we haven't already processed that template into @@ -201,8 +202,8 @@ def unpack(cmd, exported_template, target_dir, template_file_name): abs_local_path = os.path.abspath(local_path) if os.path.commonpath([target_dir]) != os.path.commonpath([target_dir, abs_local_path]): raise BadRequestError('Unable to unpack linked template ' + getattr(artifact, 'path') + - 'because it would create a file outside of the target directory hierarchy of ' + - target_dir) + 'because it would create a file outside of the target directory hierarchy of ' + + target_dir) # Process each artifact: