diff --git a/src/acrcssc/HISTORY.rst b/src/acrcssc/HISTORY.rst new file mode 100644 index 00000000000..0667aecd8da --- /dev/null +++ b/src/acrcssc/HISTORY.rst @@ -0,0 +1,16 @@ +.. :changelog: + +Release History +=============== + +1.1.1 +++++++ +* Release for Public Preview +* Added `list`and `cancel-run` commands for workflows +* `list` command provide output on the scan and patch status of the registry +* `cancel-run` command allows to canceling all running scan and patch tasks + + +1.1.0 +++++++ +* Initial release for Private Preview \ No newline at end of file diff --git a/src/acrcssc/README.rst b/src/acrcssc/README.rst new file mode 100644 index 00000000000..4b378e42a1f --- /dev/null +++ b/src/acrcssc/README.rst @@ -0,0 +1,104 @@ +Microsoft Azure CLI 'acrcssc' Extension +========================================== + +Azure Container Registry - Container Secure Supply Chain (Continuous Patching) +========================================== + +Overview +======== +The `acrcssc` extension for Azure CLI provides continuous patching capabilities for Azure Container Registry (ACR). This extension helps automate the process of scanning and patching container images to ensure they are up-to-date with the latest security patches. Scans your configured list of images for vulnerabilities (CVEs) using Trivy and patch them using Copacetic. + +Preview Limitations +=================== +Continuous Patching is currently in preview. The following limitations apply: + +- Windows-based container images aren’t supported +- Only "OS-level" vulnerabilities will be patched. This includes packages in the image managed by a package manager such as “apt” and “yum”. Vulnerabilities at the “application level” are unable to be patched, such as compiled languages like Go, Python, NodeJS +- Patching is only supported in Public regions, not in Sovereign regions +- CSSC patching is not supported for registries or in regions where Tasks are unavailable. + +Features +======== +- **Continuous Patching Workflow**: Automates the process of scanning and patching container images. +- **Task Management**: Create, update, delete, show, and cancel continuous patch tasks in the registry. +- **Dry Run Mode**: Validate the configuration without making any changes. +- **Immediate Run**: Trigger the patching workflow immediately. +- **Run Status**: Monitor the status of the scanning and patching tasks. + +Commands +======== +- `az acr supply-chain workflow create`: Create a continuous patch task in the registry. +- `az acr supply-chain workflow update`: Update an existing continuous patch task. +- `az acr supply-chain workflow delete`: Delete a continuous patch task. +- `az acr supply-chain workflow list`: List all continuous patch tasks in the registry. +- `az acr supply-chain workflow show`: Show details of a specific continuous patch task. +- `az acr supply-chain workflow cancel-run`: Cancel all running scan and patch tasks. + +Usage +===== +1. **Create a Continuous Patch Task**: + ```sh + az acr supply-chain workflow create --resource-group --registry --type continuouspatchv1 --schedule --config + ``` + +1. **Update a Continuous Patch Task**: + ```sh + az acr supply-chain workflow update --resource-group --registry --type continuouspatchv1 --schedule --config + ``` + +1. **Update with dryrun to test configuration changes**: + ```sh + az acr supply-chain workflow update --resource-group --registry --type continuouspatchv1 --config --dryrun + ``` + +1. **Delete a Continuous Patch Task**: + ```sh + az acr supply-chain workflow delete --resource-group --registry --type continuouspatchv1 + ``` + +1. **List Continuous Patch Tasks**: + ```sh + az acr supply-chain workflow list --resource-group --registry --type continuouspatchv1 --run-status + ``` + +1. **Show a Continuous Patch Task**: + ```sh + az acr supply-chain workflow show --resource-group --registry --type continuouspatchv1 + ``` + +1. **Cancel all Scan and Patch Running Tasks**: + ```sh + az acr supply-chain workflow cancel-run --resource-group --registry --type continuouspatchv1 + ``` + +Configuration +============= +The configuration file for the continuous patch task should define the repositories to be scanned and patched, the schedule for the task, and any other relevant settings. + +Example Configuration: + +```JSON +{ + "repositories": [ + { + "repository": "alpine", + "tags": ["tag1", "tag2"], + "enabled": true + }, + { + "repository": "python", + "tags": ["*"], + "enabled": false + } + ], + "version": "v1", + "tag-convention": "floating" +} +``` + +Tag Convention +============== +The `tag-convention` property in the configuration file determines how the tags for patched images are managed. It can have the following values: + +- **incremental**: This is the default behavior. It increases the patch version of the tag. For example, if the original tag is `1.0`, the patched tags will be `1.0-1`, `1.0-2`, etc. +- **floating**: This reuses the tag postfix `patched` for patching. For example, if the original tag is `1.0`, the patched tag will be `1.0-patched`. diff --git a/src/acrcssc/azext_acrcssc/__init__.py b/src/acrcssc/azext_acrcssc/__init__.py new file mode 100644 index 00000000000..86d733516bd --- /dev/null +++ b/src/acrcssc/azext_acrcssc/__init__.py @@ -0,0 +1,32 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from azure.cli.core import AzCommandsLoader + +from azext_acrcssc._help import helps # pylint: disable=unused-import + + +class AcrcsscCommandsLoader(AzCommandsLoader): + + def __init__(self, cli_ctx=None): + from azure.cli.core.commands import CliCommandType + from azext_acrcssc._client_factory import cf_acr + acrcssc_custom = CliCommandType( + operations_tmpl='azext_acrcssc.custom#{}', + client_factory=cf_acr) + super(AcrcsscCommandsLoader, self).__init__(cli_ctx=cli_ctx, + custom_command_type=acrcssc_custom) + + def load_command_table(self, args): + from azext_acrcssc.commands import load_command_table + load_command_table(self, args) + return self.command_table + + def load_arguments(self, command): + from azext_acrcssc._params import load_arguments + load_arguments(self, command) + + +COMMAND_LOADER_CLS = AcrcsscCommandsLoader diff --git a/src/acrcssc/azext_acrcssc/_client_factory.py b/src/acrcssc/azext_acrcssc/_client_factory.py new file mode 100644 index 00000000000..508e4f1a006 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/_client_factory.py @@ -0,0 +1,61 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +from azure.cli.core.commands.client_factory import get_mgmt_service_client +from azure.cli.core.profiles import ResourceType +from azure.mgmt.containerregistry import ContainerRegistryManagementClient +from .helper._constants import ( + ACR_API_VERSION_2023_01_01_PREVIEW, + ACR_API_VERSION_2019_06_01_PREVIEW +) + +from azure.mgmt.authorization import AuthorizationManagementClient + + +def cf_acr(cli_ctx, *_) -> ContainerRegistryManagementClient: + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_CONTAINERREGISTRY, + api_version=ACR_API_VERSION_2023_01_01_PREVIEW) + + +def cf_acr_registries(cli_ctx, *_) -> ContainerRegistryManagementClient: + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_CONTAINERREGISTRY, + api_version=ACR_API_VERSION_2023_01_01_PREVIEW).registries + + +def cf_acr_tasks(cli_ctx, *_): + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_CONTAINERREGISTRY, + api_version=ACR_API_VERSION_2019_06_01_PREVIEW).tasks + + +def cf_acr_registries_tasks(cli_ctx, *_): + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_CONTAINERREGISTRY, + api_version=ACR_API_VERSION_2019_06_01_PREVIEW).registries + + +def cf_acr_taskruns(cli_ctx, *_): + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_CONTAINERREGISTRY, + api_version=ACR_API_VERSION_2019_06_01_PREVIEW).task_runs + + +def cf_acr_runs(cli_ctx, *_): + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_CONTAINERREGISTRY, + api_version=ACR_API_VERSION_2019_06_01_PREVIEW).runs + + +def cf_resources(cli_ctx, subscription_id=None): + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_RESOURCE_RESOURCES, + subscription_id=subscription_id) + + +def cf_authorization(cli_ctx, subscription_id=None) -> AuthorizationManagementClient: + return get_mgmt_service_client(cli_ctx, + ResourceType.MGMT_AUTHORIZATION, + subscription_id=subscription_id, api_version="2022-04-01") diff --git a/src/acrcssc/azext_acrcssc/_help.py b/src/acrcssc/azext_acrcssc/_help.py new file mode 100644 index 00000000000..d7a7b49b2d0 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/_help.py @@ -0,0 +1,66 @@ +# coding=utf-8 +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from knack.help_files import helps # pylint: disable=unused-import + +helps['acr supply-chain'] = """ + type: group + short-summary: Commands to manage acr supply chain resources. +""" + +helps['acr supply-chain workflow'] = """ + type: group + short-summary: Commands to manage acr supply chain workflows. +""" + +helps['acr supply-chain workflow create'] = """ + type: command + short-summary: Create acr supply chain workflow. + examples: + - name: Create acr supply chain workflow + text: az acr supply-chain workflow create -r $MyRegistry -g $MyResourceGroup \ + --type continuouspatchv1 --schedule 1d --config path-to-config-file +""" +helps['acr supply-chain workflow update'] = """ + type: command + short-summary: Update acr supply chain workflow. + examples: + - name: Update acr supply chain workflow + text: az acr supply-chain workflow update -r $MyRegistry -g $MyResourceGroup --type \ + continuouspatchv1 --schedule 1d --config path-to-config-file +""" + +helps['acr supply-chain workflow show'] = """ + type: command + short-summary: Show acr supply chain workflow tasks. + examples: + - name: Show all acr supply chain workflow + text: az acr supply-chain workflow show -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1 +""" + +helps['acr supply-chain workflow delete'] = """ + type: command + short-summary: Delete acr supply chain workflow. + examples: + - name: Delete acr supply chain workflow and associated configuration files + text: az acr supply-chain workflow delete -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1 +""" + +helps['acr supply-chain workflow cancel-run'] = """ + type: command + short-summary: Cancel currently running supply chain workflow. + examples: + - name: Cancel currently running acr supply chain workflow scans/patch + text: az acr supply-chain workflow cancel-run -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1 +""" + +helps['acr supply-chain workflow list'] = """ + type: command + short-summary: List status of acr supply chain workflow images. + examples: + - name: List all acr supply chain workflow images based on the status provided + text: az acr supply-chain workflow list -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1 --run-status Failed +""" diff --git a/src/acrcssc/azext_acrcssc/_params.py b/src/acrcssc/azext_acrcssc/_params.py new file mode 100644 index 00000000000..0b579f03e73 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/_params.py @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +# pylint: disable=line-too-long +from azure.cli.command_modules.acr._constants import REGISTRY_RESOURCE_TYPE +from azure.cli.command_modules.acr._validators import validate_registry_name +from azure.cli.core import AzCommandsLoader +from azure.cli.core.commands.parameters import (get_resource_name_completion_list, get_three_state_flag, get_enum_type) +from .helper._constants import CONTINUOUSPATCH_SCHEDULE_MAX_DAYS + + +def load_arguments(self: AzCommandsLoader, _): + from .helper._constants import CSSCTaskTypes + from .helper._workflow_status import WorkflowTaskState + + with self.argument_context("acr supply-chain workflow") as c: + c.argument('resource_group', options_list=['--resource-group', '-g'], help='Name of resource group. You can configure the default group using `az configure --defaults group=`', completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE)) + c.argument('registry_name', options_list=['--registry', '-r'], help='The name of the container registry. It should be specified in lower case. You can configure the default registry name using `az configure --defaults acr=`', completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE), configured_default='acr', validator=validate_registry_name) + c.argument("workflow_type", arg_type=get_enum_type(CSSCTaskTypes), options_list=['--type', '-t'], help="Type of workflow task.", required=True) + + with self.argument_context("acr supply-chain workflow create") as c: + c.argument("config", help="Configuration file path containing the json schema for the list of repositories and tags to filter within the registry. Schema example:{\"repositories\":[{\"repository\":\"alpine\",\"tags\":[\"tag1\",\"tag2\"],\"enabled\":true},{\"repository\":\"python\",\"tags\":[\"*\"],\"enabled\":false}], \"version\": \"v1\", \"tag-convention\": \"floating\"}. \"tag-convention\" is an optional property, values can be \"incremental\" (the default behavior, will increase the patch version of the tag, for example \"{repository}:{original-tag}-1\", \"{repository}:{original-tag}-2\", etc), or \"floating\" (will reuse the tag \"{repository}:{original-tag}-patched\" for patching)", required=True) + c.argument("schedule", help=f"schedule to run the scan and patching task. E.g. `d` where is the number of days between each run. Max value is {CONTINUOUSPATCH_SCHEDULE_MAX_DAYS}d.", required=True) + c.argument("run_immediately", help="Set this flag to trigger the immediate run of the selected workflow task. Default value: false.", arg_type=get_three_state_flag()) + c.argument("dryrun", options_list=["--dry-run"], help="Use this flag to see the qualifying repositories and tags that would be affected by the workflow. Default value: false. 'config' parameter is mandatory to provide with dry-run", arg_type=get_three_state_flag()) + + with self.argument_context("acr supply-chain workflow update") as c: + c.argument("config", help="Configuration file path containing the json schema for the list of repositories and tags to filter within the registry. Schema example:{\"repositories\":[{\"repository\":\"alpine\",\"tags\":[\"tag1\",\"tag2\"],\"enabled\":true},{\"repository\":\"python\",\"tags\":[\"*\"],\"enabled\":false}], \"version\": \"v1\", \"tag-convention\": \"floating\"}. \"tag-convention\" is an optional property, values can be \"incremental\" (the default behavior, will increase the patch version of the tag, for example \"{repository}:{original-tag}-1\", \"{repository}:{original-tag}-2\", etc), or \"floating\" (will reuse the tag \"{repository}:{original-tag}-patched\" for patching)") + c.argument("schedule", help=f"schedule to run the scan and patching task. E.g. `d` where n is the number of days between each run. Max value is {CONTINUOUSPATCH_SCHEDULE_MAX_DAYS}d.") + c.argument("run_immediately", help="Set this flag to trigger the immediate run of the selected workflow task. Default value: false.", arg_type=get_three_state_flag()) + c.argument("dryrun", options_list=["--dry-run"], help="Use this flag to see the qualifying repositories and tags that would be affected by the workflow. Default value: false. 'config' parameter is mandatory to provide with dry-run", arg_type=get_three_state_flag()) + + with self.argument_context("acr supply-chain workflow list") as c: + c.argument("status", arg_type=get_enum_type(WorkflowTaskState), options_list=["--run-status"], help="Status to filter the supply-chain workflow image status.") + + with self.argument_context("acr supply-chain workflow delete") as c: + c.argument("yes", options_list=["--yes", "-y"], help="Proceed with the deletion without user confirmation") diff --git a/src/acrcssc/azext_acrcssc/_validators.py b/src/acrcssc/azext_acrcssc/_validators.py new file mode 100644 index 00000000000..f0e2e548f86 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/_validators.py @@ -0,0 +1,170 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +# pylint: disable=line-too-long +# pylint: disable=broad-exception-caught +# pylint: disable=logging-fstring-interpolation +import os +import re +from knack.log import get_logger +from azure.cli.command_modules.acr.repository import acr_repository_show +from .helper._constants import ( + BEARER_TOKEN_USERNAME, + CSSC_WORKFLOW_POLICY_REPOSITORY, + CONTINUOUSPATCH_IMAGE_LIMIT, + CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG, + CONTINUOUSPATCH_CONFIG_SCHEMA_SIZE_LIMIT, + CONTINUOUSPATCH_ALL_TASK_NAMES, + ERROR_MESSAGE_INVALID_TIMESPAN_FORMAT, + SUBSCRIPTION) +from .helper._constants import CSSCTaskTypes, ERROR_MESSAGE_INVALID_TASK +from .helper._ociartifactoperations import _get_acr_token, ContinuousPatchConfig +from azure.mgmt.core.tools import (parse_resource_id) +from azure.cli.core.azclierror import InvalidArgumentValueError +from ._client_factory import cf_acr_tasks +from .helper._utility import get_task, convert_timespan_to_cron + +logger = get_logger(__name__) + + +def validate_continuouspatch_config_v1(config_path): + _validate_continuouspatch_file(config_path) + config = validate_continuouspatch_json(config_path) + _validate_continuouspatch_config(config) + + +def _validate_continuouspatch_file(config_path): + if not os.path.exists(config_path): + raise InvalidArgumentValueError(f"Config path file: {config_path} does not exist in the path specified") + if not os.path.isfile(config_path): + raise InvalidArgumentValueError(f"Config path file: {config_path} is not a valid file") + if os.path.getsize(config_path) > CONTINUOUSPATCH_CONFIG_SCHEMA_SIZE_LIMIT: + raise InvalidArgumentValueError(f"Config path file: {config_path} is too large. Max size limit is {CONTINUOUSPATCH_CONFIG_SCHEMA_SIZE_LIMIT / (1024 * 1024)} MB") + if os.path.getsize(config_path) == 0: + raise InvalidArgumentValueError(f"Config path file: {config_path} is empty") + if not os.access(config_path, os.R_OK): + raise InvalidArgumentValueError(f"Config path file: '{config_path}' is not readable") + + +def validate_continuouspatch_json(config_path): + config = ContinuousPatchConfig().from_file(file_path=config_path) + if not config: + raise InvalidArgumentValueError(f"Config path file: {config_path} is not a valid JSON file. Use --help to see the schema of the config file.") + return config + + +def _validate_continuouspatch_config(config): + if not isinstance(config, ContinuousPatchConfig): + raise InvalidArgumentValueError("Config file is not a valid JSON file. Use --help to see the schema of the config file.") + for repository in config.repositories: + for tag in repository.tags: + if re.match(r'.*-patched$', tag) or re.match(r'.*-[0-9]{1,3}$', tag): + raise InvalidArgumentValueError(f"Configuration error: Repository '{repository.repository}' with tag '{tag}' is not allowed. Tags ending with '*-patched' (floating tag) or '*-0' to '*-999' (incremental tag) are reserved for internal use.") + if tag == "*" and len(repository.tags) > 1: + raise InvalidArgumentValueError("Configuration error: Tag '*' is not allowed with other tags in the same repository. Use '*' as the only tag in the repository to avoid overlaps.") + + +# to save on API calls, we use task_list to return a list of CSSC tasks found in the registry +def check_continuous_task_exists(cmd, registry): + task_list = [] + missing_tasks = [] + + acrtask_client = cf_acr_tasks(cmd.cli_ctx) + for task_name in CONTINUOUSPATCH_ALL_TASK_NAMES: + try: + task = get_task(cmd, registry, task_name, acrtask_client) + if task is None: + missing_tasks.append(task_name) + else: + task_list.append(task) + except Exception as exception: + logger.debug(f"Failed to find tasks from registry {registry.name} : {exception}") + missing_tasks.append(task_name) + + if missing_tasks: + logger.debug(f"Failed to find tasks {', '.join(missing_tasks)} from registry {registry.name}") + return False, task_list + + return True, task_list + + +def check_continuous_task_config_exists(cmd, registry): + # A client cannot be used in this situation because the 'show registry/image' + # is a data plane operation and the az cli does not include the data plane API. + subscription = parse_resource_id(registry.id)[SUBSCRIPTION] + try: + token = _get_acr_token(registry.name, subscription) + acr_repository_show( + cmd=cmd, + registry_name=registry.name, + repository=f"{CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG}", + username=BEARER_TOKEN_USERNAME, + password=token) + except Exception as exception: + if hasattr(exception, 'status_code') and exception.status_code == 404: + return False + # report on the error only if we get something other than 404 + logger.error(f"Failed to find config {CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG} from registry {registry.name} : {exception}") + raise + return True + + +def _validate_schedule(schedule): + # during update, schedule can be null if we are only updating the config + if schedule is None: + return + # the convertion to cron will raise an error if the format is invalid + cron = convert_timespan_to_cron(schedule) + if not cron: + raise InvalidArgumentValueError(error_msg=ERROR_MESSAGE_INVALID_TIMESPAN_FORMAT) + + +def validate_inputs(schedule, config_file_path=None, dryrun=False, run_immediately=False): + _validate_schedule(schedule) + if config_file_path: + validate_continuouspatch_config_v1(config_file_path) + validate_run_type(dryrun, run_immediately) + + +def validate_run_type(dryrun, run_immediately): + if dryrun and run_immediately: + raise InvalidArgumentValueError(error_msg="The --dryrun and --run-immediately options cannot be used together. Use one or the other.") + + +def validate_task_type(task_type): + if (task_type not in [item.value for item in CSSCTaskTypes]): + raise InvalidArgumentValueError(error_msg=ERROR_MESSAGE_INVALID_TASK % task_type) + + +def validate_cssc_optional_inputs(cssc_config_path, schedule): + if cssc_config_path is None and schedule is None: + raise InvalidArgumentValueError(error_msg="Provide at least one parameter to update: --schedule or --config") + + +def validate_continuous_patch_v1_image_limit(dryrun_log): + match = re.search(r"Matches found: (\d+)", dryrun_log) + if match is None: + # the quick task did not return the expected output, we cannot validate the image limit but cannot block the operation + logger.error("Failed to parse the image limit from the dry run log. Execution will continue.") + logger.debug("Dry run log: %s", dryrun_log) + return + + image_limit = int(match.group(1)) + + if image_limit > CONTINUOUSPATCH_IMAGE_LIMIT: + # these expressions remove all the Task related output from the log, and only leaves the listing of repositories and tags + pattern_prefix = "Listing repositories and tags matching the filter" + result = re.sub(r'^(.*\n)*?' + re.escape(pattern_prefix), pattern_prefix, dryrun_log, flags=re.MULTILINE) + + pattern_postfix = "Adjust the JSON filter to limit the number of images." + result = re.sub(r'(?s)' + re.escape(pattern_postfix) + r'.*', pattern_postfix, result) + + raise InvalidArgumentValueError(error_msg=result) + + if image_limit == 0: + # when no matching images are found, we should relay the information to the user + # extract everything between and including the target lines + match = re.search(r'No matching repository and tag found!.*?Matches found: 0', dryrun_log, re.DOTALL) + if match: + logger.warning(match.group()) diff --git a/src/acrcssc/azext_acrcssc/azext_metadata.json b/src/acrcssc/azext_acrcssc/azext_metadata.json new file mode 100644 index 00000000000..b165ea04b95 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/azext_metadata.json @@ -0,0 +1,4 @@ +{ + "azext.isPreview": true, + "azext.minCliCoreVersion": "2.60.0" +} \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/commands.py b/src/acrcssc/azext_acrcssc/commands.py new file mode 100644 index 00000000000..74311bac307 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/commands.py @@ -0,0 +1,20 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=line-too-long +from azext_acrcssc._client_factory import cf_acr + + +def load_command_table(self, _): + # required to mark the command as 'preview', can be expanded if additional commands are added + self.command_group("acr supply-chain", client_factory=cf_acr, is_preview=True) + + with self.command_group("acr supply-chain workflow", client_factory=cf_acr, is_preview=True) as g: + g.custom_command("create", "create_acrcssc") + g.custom_command("update", "update_acrcssc") + g.custom_command("delete", "delete_acrcssc") + g.custom_show_command("show", "show_acrcssc") + g.custom_command("cancel-run", "cancel_runs") + g.custom_command("list", "list_scan_status") diff --git a/src/acrcssc/azext_acrcssc/cssc.py b/src/acrcssc/azext_acrcssc/cssc.py new file mode 100644 index 00000000000..733949ba7c4 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/cssc.py @@ -0,0 +1,152 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +# pylint: disable=line-too-long +# pylint: disable=logging-fstring-interpolation +from azure.cli.core.util import user_confirmation +from knack.log import get_logger +from .helper._constants import CONTINUOUS_PATCHING_WORKFLOW_NAME +from .helper._taskoperations import ( + create_update_continuous_patch_v1, + delete_continuous_patch_v1, + list_continuous_patch_v1, + acr_cssc_dry_run, + cancel_continuous_patch_runs, + track_scan_progress +) +from ._validators import ( + validate_inputs, + validate_task_type, + validate_cssc_optional_inputs, + validate_continuous_patch_v1_image_limit +) +from azext_acrcssc._client_factory import cf_acr_registries + +logger = get_logger(__name__) + + +def _perform_continuous_patch_operation(cmd, + resource_group_name, + registry_name, + config, + schedule, + dryrun=False, + run_immediately=False, + is_create=True): + acr_client_registries = cf_acr_registries(cmd.cli_ctx, None) + registry = acr_client_registries.get(resource_group_name, registry_name) + + validate_inputs(schedule, config, dryrun, run_immediately) + + if not is_create: + validate_cssc_optional_inputs(config, schedule) + + logger.debug('validations completed successfully.') + + # every time we perform a create or update operation, we need to validate for the number of images selected on the + # configuration file. The way to do this is by silently running the dryrun operation. If the limit is exceeded, we + # will not proceed with the operation. + dryrun_output = acr_cssc_dry_run(cmd, + registry=registry, + config_file_path=config, + is_create=is_create, + remove_internal_statements=not dryrun) + if dryrun: + print(dryrun_output) + else: + validate_continuous_patch_v1_image_limit(dryrun_output) + create_update_continuous_patch_v1(cmd, registry, config, schedule, dryrun, run_immediately, is_create) + + +def create_acrcssc(cmd, + resource_group_name, + registry_name, + workflow_type, + config, + schedule, + dryrun=False, + run_immediately=False): + '''Create a continuous patch task in the registry.''' + logger.debug(f"Entering create_acrcssc with parameters: {registry_name} {workflow_type} {config} {schedule} {dryrun}") + _perform_continuous_patch_operation(cmd, + resource_group_name, + registry_name, + config, + schedule, + dryrun, + run_immediately, + is_create=True) + + +def update_acrcssc(cmd, + resource_group_name, + registry_name, + workflow_type, + config=None, + schedule=None, + dryrun=False, + run_immediately=False): + '''Update a continuous patch task in the registry.''' + logger.debug(f'Entering update_acrcssc with parameters: {registry_name} {workflow_type} {config} {schedule} {dryrun} {run_immediately}') + _perform_continuous_patch_operation(cmd, + resource_group_name, + registry_name, + config, + schedule, + dryrun, + run_immediately, + is_create=False) + + +def delete_acrcssc(cmd, + resource_group_name, + registry_name, + workflow_type, + yes=False): + '''Delete a continuous patch task in the registry.''' + logger.debug(f"Entering delete_acrcssc with parameters: {resource_group_name} {registry_name} {workflow_type}") + + validate_task_type(workflow_type) + acr_client_registries = cf_acr_registries(cmd.cli_ctx, None) + registry = acr_client_registries.get(resource_group_name, registry_name) + + user_confirmation(f"Are you sure you want to delete the workflow {CONTINUOUS_PATCHING_WORKFLOW_NAME} from registry {registry_name}?", yes=yes) + + delete_continuous_patch_v1(cmd, registry, yes=yes) + print(f"Deleted {CONTINUOUS_PATCHING_WORKFLOW_NAME} workflow successfully from registry {registry_name}") + + +def show_acrcssc(cmd, + resource_group_name, + registry_name, + workflow_type): + '''Show a continuous patch task in the registry.''' + logger.debug(f'Entering show_acrcssc with parameters: {registry_name} {workflow_type}') + + acr_client_registries = cf_acr_registries(cmd.cli_ctx, None) + registry = acr_client_registries.get(resource_group_name, registry_name) + + validate_task_type(workflow_type) + return list_continuous_patch_v1(cmd, registry) + + +def cancel_runs(cmd, + resource_group_name, + registry_name, + workflow_type): + '''cancel all running scans in continuous patch in the registry.''' + logger.debug('Entering cancel_runs with parameters:%s %s %s', resource_group_name, registry_name, workflow_type) + validate_task_type(workflow_type) + cancel_continuous_patch_runs(cmd, resource_group_name, registry_name) + + +def list_scan_status(cmd, registry_name, resource_group_name, workflow_type, status=None): + '''track in continuous patch in the registry.''' + logger.debug('Entering track_scan_status with parameters:%s %s %s', resource_group_name, registry_name, workflow_type) + + validate_task_type(workflow_type) + acr_client_registries = cf_acr_registries(cmd.cli_ctx, None) + registry = acr_client_registries.get(resource_group_name, registry_name) + + return track_scan_progress(cmd, resource_group_name, registry, status) diff --git a/src/acrcssc/azext_acrcssc/custom.py b/src/acrcssc/azext_acrcssc/custom.py new file mode 100644 index 00000000000..3d9f68794d0 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/custom.py @@ -0,0 +1,7 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +# pylint: disable=unused-import + +from .cssc import create_acrcssc, update_acrcssc, delete_acrcssc, show_acrcssc, cancel_runs, list_scan_status diff --git a/src/acrcssc/azext_acrcssc/helper/__init__.py b/src/acrcssc/azext_acrcssc/helper/__init__.py new file mode 100644 index 00000000000..34913fb394d --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/__init__.py @@ -0,0 +1,4 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- diff --git a/src/acrcssc/azext_acrcssc/helper/_constants.py b/src/acrcssc/azext_acrcssc/helper/_constants.py new file mode 100644 index 00000000000..f9a9562ac18 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/_constants.py @@ -0,0 +1,141 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +"""Constants used across the extension.""" +# pylint: disable=line-too-long +from enum import Enum + + +# This enum is used to define the task types for the CLI, in case new types are added this is the place to start +class CSSCTaskTypes(Enum): + """Enum for the task type.""" + ContinuousPatchV1 = 'continuouspatchv1' + + +class TaskRunStatus(Enum): + """Enum for the task status. ACR.Build.Contracts""" + Unknown = 'Unknown' + Queued = 'Queued' + Started = 'Started' + Running = 'Running' + Succeeded = 'Succeeded' + Failed = 'Failed' + Canceled = 'Canceled' + Error = 'Error' + Timeout = 'Timeout' + + +# General Constants +CSSC_TAGS = "acr-cssc" +ACR_API_VERSION_2023_01_01_PREVIEW = "2023-01-01-preview" +ACR_API_VERSION_2019_06_01_PREVIEW = "2019-06-01-preview" +BEARER_TOKEN_USERNAME = "00000000-0000-0000-0000-000000000000" +RESOURCE_GROUP = "resource_group" +SUBSCRIPTION = "subscription" +TMP_DRY_RUN_FILE_NAME = "tmp_dry_run_template.yaml" + + +# Continuous Patch Constants +CONTINUOUSPATCH_IMAGE_LIMIT = 100 +CONTINUOUSPATCH_OCI_ARTIFACT_TYPE = "oci-artifact" +CSSC_WORKFLOW_POLICY_REPOSITORY = "csscpolicies" +CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG = "patchpolicy" +CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1 = "v1" +CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_DRYRUN = "dryrun" +CONTINUOUSPATCH_DEPLOYMENT_NAME = "continuouspatchingdeployment" +CONTINUOUSPATCH_DEPLOYMENT_TEMPLATE = "CSSC-AutoImagePatching-encodedtasks.json" +# listing all individual tasks that are required for Continuous Patching to work +CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME = "cssc-patch-image" +CONTINUOUSPATCH_TASK_PATCHIMAGE_DESCRIPTION = "This task will patch the OS vulnerabilities on a given image using Copacetic." +CONTINUOUSPATCH_TASK_SCANIMAGE_NAME = "cssc-scan-image" +CONTINUOUSPATCH_TASK_SCANIMAGE_DESCRIPTION = f"This task will perform vulnerability OS scan on a given image using Trivy. If there are any vulnerabilities found, it will trigger the patching task using {CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME} task." +CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME = "cssc-trigger-workflow" +CONTINUOUSPATCH_TASK_SCANREGISTRY_DESCRIPTION = f"This task will trigger the continuous patching workflow based on the schedule set during the creation. It will match the filter repositories set with config parameter and schedule vulnerability scan check using {CONTINUOUSPATCH_TASK_SCANIMAGE_NAME} task." +CONTINUOUS_PATCHING_WORKFLOW_NAME = CSSCTaskTypes.ContinuousPatchV1.value +DESCRIPTION = "Description" +CONTINUOUSPATCH_SCHEDULE_MIN_DAYS = 1 +CONTINUOUSPATCH_SCHEDULE_MAX_DAYS = 30 + + +CONTINUOUSPATCH_ALL_TASK_NAMES = [ + CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME, + CONTINUOUSPATCH_TASK_SCANIMAGE_NAME, + CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME +] + +WORKFLOW_STATUS_NOT_AVAILABLE = "---Not Available---" +WORKFLOW_STATUS_PATCH_NOT_AVAILABLE = "---No patch image available---" +WORKFLOW_VALIDATION_MESSAGE = "Validating configuration" + +ERROR_MESSAGE_WORKFLOW_TASKS_DOES_NOT_EXIST = f"{CONTINUOUS_PATCHING_WORKFLOW_NAME} workflow tasks does not exist. Run 'az acr supply-chain workflow create' command to create workflow tasks." +ERROR_MESSAGE_WORKFLOW_TASKS_ALREADY_EXISTS = f"{CONTINUOUS_PATCHING_WORKFLOW_NAME} workflow tasks already exists. Use 'az acr supply-chain workflow update' command to perform updates." +ERROR_MESSAGE_INVALID_TASK = "Workflow type %s is invalid" +ERROR_MESSAGE_INVALID_TIMESPAN_VALUE = "Schedule value is invalid. " +ERROR_MESSAGE_INVALID_TIMESPAN_FORMAT = "Schedule format is invalid. " +ERROR_MESSAGE_INVALID_JSON_PARSE = "File used for --config cannot be parsed as a JSON file. Use --help to see the schema of the config file." +ERROR_MESSAGE_INVALID_JSON_SCHEMA = "File used for --config is not a valid config JSON file. Use --help to see the schema of the config file." +RECOMMENDATION_SCHEDULE = f"Schedule must be in the format of where unit is d for days. Example: {CONTINUOUSPATCH_SCHEDULE_MIN_DAYS}d. Max value for d is {CONTINUOUSPATCH_SCHEDULE_MAX_DAYS}d." + +# this dictionary can be expanded to handle more configuration of the tasks regarding continuous patching +# if this gets out of hand, or more types of tasks are supported, this should be a class on its own +CONTINUOUSPATCH_TASK_DEFINITION = { + CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME: + { + "parameter_name": "imagePatchingEncodedTask", + "template_file": "task/cssc_patch_image.yaml", + DESCRIPTION: CONTINUOUSPATCH_TASK_PATCHIMAGE_DESCRIPTION + }, + CONTINUOUSPATCH_TASK_SCANIMAGE_NAME: + { + "parameter_name": "imageScanningEncodedTask", + "template_file": "task/cssc_scan_image.yaml", + DESCRIPTION: CONTINUOUSPATCH_TASK_SCANIMAGE_DESCRIPTION + }, + CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME: + { + "parameter_name": "registryScanningEncodedTask", + "template_file": "task/cssc_trigger_workflow.yaml", + DESCRIPTION: CONTINUOUSPATCH_TASK_SCANREGISTRY_DESCRIPTION + }, +} +CONTINUOUSPATCH_CONFIG_SCHEMA_SIZE_LIMIT = 1024 * 1024 * 10 # 10MB, we don't want to allow huge files +CONTINUOUSPATCH_CONFIG_SCHEMA_V1 = { + "type": "object", + "properties": { + "version": { + "type": "string", + "pattern": "^(v1)$" + }, + "tag-convention": { + "type": "string", + "pattern": "^(floating|incremental)$" + }, + "repositories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": True, + "minItems": 1 + }, + "enabled": { + "type": "boolean" + } + }, + "required": ["repository", "tags"] + }, + "uniqueItems": True, + "minItems": 1 + } + }, + "required": ["repositories", "version"] +} diff --git a/src/acrcssc/azext_acrcssc/helper/_deployment.py b/src/acrcssc/azext_acrcssc/helper/_deployment.py new file mode 100644 index 00000000000..f00653aef6c --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/_deployment.py @@ -0,0 +1,143 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +"""A module to handle deployment functions related to tasks.""" +import os +from typing import Optional +from .._client_factory import cf_resources +from azure.cli.core.util import get_file_json +from azure.cli.core.azclierror import AzCLIError +from azure.cli.core.commands import LongRunningOperation +from azure.mgmt.resource.resources.models import ( + DeploymentExtended, + DeploymentProperties, + DeploymentMode, + Deployment +) +from knack.log import get_logger +# pylint: disable=line-too-long +# pylint: disable=logging-fstring-interpolation +logger = get_logger(__name__) + + +def validate_and_deploy_template(cmd_ctx, + registry, + resource_group: str, + deployment_name: str, + template_file_name: str, + parameters: dict, + dryrun: Optional[bool] = False): + logger.debug(f'Working with resource group {resource_group}, registry {registry} template {template_file_name}') + + deployment_path = os.path.dirname( + os.path.join( + os.path.dirname( + os.path.abspath(__file__)), + "../templates/")) + + arm_path = os.path.join(deployment_path, "arm") + template_path = os.path.join(arm_path, template_file_name) + template = DeploymentProperties( + template=get_file_json(template_path), + parameters=parameters, + mode=DeploymentMode.incremental) + try: + validate_template(cmd_ctx, resource_group, deployment_name, template) + if dryrun: + logger.debug("Dry run, skipping deployment") + return None + + return deploy_template(cmd_ctx, resource_group, deployment_name, template) + except Exception as exception: + raise AzCLIError(f'Failed to validate and deploy template: {exception}') + + +def validate_template(cmd_ctx, resource_group, deployment_name, template): + # Validation is automatically re-attempted in live runs, but not in test + # playback, causing them to fail. This explicitly re-attempts validation to + # ensure the tests pass + api_clients = cf_resources(cmd_ctx) + validation_res = None + deployment = Deployment( + properties=template + ) + + for validation_attempt in range(2): + try: + validation = ( + api_clients.deployments.begin_validate( + resource_group_name=resource_group, + deployment_name=deployment_name, + parameters=deployment + ) + ) + validation_res = LongRunningOperation( + cmd_ctx, "Validating ARM template..." + )(validation) + break + except Exception as exception: # pylint: disable=broad-except + logger.debug(f"Validation attempt {validation_attempt + 1} failed for template {template}, exception: {exception}") + if validation_attempt == 1: + raise + + if not validation_res: + # Don't expect to hit this but it appeases mypy + raise RuntimeError(f"Validation of template {template} failed.") + + logger.debug(f"Validation Result {validation_res}") + if validation_res.error: + # Validation failed so don't even try to deploy + logger.error( + ( + f"Template for resource group {resource_group} has failed validation. The message" + f" was: {validation_res.error.message}. See logs for additional details." + ) + ) + logger.debug( + ( + f"Template for resource group {resource_group} failed validation." + f" Full error details: {validation_res.error}" + ) + ) + raise RuntimeError("Azure template validation failed.") + + # Validation succeeded so proceed with deployment + logger.debug(f"Successfully validated resources for {resource_group}") + + +def deploy_template(cmd_ctx, resource_group, deployment_name, template): + api_client = cf_resources(cmd_ctx) + + deployment = Deployment( + properties=template + ) + + poller = api_client.deployments.begin_create_or_update( + resource_group_name=resource_group, + deployment_name=deployment_name, + parameters=deployment) + + # Wait for the deployment to complete and get the outputs + deployment: DeploymentExtended = LongRunningOperation( + cmd_ctx + )(poller) + logger.debug("Finished deploying") + + if deployment.properties is None: + raise RuntimeError("The deployment has no properties.\nAborting") + + depl_props = deployment.properties + logger.debug(f"Deployed: {deployment.name} {deployment.id} {depl_props}") + + if depl_props.provisioning_state != "Succeeded": + logger.error(f"Failed to provision: {depl_props}") + raise RuntimeError( + "Deploy of template to resource group" + f" {resource_group} proceeded but the provisioning" + f" state returned is {depl_props.provisioning_state}." + "\nAborting" + ) + logger.debug(f"Provisioning state of deployment {resource_group} : {depl_props.provisioning_state}") + + return depl_props.outputs diff --git a/src/acrcssc/azext_acrcssc/helper/_ociartifactoperations.py b/src/acrcssc/azext_acrcssc/helper/_ociartifactoperations.py new file mode 100644 index 00000000000..794d88a191c --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/_ociartifactoperations.py @@ -0,0 +1,240 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +"""A module to handle ORAS calls to the registry.""" +# pylint: disable=line-too-long +# pylint: disable=logging-fstring-interpolation +import os +import dataclasses +import shutil +import subprocess +import json + +from oras.client import OrasClient +from azure.cli.core.azclierror import AzCLIError, InvalidArgumentValueError +from azure.cli.command_modules.acr.repository import acr_repository_delete +from azure.mgmt.core.tools import parse_resource_id +from jsonschema import validate +from jsonschema.exceptions import ValidationError +from knack.log import get_logger +from tempfile import NamedTemporaryFile +from ._constants import ( + BEARER_TOKEN_USERNAME, + CONTINUOUSPATCH_CONFIG_SCHEMA_V1, + CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG, + CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1, + CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_DRYRUN, + CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME, + CSSC_WORKFLOW_POLICY_REPOSITORY, + ERROR_MESSAGE_INVALID_JSON_PARSE, + ERROR_MESSAGE_INVALID_JSON_SCHEMA, + SUBSCRIPTION +) +from ._utility import ( + convert_cron_to_schedule, + get_task +) + +logger = get_logger(__name__) + + +def create_oci_artifact_continuous_patch(registry, cssc_config_file, dryrun): + logger.debug(f"Entering create_oci_artifact_continuouspatching with parameters: {registry.name} {cssc_config_file} {dryrun}") + + oras_client = None + try: + oras_client = _oras_client(registry) + + # the ORAS client can only work with files under the current directory + with NamedTemporaryFile( + prefix="cssc_config_tmp_", + mode="w+b", + dir=os.getcwd(), + delete=False + ) as temp_artifact, open(cssc_config_file, "rb") as user_artifact: + shutil.copyfileobj(user_artifact, temp_artifact) + temp_artifact.flush() # Ensure all data is written to disk + temp_artifact_name = temp_artifact.name + + if dryrun: + oci_target_name = f"{CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG}:{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_DRYRUN}" + else: + oci_target_name = f"{CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG}:{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1}" + + logger.debug(f"Publish OCI artifact to: {oci_target_name}") + oras_client.push( + target=oci_target_name, + files=[temp_artifact_name]) + except Exception as exception: + raise AzCLIError(f"Failed to push OCI artifact to ACR: {exception}") + finally: + if oras_client: + oras_client.logout(hostname=str.lower(registry.login_server)) + + +def get_oci_artifact_continuous_patch(cmd, registry): + logger.debug("Entering get_oci_artifact_continuous_patch with parameter: %s", registry.login_server) + config = None + file_name = None + oras_client = None + try: + oras_client = _oras_client(registry) + + oci_target_name = f"{CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG}:{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1}" + + logger.debug(f"Pull OCI artifact from: {oci_target_name}") + oci_artifacts = oras_client.pull(target=oci_target_name, + overwrite=True) + + if not oci_artifacts: + raise AzCLIError(f"Failed to pull OCI artifact from ACR: {oci_target_name}") + + trigger_task = get_task(cmd, registry, CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME) + file_name = oci_artifacts[0] + logger.debug(f"OCI artifact file name: {file_name}, trigger task: {trigger_task}") + config = ContinuousPatchConfig().from_file(file_name, trigger_task) + except Exception as exception: + raise AzCLIError(f"Failed to get OCI artifact from ACR: {exception}") + finally: + if oras_client: + oras_client.logout(hostname=str.lower(registry.login_server)) + + return config, file_name + + +def delete_oci_artifact_continuous_patch(cmd, registry): + logger.debug(f"Entering delete_oci_artifact_continuous_patch with parameters {registry}") + resourceid = parse_resource_id(registry.id) + subscription = resourceid[SUBSCRIPTION] + + try: + token = _get_acr_token(registry.name, subscription) + oci_target_name = f"{CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG}" + # Delete repository, removing only image isn't deleting the repository always (Bug) + acr_repository_delete( + cmd=cmd, + registry_name=registry.name, + repository=oci_target_name, + username=BEARER_TOKEN_USERNAME, + password=token, + yes=True) + logger.debug("Call to acr_repository_delete completed successfully") + except Exception as exception: + logger.debug(exception) + logger.error(f"{oci_target_name}:{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1} might not exist or attempt to delete failed.") + raise + + +def _oras_client(registry): + resourceid = parse_resource_id(registry.id) + subscription = resourceid[SUBSCRIPTION] + + try: + token = _get_acr_token(registry.name, subscription) + client = OrasClient(hostname=str.lower(registry.login_server), auth_backend="token") + client.login(BEARER_TOKEN_USERNAME, token) + logger.debug(f"Login to ACR {registry.name} completed successfully.") + except Exception as exception: + raise AzCLIError(f"Failed to login to Artifact Store ACR {registry.name}: {exception}") + + return client + + +def _get_acr_token(registry_name, subscription): + logger.debug(f"Using CLI user credentials to log into {registry_name}") + acr_login_with_token_cmd = [ + str(shutil.which("az")), + "acr", "login", + "--name", registry_name, + "--subscription", subscription, + "--expose-token", + "--output", "tsv", + "--query", "accessToken", + ] + + try: + result = subprocess.run( + acr_login_with_token_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, # Ensures output is returned as a string + check=True # Raises CalledProcessError for non-zero exit codes + ) + token = result.stdout.strip() + if not token or token == "": + raise AzCLIError("Failed to retrieve ACR token. The token is empty.") + return token + except subprocess.CalledProcessError as error: + stderr = error.stderr.strip() + logger.debug(f"Error while retrieving ACR token: {stderr}") + unauthorized = "401" in stderr or "unauthorized" in stderr.lower() + + if unauthorized: + # As we shell out the the subprocess, I think checking for these + # strings is the best check we can do for permission failures. + raise AzCLIError( + " Failed to login to Artifact Store ACR.\n" + " It looks like you do not have permissions. You need to have" + " the AcrPush role over the" + " registry in order to be able to upload to the new" + " artifact store." + ) from error + + raise AzCLIError(f"Failed to retrieve ACR token: {stderr}") from error + + +class ContinuousPatchConfig: + def __init__(self): + self.version = "" + self.repositories = [] + self.schedule = None + + def from_file(self, file_path, trigger_task=None): + with open(file_path, "r") as file: + return self.from_json(file.read(), trigger_task) + + def from_json(self, json_str, trigger_task=None): + try: + json_config = json.loads(json_str) + validate(json_config, CONTINUOUSPATCH_CONFIG_SCHEMA_V1) + except json.JSONDecodeError as e: + raise AzCLIError(ERROR_MESSAGE_INVALID_JSON_PARSE) from e + except ValidationError as e: + logger.error(f"Error validating the continuous patch config file: {e}") + raise AzCLIError(ERROR_MESSAGE_INVALID_JSON_SCHEMA) from e + except Exception as e: + logger.error(f"Error validating the continuous patch config file: {e}") + if json_str: + logger.debug(f"Config file content: {json_str}") + raise InvalidArgumentValueError(ERROR_MESSAGE_INVALID_JSON_PARSE) from e + + self.version = json_config.get("version", "") + repositories = json_config.get("repositories", []) + for repo in repositories: + enabled = repo.get("enabled", True) # optional field, default to True + repository = Repository(repo["repository"], repo["tags"], enabled) + self.repositories.append(repository) + + if trigger_task: + trigger = trigger_task.trigger + if trigger and trigger.timer_triggers: + self.schedule = convert_cron_to_schedule(trigger.timer_triggers[0].schedule, just_days=True) + + return self + + def get_enabled_images(self): + enabled_images = [] + for repository in self.repositories: + if repository.enabled: + for tag in repository.tags: + image = f"{repository.repository}:{tag}" + enabled_images.append(image) + return enabled_images + + +@dataclasses.dataclass +class Repository: + repository: str + tags: list[str] + enabled: bool diff --git a/src/acrcssc/azext_acrcssc/helper/_taskoperations.py b/src/acrcssc/azext_acrcssc/helper/_taskoperations.py new file mode 100644 index 00000000000..e8f93e068e4 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/_taskoperations.py @@ -0,0 +1,542 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +# pylint: disable=line-too-long +# pylint: disable=broad-exception-caught +# pylint: disable=logging-fstring-interpolation +import base64 +import os +import tempfile +import time +import logging +from knack.log import get_logger +from knack.util import CLIError +from ._constants import ( + CONTINUOUSPATCH_DEPLOYMENT_NAME, + CONTINUOUSPATCH_DEPLOYMENT_TEMPLATE, + CONTINUOUSPATCH_ALL_TASK_NAMES, + CONTINUOUSPATCH_TASK_DEFINITION, + CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME, + RESOURCE_GROUP, + CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG, + CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1, + TMP_DRY_RUN_FILE_NAME, + CONTINUOUS_PATCHING_WORKFLOW_NAME, + ERROR_MESSAGE_WORKFLOW_TASKS_DOES_NOT_EXIST, + ERROR_MESSAGE_WORKFLOW_TASKS_ALREADY_EXISTS, + CSSC_WORKFLOW_POLICY_REPOSITORY, + CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME, + CONTINUOUSPATCH_TASK_SCANIMAGE_NAME, + DESCRIPTION, + WORKFLOW_VALIDATION_MESSAGE, + TaskRunStatus) +from azure.cli.core.azclierror import AzCLIError, InvalidArgumentValueError, ResourceNotFoundError +from azure.cli.core.commands import LongRunningOperation +from azure.cli.core.commands.progress import IndeterminateProgressBar +from azure.cli.command_modules.acr._utils import prepare_source_location +from azure.cli.command_modules.acr._archive_utils import logger as acr_archive_utils_logger +from azure.core.exceptions import HttpResponseError +from azure.mgmt.core.tools import parse_resource_id +from azext_acrcssc._client_factory import cf_acr_tasks, cf_authorization, cf_acr_registries_tasks, cf_acr_runs +from azext_acrcssc.helper._deployment import validate_and_deploy_template +from azext_acrcssc._validators import check_continuous_task_exists, check_continuous_task_config_exists +from datetime import datetime, timezone, timedelta +from ._utility import convert_timespan_to_cron, convert_cron_to_schedule, create_temporary_dry_run_file, delete_temporary_dry_run_file +from azext_acrcssc.helper._ociartifactoperations import create_oci_artifact_continuous_patch, get_oci_artifact_continuous_patch, delete_oci_artifact_continuous_patch +from ._workflow_status import WorkflowTaskStatus + +logger = get_logger(__name__) + + +def create_update_continuous_patch_v1(cmd, + registry, + cssc_config_file, + schedule, + dryrun, + run_immediately, + is_create_workflow=True): + + logger.debug(f"Entering continuousPatchV1_creation {cssc_config_file} {dryrun} {run_immediately}") + + resource_group = parse_resource_id(registry.id)[RESOURCE_GROUP] + schedule_cron_expression = None + cssc_tasks_exists, task_list = check_continuous_task_exists(cmd, registry) + + if schedule: + schedule_cron_expression = convert_timespan_to_cron(schedule) + logger.debug(f"converted schedule {schedule} to cron expression: {schedule_cron_expression}") + + if is_create_workflow: + if cssc_tasks_exists: + raise AzCLIError(f"{ERROR_MESSAGE_WORKFLOW_TASKS_ALREADY_EXISTS}") + + create_oci_artifact_continuous_patch(registry, cssc_config_file, dryrun) + logger.debug(f"Uploading of {cssc_config_file} for create completed successfully.") + + _create_cssc_workflow(cmd, registry, schedule_cron_expression, resource_group, dryrun) + else: + if not cssc_tasks_exists: + raise AzCLIError(f"{ERROR_MESSAGE_WORKFLOW_TASKS_DOES_NOT_EXIST}") + + if cssc_config_file: + create_oci_artifact_continuous_patch(registry, cssc_config_file, dryrun) + logger.debug(f"Uploading of {cssc_config_file} for update completed successfully.") + + _update_cssc_workflow(cmd, registry, schedule_cron_expression, resource_group, dryrun, task_list) + + # on 'update' schedule is optional + if schedule is None: + trigger_task = next(task for task in task_list if task.name == CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME) + trigger = trigger_task.trigger + if trigger and trigger.timer_triggers: + schedule_cron_expression = trigger.timer_triggers[0].schedule + + _eval_trigger_run(cmd, registry, resource_group, run_immediately) + next_date = get_next_date(schedule_cron_expression) + print(f"Continuous Patching workflow scheduled to run next at: {next_date} UTC") + + +def _create_cssc_workflow(cmd, registry, schedule_cron_expression, resource_group, dry_run, silent_execution=False): + parameters = { + "AcrName": {"value": registry.name}, + "AcrLocation": {"value": registry.location}, + "taskSchedule": {"value": schedule_cron_expression} + } + + for task in CONTINUOUSPATCH_TASK_DEFINITION: + encoded_task = {"value": _create_encoded_task(CONTINUOUSPATCH_TASK_DEFINITION[task]["template_file"])} + param_name = CONTINUOUSPATCH_TASK_DEFINITION[task]["parameter_name"] + parameters[param_name] = encoded_task + + validate_and_deploy_template( + cmd.cli_ctx, + registry, + resource_group, + CONTINUOUSPATCH_DEPLOYMENT_NAME, + CONTINUOUSPATCH_DEPLOYMENT_TEMPLATE, + parameters, + dry_run + ) + + if not silent_execution: + print(f"Deployment of {CONTINUOUS_PATCHING_WORKFLOW_NAME} tasks completed successfully.") + + +def _update_cssc_workflow(cmd, registry, schedule_cron_expression, resource_group, dry_run, task_list): + # compare the task definition to the existing tasks, if there is a difference, we need to update the tasks + # if we need to update the tasks, we will update the cron expression from it + # if not we just update the cron expression from the given parameter + acr_task_client = cf_acr_tasks(cmd.cli_ctx) + for task in task_list: + deployed_task = task.step.encoded_task_content + extension_task = _create_encoded_task(CONTINUOUSPATCH_TASK_DEFINITION[task.name]["template_file"]) + if deployed_task != extension_task: + logger.debug(f"Task {task.name} is different from the extension task, updating the task") + _update_task_yaml(acr_task_client, registry, resource_group, task, extension_task) + + if schedule_cron_expression: + _update_task_schedule(acr_task_client, registry, resource_group, schedule_cron_expression, dry_run) + + +def _eval_trigger_run(cmd, registry, resource_group, run_immediately): + if run_immediately: + logger.warning(f'Triggering the {CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME} to run immediately') + # Seen Managed Identity taking time, see if there can be an alternative (one alternative is to schedule the cron expression with delay) + # NEED TO SKIP THE TIME.SLEEP IN UNIT TEST CASE OR FIND AN ALTERNATIVE SOLUITION TO MI COMPLETE + time.sleep(30) + _trigger_task_run(cmd, registry, resource_group, CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME) + + +def delete_continuous_patch_v1(cmd, registry, yes): + logger.debug("Entering delete_continuous_patch_v1") + cssc_tasks_exists, cssc_task_list = check_continuous_task_exists(cmd, registry) + task_list_names = [task.name for task in cssc_task_list] + cssc_config_exists = check_continuous_task_config_exists(cmd, registry) + + acr_run_client = cf_acr_runs(cmd.cli_ctx) + resource_group_name = parse_resource_id(registry.id)[RESOURCE_GROUP] + running_tasks = WorkflowTaskStatus.get_taskruns_with_filter( + acr_run_client, + registry_name=registry.name, + resource_group_name=resource_group_name, + status_filter=[TaskRunStatus.Running.value, TaskRunStatus.Queued.value, TaskRunStatus.Started.value], + taskname_filter=[CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME, CONTINUOUSPATCH_TASK_SCANIMAGE_NAME, CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME]) + if running_tasks: + from knack.prompting import prompt_y_n + if yes or prompt_y_n("There are currently running tasks for this workflow. Do you want to cancel their execution?"): + _cancel_task_runs(acr_run_client, registry.name, resource_group_name, running_tasks) + + if cssc_tasks_exists: + cssc_tasks = ', '.join(task_list_names) + logger.warning(f"All of these tasks will be deleted: {cssc_tasks}") + else: + logger.warning(f"{ERROR_MESSAGE_WORKFLOW_TASKS_DOES_NOT_EXIST}") + if task_list_names: + logger.warning("An attempt will be made to delete any dangling workflow tasks and the configuration file.") + + for taskname in task_list_names: + _delete_task(cmd, registry, taskname) + logger.warning(f"Task {taskname} deleted.") + + if cssc_config_exists: + logger.warning(f"Deleting {CSSC_WORKFLOW_POLICY_REPOSITORY}/{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG}:{CONTINUOUSPATCH_OCI_ARTIFACT_CONFIG_TAG_V1}") + delete_oci_artifact_continuous_patch(cmd, registry) + + +def list_continuous_patch_v1(cmd, registry): + logger.debug("Entering list_continuous_patch_v1") + cssc_tasks_exists, task_list = check_continuous_task_exists(cmd, registry) + if not cssc_tasks_exists: + logger.error(f"{ERROR_MESSAGE_WORKFLOW_TASKS_DOES_NOT_EXIST}") + return + + filtered_cssc_tasks = _transform_task_list(task_list) + return filtered_cssc_tasks + + +def acr_cssc_dry_run(cmd, registry, config_file_path, is_create=True, remove_internal_statements=True): + logger.debug(f"Entering acr_cssc_dry_run with parameters: {registry} {config_file_path}") + cssc_tasks_exists, _ = check_continuous_task_exists(cmd, registry) + + if is_create and cssc_tasks_exists: + raise AzCLIError(f"{ERROR_MESSAGE_WORKFLOW_TASKS_ALREADY_EXISTS}") + + if config_file_path is None: + if not cssc_tasks_exists: + raise InvalidArgumentValueError("--config parameter is needed to perform dry-run check.") + + # attempt to get the config file from the registry, since the configuration should exist + logger.debug("Retrieving the configuration file from the registry.") + _, config_file_path = get_oci_artifact_continuous_patch(cmd, registry) + if config_file_path is None: + raise AzCLIError("Failed to retrieve the configuration file from the registry.") + + file_name = None + tmp_folder = None + acr_archive_utils_logger_level = acr_archive_utils_logger.getEffectiveLevel() + try: + file_name = os.path.basename(config_file_path) + tmp_folder = os.path.join(os.getcwd(), tempfile.mkdtemp(prefix="cli_temp_cssc")) + create_temporary_dry_run_file(config_file_path, tmp_folder) + + resource_group_name = parse_resource_id(registry.id)[RESOURCE_GROUP] + acr_registries_task_client = cf_acr_registries_tasks(cmd.cli_ctx) + acr_run_client = cf_acr_runs(cmd.cli_ctx) + + # This removes the internal logging from the acr module, reenables it after the setup is completed. + # Because it is an external logger, the only way to control the output is by changing the level + try: + if remove_internal_statements: + acr_archive_utils_logger.setLevel(logging.ERROR) + + source_location = prepare_source_location( + cmd, + tmp_folder, + acr_registries_task_client, + registry.name, + resource_group_name) + + except CLIError as cli_error: + raise AzCLIError(f"Failed to prepare source to trigger ACR task: {cli_error}") + finally: + if remove_internal_statements: + acr_archive_utils_logger.setLevel(acr_archive_utils_logger_level) + + OS = acr_run_client.models.OS + Architecture = acr_run_client.models.Architecture + + # TODO: when the extension merges back into the acr module, we need to reuse the 'get_validate_platform()' from ACR modules (src\azure-cli\azure\cli\command_modules\acr\_utils.py) + platform_os = OS.linux.value + platform_arch = Architecture.amd64.value + platform_variant = None + + value_pair = [{"name": "CONFIGPATH", "value": f"{file_name}"}] + request = acr_registries_task_client.models.FileTaskRunRequest( + task_file_path=TMP_DRY_RUN_FILE_NAME, + values_file_path=None, + values=value_pair, + source_location=source_location, + timeout=None, + platform=acr_registries_task_client.models.PlatformProperties( + os=platform_os, + architecture=platform_arch, + variant=platform_variant + ), + credentials=_get_custom_registry_credentials(cmd), + agent_pool_name=None, + log_template=None + ) + queued = LongRunningOperation(cmd.cli_ctx, start_msg=WORKFLOW_VALIDATION_MESSAGE)(acr_registries_task_client.begin_schedule_run( + resource_group_name=resource_group_name, + registry_name=registry.name, + run_request=request)) + run_id = queued.run_id + logger.info("Performing dry-run check for filter policy using acr task run id: %s", run_id) + return WorkflowTaskStatus.remove_internal_acr_statements( + WorkflowTaskStatus.generate_logs( + cmd, + acr_run_client, + run_id, + registry.name, + resource_group_name, + await_task_run=True, + await_task_message=WORKFLOW_VALIDATION_MESSAGE)) + finally: + delete_temporary_dry_run_file(tmp_folder) + + +def cancel_continuous_patch_runs(cmd, resource_group_name, registry_name): + logger.debug("Entering cancel_continuous_patch_v1") + acr_task_run_client = cf_acr_runs(cmd.cli_ctx) + running_tasks = WorkflowTaskStatus.get_taskruns_with_filter( + acr_task_run_client, + registry_name=registry_name, + resource_group_name=resource_group_name, + status_filter=[TaskRunStatus.Running.value, TaskRunStatus.Queued.value, TaskRunStatus.Started.value], + taskname_filter=[CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME, CONTINUOUSPATCH_TASK_SCANIMAGE_NAME, CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME]) + + _cancel_task_runs(acr_task_run_client, registry_name, resource_group_name, running_tasks) + logger.warning("All active running workflow tasks have been cancelled.") + + +def _cancel_task_runs(acr_task_run_client, registry_name, resource_group_name, running_tasks): + for task in running_tasks: + try: + logger.warning("Sending request to cancel task %s", task.name) + logger.debug("Cancel Task run, name %s run id: %s", task.name, task.run_id) + acr_task_run_client.begin_cancel(resource_group_name, registry_name, task.name) + except Exception as exception: + logger.error(f"Failed to cancel task {task.name} from registry {registry_name}: {exception}") + + +def track_scan_progress(cmd, resource_group_name, registry, status=None): + logger.debug("Entering track_scan_progress") + + cssc_tasks_exists, _ = check_continuous_task_exists(cmd, registry) + if not cssc_tasks_exists: + logger.warning(f"{ERROR_MESSAGE_WORKFLOW_TASKS_DOES_NOT_EXIST}") + return + + config, _ = get_oci_artifact_continuous_patch(cmd, registry) + + image_status = _retrieve_logs_for_image(cmd, registry, resource_group_name, config.schedule, status) + print(f"Listing images that have been scanned and/or patched in the last {config.schedule} days") + print(f"Total images: {len(image_status) if image_status else 0}") + return image_status + + +def _retrieve_logs_for_image(cmd, registry, resource_group_name, schedule, workflow_status=None): + image_status = [] + acr_task_run_client = cf_acr_runs(cmd.cli_ctx) + + # get all the tasks executed since the last schedule, add a day to make sure we are not running into and edge case with the date + today = datetime.now(timezone.utc) + # delta = datetime.timedelta(days=int(schedule) + 1) + delta = timedelta(days=int(schedule)) # use the schedule as is, we are running into issues we are querying too much and take time to filter + previous_date = today - delta + previous_date_filter = previous_date.strftime('%Y-%m-%dT%H:%M:%SZ') + + # th API returns an iterator, if we want to be able to modify it, we need to convert it to a list + scan_taskruns = WorkflowTaskStatus.get_taskruns_with_filter( + acr_task_run_client, + registry.name, + resource_group_name, + taskname_filter=[CONTINUOUSPATCH_TASK_SCANIMAGE_NAME], + date_filter=previous_date_filter) + + patch_taskruns = WorkflowTaskStatus.get_taskruns_with_filter( + acr_task_run_client, + registry.name, + resource_group_name, + taskname_filter=[CONTINUOUSPATCH_TASK_PATCHIMAGE_NAME], + date_filter=previous_date_filter) + + start_time = time.time() + + progress_indicator = IndeterminateProgressBar(cmd.cli_ctx, message="Retrieving logs for images") + progress_indicator.begin() + + image_status = WorkflowTaskStatus.from_taskrun(cmd, + acr_task_run_client, + registry, + scan_taskruns, + patch_taskruns, + progress_indicator=progress_indicator, + workflow_status_filter=workflow_status) + + end_time = time.time() + execution_time = end_time - start_time + logger.debug(f"Execution time: {execution_time} seconds / tasks filtered: {len(scan_taskruns)} + {len(patch_taskruns)}") + + progress_indicator.end() + + return image_status + + +def _trigger_task_run(cmd, registry, resource_group, task_name): + acr_task_registries_client = cf_acr_registries_tasks(cmd.cli_ctx) + request = acr_task_registries_client.models.TaskRunRequest( + task_id=f"{registry.id}/tasks/{task_name}") + queued_run = LongRunningOperation(cmd.cli_ctx)( + acr_task_registries_client.begin_schedule_run( + resource_group, + registry.name, + request)) + run_id = queued_run.run_id + print(f"Queued {CONTINUOUS_PATCHING_WORKFLOW_NAME} workflow task '{task_name}' with run ID: {run_id}. Use 'az acr task logs --registry {registry.name} --run-id {run_id}' to view the logs.") + + +def _create_encoded_task(task_file): + # this is a bit of a hack, but we need to fix the path to the task's yaml, + # relative paths don't work because we don't control where the az cli is running from + templates_path = os.path.dirname( + os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "../templates/")) + + with open(os.path.join(templates_path, task_file), "rb") as f: + base64_content = base64.b64encode(f.read()) + return base64_content.decode('utf-8') + + +def _update_task_yaml(acr_task_client, registry, resource_group_name, task, encoded_task): + logger.debug("Entering update_task_yaml for task %s", task.name) + try: + taskUpdateParameters = acr_task_client.models.TaskUpdateParameters( + step=acr_task_client.models.EncodedTaskStepUpdateParameters( + encoded_task_content=encoded_task)) + + acr_task_client.begin_update(resource_group_name, + registry.name, + task.name, + taskUpdateParameters) + + logger.debug(f"Task {task.name} updated successfully") + except HttpResponseError as exception: + logger.warning(f"Failed to update task {task.name} in registry {registry.name}: {exception}") + + +def _update_task_schedule(acr_task_client, registry, resource_group_name, cron_expression, dryrun): + logger.debug(f"Using cron_expression: {cron_expression}") + taskUpdateParameters = acr_task_client.models.TaskUpdateParameters( + trigger=acr_task_client.models.TriggerUpdateParameters( + timer_triggers=[ + acr_task_client.models.TimerTriggerUpdateParameters( + name='azcli_defined_schedule', + schedule=cron_expression) + ])) + + if dryrun: + logger.debug("Dry run, skipping the update of the task schedule") + return + try: + acr_task_client.begin_update(resource_group_name, + registry.name, + CONTINUOUSPATCH_TASK_SCANREGISTRY_NAME, + taskUpdateParameters) + print("Schedule has been successfully updated.") + except HttpResponseError as exception: + raise AzCLIError(f"Failed to update the task schedule: {exception}") + + +def _delete_task(cmd, registry, task_name): + logger.debug("Entering delete_task") + resource_group = parse_resource_id(registry.id)[RESOURCE_GROUP] + + try: + acr_tasks_client = cf_acr_tasks(cmd.cli_ctx) + _delete_task_role_assignment(cmd.cli_ctx, acr_tasks_client, registry, resource_group, task_name) + + logger.debug(f"Deleting task {task_name}") + LongRunningOperation(cmd.cli_ctx)( + acr_tasks_client.begin_delete( + resource_group, + registry.name, + task_name)) + logger.debug(f"Task {task_name} deleted successfully") + + except AzCLIError as exception: + logger.error(f"Failed to delete task {task_name} from registry {registry.name} : {exception}") + + +def _delete_task_role_assignment(cli_ctx, acrtask_client, registry, resource_group, task_name): + role_client = cf_authorization(cli_ctx) + + try: + task = acrtask_client.get(resource_group, registry.name, task_name) + except ResourceNotFoundError: + logger.debug(f"Task {task_name} does not exist in registry {registry.name}") + logger.debug("Continuing with deletion") + return None + + identity = task.identity + + if not identity or not identity.principal_id: + logger.debug(f"Task {task_name} has no associated managed identity. Skipping role assignment deletion.") + return None + + try: + assigned_roles = role_client.role_assignments.list_for_scope( + registry.id, + filter=f"principalId eq '{identity.principal_id}'" + ) + except ResourceNotFoundError: + logger.debug(f"Role assignments for principal ID {identity.principal_id} do not exist in registry {registry.name}") + return None + + for role in assigned_roles: + try: + logger.debug(f"Deleting role assignments of task {task_name} from the registry") + role_client.role_assignments.delete( + scope=registry.id, + role_assignment_name=role.name + ) + except ResourceNotFoundError: + logger.debug(f"Role assignment {role.name} does not exist in registry {registry.name}") + except AzCLIError as exception: + logger.error(f"Failed to delete role assignment {role.name} from registry {registry.name} : {exception}") + + +def _transform_task_list(tasks): + transformed = [] + for task in tasks: + if task.name not in CONTINUOUSPATCH_ALL_TASK_NAMES: + continue + + transformed_obj = { + "creationDate": task.creation_date, + "location": task.location, + "name": task.name, + "provisioningState": task.provisioning_state, + "systemData": task.system_data, + "schedule": None, + "description": CONTINUOUSPATCH_TASK_DEFINITION[task.name][DESCRIPTION] + } + + trigger = task.trigger + if trigger and trigger.timer_triggers: + # convert the cron expression to a 'days' format to keep consistent with the command's options + transformed_obj["schedule"] = convert_cron_to_schedule(trigger.timer_triggers[0].schedule) + + # add a 'nextOccurrence' field to the task, only for the scheduling task + transformed_obj["nextOccurrence"] = get_next_date(task.trigger.timer_triggers[0].schedule) + transformed.append(transformed_obj) + + return transformed + + +def _get_custom_registry_credentials(cmd): + acr_tasks_client = cf_acr_tasks(cmd.cli_ctx) + return acr_tasks_client.models.Credentials( + source_registry=None, + custom_registries=None + ) + + +def get_next_date(cron_expression): + from croniter import croniter + now = datetime.now(timezone.utc) + cron = croniter(cron_expression, now, expand_from_start_time=False) + next_date = cron.get_next(datetime) + return str(next_date) diff --git a/src/acrcssc/azext_acrcssc/helper/_utility.py b/src/acrcssc/azext_acrcssc/helper/_utility.py new file mode 100644 index 00000000000..04b0f8ff0e5 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/_utility.py @@ -0,0 +1,108 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import os +import re +from knack.log import get_logger +from datetime import (datetime, timezone) +import shutil +from azure.cli.core.azclierror import AzCLIError, InvalidArgumentValueError, ResourceNotFoundError +from azure.mgmt.core.tools import parse_resource_id +from ._constants import ( + CONTINUOUSPATCH_SCHEDULE_MIN_DAYS, + CONTINUOUSPATCH_SCHEDULE_MAX_DAYS, + ERROR_MESSAGE_INVALID_TIMESPAN_VALUE, + RESOURCE_GROUP, + TMP_DRY_RUN_FILE_NAME, + RECOMMENDATION_SCHEDULE) +from .._client_factory import cf_acr_tasks + +logger = get_logger(__name__) +# pylint: disable=logging-fstring-interpolation + + +def convert_timespan_to_cron(schedule, date_time=None): + # Regex to look for pattern 1d, 2d, 3d, etc. + match = re.match(r'(\d+)(d)$', schedule) + if match is None: + raise InvalidArgumentValueError(error_msg=ERROR_MESSAGE_INVALID_TIMESPAN_VALUE, + recommendation=RECOMMENDATION_SCHEDULE) + + value = int(match.group(1)) + unit = match.group(2) + + if date_time is None: + date_time = datetime.now(timezone.utc) + + cron_hour = date_time.hour + cron_minute = date_time.minute + cron_expression = "" + + if unit == 'd': # day of the month + if value < CONTINUOUSPATCH_SCHEDULE_MIN_DAYS or value > CONTINUOUSPATCH_SCHEDULE_MAX_DAYS: + raise InvalidArgumentValueError(error_msg=ERROR_MESSAGE_INVALID_TIMESPAN_VALUE, + recommendation=RECOMMENDATION_SCHEDULE) + cron_expression = f'{cron_minute} {cron_hour} */{value} * *' + + return cron_expression + + +def convert_cron_to_schedule(cron_expression, just_days=False): + try: + parts = cron_expression.split() + # The third part of the cron expression for 'day of the month' + third_part = parts[2] + + match = re.search(r'^\*/(\d+)$', third_part) + + if match: + if just_days: + return match.group(1) + return match.group(1) + 'd' + + return None + except IndexError: + return None + + +def create_temporary_dry_run_file(file_location, tmp_folder): + templates_path = os.path.abspath(os.path.join( + os.path.dirname(__file__), + "../templates")) + logger.debug(f"templates_path: {templates_path}") + + try: + os.makedirs(tmp_folder, exist_ok=True) + file_template_copy = os.path.join(templates_path, TMP_DRY_RUN_FILE_NAME) + + if not os.path.exists(file_template_copy): + raise AzCLIError(f"Template file {file_template_copy} does not exist") + + shutil.copy2(file_template_copy, tmp_folder) + shutil.copy2(file_location, tmp_folder) + folder_contents = os.listdir(tmp_folder) + logger.debug(f"Copied dry run file {folder_contents}") + except Exception as exception: + raise AzCLIError(f"Failed to copy dry run file: {exception}") + + +def delete_temporary_dry_run_file(tmp_folder): + if tmp_folder is None or not os.path.exists(tmp_folder): + return + logger.debug(f"Deleting contents and directory {tmp_folder}") + shutil.rmtree(tmp_folder) + + +def get_task(cmd, registry, task_name, task_client=None): + if task_client is None: + task_client = cf_acr_tasks(cmd.cli_ctx) + + resourceid = parse_resource_id(registry.id) + resource_group = resourceid[RESOURCE_GROUP] + + try: + return task_client.get(resource_group, registry.name, task_name) + except ResourceNotFoundError as exception: + logger.debug("Failed to find task %s from registry %s : %s", task_name, registry.name, exception) + return None diff --git a/src/acrcssc/azext_acrcssc/helper/_workflow_status.py b/src/acrcssc/azext_acrcssc/helper/_workflow_status.py new file mode 100644 index 00000000000..64c27914035 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/helper/_workflow_status.py @@ -0,0 +1,604 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# want it to be something where we can store the status of a image processed by the workflow +# contain both the image, scanning status and patching status + +import time +import re +from ._constants import ( + RESOURCE_GROUP, + CSSCTaskTypes, + TaskRunStatus, + WORKFLOW_STATUS_NOT_AVAILABLE, + WORKFLOW_STATUS_PATCH_NOT_AVAILABLE +) +from azure.cli.core.commands import LongRunningOperation +from azure.cli.core.commands.progress import IndeterminateProgressBar +from azure.cli.core.profiles import ResourceType, get_sdk +from azure.cli.core.azclierror import AzCLIError, ResourceNotFoundError +from azure.core.polling import PollingMethod +from azure.mgmt.core.tools import parse_resource_id +from knack.log import get_logger +from enum import Enum +from msrestazure.azure_exceptions import CloudError + + +logger = get_logger(__name__) + + +class WorkflowTaskState(Enum): + RUNNING = "Running" + SUCCEEDED = "Succeeded" + FAILED = "Failed" + QUEUED = "Queued" + SKIPPED = "Skipped" + CANCELED = "Canceled" + UNKNOWN = "Unknown" + + +class WorkflowTaskStatus: + def __init__(self, image): + repo = image.split(':') + # string to represent the repository + self.repository = repo[0] + + # string to represent the tag + self.tag = repo[1] + + # latest taskrun object for the scan task. If none, means no scan task has been run + self.scan_task = None + + # not sure if we should be proactive to get the logs for the scan task, but it will also be that we don't + # know that the scan task has been run until we check for logs + self.scan_logs = "" + + # latest taskrun object for the patch task, if none, means no patch task has been run + self.patch_task = None + + # ditto for patch logs, we don't know if the patch task has been run until we check for logs + self.patch_logs = "" + + def image(self): + return f"{self.repository}:{self.tag}" + + # task run status from src\ACR.Build.Contracts\src\Status.cs + @staticmethod + def _task_status_to_workflow_status(task): + if task is None: + return WorkflowTaskState.UNKNOWN.value + + status = task.status.lower() + status_mapping = { + TaskRunStatus.Succeeded.value.lower(): WorkflowTaskState.SUCCEEDED.value, + TaskRunStatus.Running.value.lower(): WorkflowTaskState.RUNNING.value, + TaskRunStatus.Started.value.lower(): WorkflowTaskState.RUNNING.value, + TaskRunStatus.Queued.value.lower(): WorkflowTaskState.QUEUED.value, + TaskRunStatus.Canceled.value.lower(): WorkflowTaskState.CANCELED.value, + TaskRunStatus.Failed.value.lower(): WorkflowTaskState.FAILED.value, + TaskRunStatus.Error.value.lower(): WorkflowTaskState.FAILED.value, + TaskRunStatus.Timeout.value.lower(): WorkflowTaskState.FAILED.value, + } + + return status_mapping.get(status, WorkflowTaskState.UNKNOWN.value) + + @staticmethod + def _workflow_status_to_task_status(status): + status_mapping = { + WorkflowTaskState.SUCCEEDED.value: [TaskRunStatus.Succeeded.value], + WorkflowTaskState.SKIPPED.value: [TaskRunStatus.Succeeded.value], + WorkflowTaskState.RUNNING.value: [TaskRunStatus.Running.value, + TaskRunStatus.Started.value], + WorkflowTaskState.QUEUED.value: [TaskRunStatus.Queued.value], + WorkflowTaskState.CANCELED.value: [TaskRunStatus.Canceled.value], + WorkflowTaskState.FAILED.value: [TaskRunStatus.Failed.value, + TaskRunStatus.Error.value, + TaskRunStatus.Timeout.value], + } + + return status_mapping.get(status, None) + + def scan_status(self): + return WorkflowTaskStatus._task_status_to_workflow_status(self.scan_task) + + def patch_status(self): + # this one is a bit more complicated, because the patch status depends on the scan status + # or more correctly, the patch status is the scan status if there is no patch task + # and the whole workflow status is both the scan and patch status + if self.patch_task is None and self.scan_status() == WorkflowTaskState.SUCCEEDED.value: + return WorkflowTaskState.SKIPPED.value + return WorkflowTaskStatus._task_status_to_workflow_status(self.patch_task) + + def status(self): + if self.patch_task is None: + return self.scan_status() + + return self.patch_status() + + # this extracts the image from the copacetic task logs, using this when we only have a repository + # name and a wildcard tag + @staticmethod + def _get_image_from_tasklog(logs): + match = re.search(r'Scanning repo: (\S+), Tag:\S+, OriginalTag:(\S+)', logs) + if match: + repository = match.group(1) + original_tag = match.group(2) + return f"{repository}:{original_tag}" + + match = re.search(r'Scanning image for vulnerability(?: and patch)? (\S+) for tag (\S+)', logs) + if match: + patched_image = match.group(1) + original_tag = match.group(2) + repository = patched_image.split(':')[0] + return f"{repository}:{original_tag}" + + match = re.search(r'Patching OS vulnerabilities for image (\S+):(\S+)', logs) + if match: + repository = match.group(1) + original_tag = match.group(2) + return f"{repository}:{original_tag}" + return None + + def get_patch_task_from_scan_tasklog(self): + if self.scan_task is None: + return None + + match = re.search(r'WARNING: Queued a run with ID: (\S+)', self.scan_logs) + if match: + return match.group(1) + return None + + def _get_scanning_repo_from_scan_task(self): + if self.scan_task is None: + return None + + if self.patch_status() == WorkflowTaskState.SKIPPED.value or \ + self.patch_status() == WorkflowTaskState.SUCCEEDED.value: + match = re.search( + r'PATCHING task scheduled for image (\S+):(\S+), new patch tag will be (\S+)', + self.scan_logs) + if match: + repository = match.group(1) + original_tag = match.group(2) + patched_tag = match.group(3) + return repository, patched_tag, original_tag + + match = re.search(r'Scanning repo: (\S+), Tag:(\S+), OriginalTag:(\S+)', self.scan_logs) + if match: + repository = match.group(1) + patched_tag = match.group(2) + original_tag = match.group(3) + return repository, patched_tag, original_tag + return None + + def _get_patch_skip_reason_from_tasklog(self): + if self.scan_task is None: + return None + match = re.search(r'PATCHING will be skipped as (.+)\n', self.scan_logs) + if match: + return match.group(1) + return None + + def _get_patch_error_reason_from_tasklog(self): + if self.patch_task is None: + return None + return self._get_errors_from_tasklog(self.patch_logs) + + def _get_scan_error_reason_from_tasklog(self): + if self.scan_task is None: + return None + return self._get_errors_from_tasklog(self.scan_logs) + + def _get_errors_from_tasklog(self, tasklog): + match = re.findall(r'(?i)\b(error\b.*)', tasklog) + # TODO: should we filter out any error? + if match: + # retrieve only unique errors, sort them to make the output deterministic + return str.join("\n", sorted(set(match))) + return None + + def _get_patched_image_name_from_tasklog(self): + if self.scan_task is None: + return None + + repository, patched_tag, _ = self._get_scanning_repo_from_scan_task() + if repository and patched_tag: + return f"{repository}:{patched_tag}" + + if self.patch_task: + match = re.search(r'Patched image pushed to (\S+)', self.patch_logs) + if match: + return match.group(1) + return None + + @staticmethod + def _latest_task(this_task, this_log, that_task, that_log): + if this_task is None: + return that_task, that_log + if that_task is None: + return this_task, this_log + return (this_task, this_log) if this_task.create_time > that_task.create_time else (that_task, that_log) + + @staticmethod + def _retrieve_all_tasklogs(cmd, taskrun_client, registry, taskruns, progress_indicator=None): + import concurrent.futures + resource_group = parse_resource_id(registry.id)[RESOURCE_GROUP] + + def process_taskrun(taskrun): + try: + tasklog = WorkflowTaskStatus.generate_logs(cmd, + taskrun_client, + taskrun.run_id, + registry.name, + resource_group, + await_task_run=False) + if tasklog == "": + logger.debug("Taskrun: %s has no logs, silent failure", taskrun.run_id) + taskrun.task_log_result = tasklog + except ResourceNotFoundError as e: + logger.debug("Failed to get logs for taskrun: %s with exception: %s", taskrun.run_id, e) + except CloudError as e: + logger.debug("An unexpected exception has occurred for taskrun: %s with exception: %s", + taskrun.run_id, e) + + with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: + futures = [] + for taskrun in taskruns: + if progress_indicator: + progress_indicator.update_progress() + + future = executor.submit(process_taskrun, taskrun) + futures.append(future) + + # Wait for all threads to complete + while not all(future.done() for future in futures): + if progress_indicator: + progress_indicator.update_progress() + time.sleep(0.5) + + @staticmethod + def from_taskrun(cmd, + taskrun_client, + registry, + scan_taskruns, + patch_taskruns, + progress_indicator=None, + workflow_status_filter=None): + WorkflowTaskStatus._retrieve_all_tasklogs(cmd, taskrun_client, registry, scan_taskruns, progress_indicator) + all_status = {} + + # we only retrieve logs for scan taskruns in the begining, we will need to retrieved the logs for + # failed patch taskruns to populate patch_error_reason. It will be faster to retrieve in a batch + failed_patch_tasklog_retrieval = [] + + for scan in scan_taskruns: + if progress_indicator: + progress_indicator.update_progress() + if hasattr(progress_indicator, 'hook') and \ + hasattr(progress_indicator.hook, 'active_progress') and \ + hasattr(progress_indicator.hook.active_progress, 'spinner'): + progress_indicator.hook.active_progress.spinner.step(label=progress_indicator.message) + if not hasattr(scan, 'task_log_result'): + logger.debug("Scan Taskrun: %s has no logs, silent failure", scan.run_id) + continue + + image = WorkflowTaskStatus._get_image_from_tasklog(scan.task_log_result) + + if not image: + continue + + # need to check if we have the latest scan task + if image in all_status: + all_status[image].scan_task, all_status[image].scan_logs = WorkflowTaskStatus._latest_task( + all_status[image].scan_task, + all_status[image].scan_logs, + scan, + scan.task_log_result) + else: + all_status[image] = WorkflowTaskStatus(image) + all_status[image].scan_task = scan + all_status[image].scan_logs = scan.task_log_result + + patch_task_id = all_status[image].get_patch_task_from_scan_tasklog() + # missing the patch task id means that the scan either failed, or succeeded and patching is not needed. + # this is important, because patching status depends on both the patching task status (if it exists) + # and the scan task status + if patch_task_id: + # it is possible for the patch task to be mentioned in the logs, but the API has not returned the + # taskrun for it yet, attempt to retrieve it from client + patch_task = next((task for task in patch_taskruns if task.run_id == patch_task_id), None) + if patch_task is None: + patch_task = WorkflowTaskStatus._get_missing_taskrun(taskrun_client, registry, patch_task_id) + + all_status[image].patch_task = patch_task + if patch_task and WorkflowTaskStatus._task_status_to_workflow_status( + patch_task + ) == WorkflowTaskState.FAILED.value: + failed_patch_tasklog_retrieval.append(all_status[image]) + + if failed_patch_tasklog_retrieval: + taskrunList = [task.patch_task for task in failed_patch_tasklog_retrieval if task.patch_task] + WorkflowTaskStatus._retrieve_all_tasklogs(cmd, taskrun_client, registry, taskrunList, progress_indicator) + for workflow_status in failed_patch_tasklog_retrieval: + workflow_status.patch_logs = workflow_status.patch_task.task_log_result + + return [status.get_status() + for status in WorkflowTaskStatus._filter_taskruns(all_status, workflow_status_filter).values()] + + @staticmethod + def _filter_taskruns(workflows, workflow_status_filter=None): + if not workflows: + return {} + + if not workflow_status_filter: + return workflows + + # SKIPPED is a special case, because it means that the patch task does not exist, + # but the scan task succeeded. Another special case that is not explicit here is SUCCEEDED, + # which will include both scan and patch tasks that succeeded, or the scan task succeeded + # and the patch task is skipped + if workflow_status_filter == WorkflowTaskState.SKIPPED.value: + filtered_workflow = {key: workflow + for key, workflow in workflows.items() + if workflow.scan_status() == WorkflowTaskState.SUCCEEDED.value and + workflow.patch_status() == WorkflowTaskState.SKIPPED.value} + return filtered_workflow + + filtered_workflow = { + key: workflow + for key, workflow in workflows.items() + if workflow.status() == workflow_status_filter} + return filtered_workflow + + def get_status(self): + scan_status = self.scan_status() + scan_date = WORKFLOW_STATUS_NOT_AVAILABLE if self.scan_task is None else self.scan_task.create_time + scan_task_id = WORKFLOW_STATUS_NOT_AVAILABLE if self.scan_task is None else self.scan_task.run_id + patch_status = self.patch_status() + patch_date = WORKFLOW_STATUS_NOT_AVAILABLE if self.patch_task is None else self.patch_task.create_time + patch_task_id = WORKFLOW_STATUS_NOT_AVAILABLE if self.patch_task is None else self.patch_task.run_id + patched_image = self._get_patched_image_name_from_tasklog() + workflow_type = CSSCTaskTypes.ContinuousPatchV1.value + # Initialize reasons only if needed + patch_skipped_reason = self._get_patch_skip_reason_from_tasklog() \ + if self.patch_status() == WorkflowTaskState.SKIPPED.value else "" + + scan_error_reason = self._get_scan_error_reason_from_tasklog() \ + if self.scan_status() == WorkflowTaskState.FAILED.value else "" + + patch_error_reason = self._get_patch_error_reason_from_tasklog() \ + if self.patch_status() == WorkflowTaskState.FAILED.value else "" + + if patched_image == self.image(): + patched_image = WORKFLOW_STATUS_PATCH_NOT_AVAILABLE + + result = { + "image": f"{self.repository}:{self.tag}", + "scan_status": scan_status, + "scan_date": scan_date, + "scan_task_ID": scan_task_id, + "patch_status": patch_status, + "patch_date": patch_date, + "patch_task_ID": patch_task_id, + "last_patched_image": patched_image, + "workflow_type": workflow_type + } + + if patch_skipped_reason != "": + result["patch_skipped_reason"] = patch_skipped_reason + + if scan_error_reason != "": + result["scan_error_reason"] = scan_error_reason + + if patch_error_reason != "": + result["patch_error_reason"] = patch_error_reason + + return result + + def __str__(self) -> str: + status = self.get_status() + result = f"image: {status.repository}:{status.tag}\n" \ + f"\tscan status: {status.scan_status}\n" \ + f"\tscan date: {status.scan_date}\n" \ + f"\tscan task ID: {status.scan_task_id}\n" + + if hasattr(status, "scan_error_reason"): + result += f"\tscan error reason: {status.scan_error_reason}\n" + + result += f"\tpatch status: {status.patch_status}\n" + + if hasattr(status, "patch_error_reason"): + result += f"\tpatch error reason: {status.patch_error_reason}\n" + + if hasattr(status, "patch_skipped_reason"): + result += f"\tpatch skipped reason: {status.patch_skipped_reason}\n" + + result += f"\tpatch date: {status.patch_date}\n" \ + f"\tpatch task ID: {status.patch_task_id}\n" \ + f"\tlast patched image: {status.patched_image}\n" \ + f"\tworkflow type: {status.workflow_type}" + + return result + + @staticmethod + def generate_logs(cmd, + client, + run_id, + registry_name, + resource_group_name, + await_task_run=True, + await_task_message=None): + + log_file_sas = None + error_msg = "Could not get logs for ID: {}".format(run_id) + try: + response = client.get_log_sas_url( + resource_group_name=resource_group_name, + registry_name=registry_name, + run_id=run_id) + log_file_sas = response.log_link + except (AttributeError, CloudError) as e: + logger.debug("%s Exception: %s", error_msg, e) + raise AzCLIError(error_msg) + except ResourceNotFoundError as e: + logger.debug("log file not found for run_id: %s, registry: %s, " + "resource_group: %s -- exception: %s", + run_id, registry_name, resource_group_name, e) + return "" + + if await_task_run: + try: + polling_method = WorkflowLogPollingMethod(client, + resource_group_name, + registry_name, + run_id) + result = LongRunningOperation( + cmd.cli_ctx, + progress_bar=IndeterminateProgressBar(cmd.cli_ctx, message=await_task_message), + poller_done_interval_ms=1500 # every poller call will do a call to the API + )(polling_method) + logger.debug("Task result: %s", result) + except TimeoutError: + logger.debug("Timeout waiting for task run to complete, workflow task run ID: %s", run_id) + logger.debug("An attempt to retrieve the logs will be done, if there are any") + + blobClient = get_sdk(cmd.cli_ctx, ResourceType.DATA_STORAGE_BLOB, '_blob_client#BlobClient') + return WorkflowTaskStatus._download_logs(blobClient.from_blob_url(log_file_sas)) + + @staticmethod + def evaluate_task_run_nonterminal_state(run_status): + return run_status != TaskRunStatus.Succeeded.value and run_status != TaskRunStatus.Failed.value + + @staticmethod + def get_run_status_local(client, resource_group_name, registry_name, run_id): + try: + response = client.get(resource_group_name, registry_name, run_id) + return response.status + except (AttributeError, CloudError): + return None + + @staticmethod + def _download_logs(blob_service): + try: + blob = blob_service.download_blob() + blob_text = blob.readall().decode('utf-8') + return blob_text + except AzCLIError as e: + logger.debug("Failed to download logs from blob: %s", e) + return "" + + @staticmethod + def remove_internal_acr_statements(blob_content): + logger.debug("Removing internal ACR statements from logs, blob content size: %s", len(blob_content)) + lines = blob_content.splitlines() + starting_identifier = "DRY RUN mode enabled" + terminating_identifier = "Total matches found" + print_line = False + output = "" + + for line in lines: + if line.strip().startswith(starting_identifier): + print_line = True + elif line.strip().startswith(terminating_identifier): + output += "\n" + line + print_line = False + + if print_line: + output += "\n" + line + + return output + + @staticmethod + def _get_missing_taskrun(taskrun_client, registry, run_id): + try: + resourceid = parse_resource_id(registry.id) + resource_group = resourceid[RESOURCE_GROUP] + runs = WorkflowTaskStatus.get_taskruns_with_filter(taskrun_client, + registry_name=registry.name, + resource_group_name=resource_group, + runId_filter=run_id) + return runs[0] + except ResourceNotFoundError as e: + logger.debug("Failed to find taskrun %s from registry %s: %s", run_id, registry.name, e) + return None + + @staticmethod + def get_taskruns_with_filter(acr_task_run_client, + registry_name, + resource_group_name, + taskname_filter=None, + runId_filter=None, + date_filter=None, + status_filter=None, + top=1000): + # filters based on OData, found in ACR.BuildRP.DataModels - RunFilter.cs + filter_str = "" + if taskname_filter: + taskname_filter_str = "', '".join(taskname_filter) + filter_str += f"TaskName in ('{taskname_filter_str}')" + + if runId_filter: + if filter_str != "": + filter_str += " and " + filter_str += f"runId eq '{runId_filter}'" + + if date_filter: + if filter_str != "": + filter_str += " and " + filter_str += f"createTime ge {date_filter}" + + if status_filter: + if filter_str != "": + filter_str += " and " + status_filter_str = "', '".join(status_filter) + filter_str += f"Status in ('{status_filter_str}')" + + taskruns = acr_task_run_client.list(resource_group_name, registry_name, filter=filter_str, top=top) + return list(taskruns) + + +# this is a polling method that will poll the taskrun status until it is done +# or the timeout is reached. It does not download the logs nor run the task +class WorkflowLogPollingMethod(PollingMethod): + def __init__(self, client, resource_group_name, registry_name, run_id): + self.client = client + self.resource_group_name = resource_group_name + self.registry_name = registry_name + self.run_id = run_id + self.run_status = TaskRunStatus.Running.value + self.start_time = time.time() + self.timeout = 10 * 60 # 10 minutes + + def initialize(self, client, initial_response, deserialization_callback): + pass + + def _timeout(self): + return (time.time() - self.start_time) >= self.timeout + + def run(self): + pass + + def status(self): + return self.run_status + + def finished(self): + if self._timeout(): + raise TimeoutError("Timeout waiting for task run to complete") + + self.run_status = WorkflowTaskStatus.get_run_status_local(self.client, + self.resource_group_name, + self.registry_name, + self.run_id) + + return not WorkflowTaskStatus.evaluate_task_run_nonterminal_state(self.status()) + + def done(self): + return self.finished() + + def result(self): + return self.status() + + def resource(self): + return self.status() diff --git a/src/acrcssc/azext_acrcssc/templates/arm/CSSC-AutoImagePatching-encodedtasks.json b/src/acrcssc/azext_acrcssc/templates/arm/CSSC-AutoImagePatching-encodedtasks.json new file mode 100644 index 00000000000..816b6609efd --- /dev/null +++ b/src/acrcssc/azext_acrcssc/templates/arm/CSSC-AutoImagePatching-encodedtasks.json @@ -0,0 +1,147 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "AcrName": { + "type": "string" + }, + "AcrLocation": { + "type": "string", + "defaultValue": "[resourceGroup().location]" + }, + "taskSchedule": { + "type": "string" + }, + "imagePatchingEncodedTask": { + "type": "string" + }, + "imageScanningEncodedTask": { + "type": "string" + }, + "registryScanningEncodedTask": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", + "name": "[format('{0}/{1}', parameters('AcrName'), 'cssc-patch-image')]", + "location": "[parameters('AcrLocation')]", + "tags": { + "cssc": "true", + "clienttracking": "true" + }, + "properties": { + "platform": { + "os": "linux", + "architecture": "amd64" + }, + "agentConfiguration": { + "cpu": 2 + }, + "timeout": 3600, + "step": { + "type": "EncodedTask", + "encodedTaskContent": "[parameters('imagePatchingEncodedTask')]", + "values": [] + }, + "isSystemTask": false + } + }, + { + "type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", + "name": "[format('{0}/{1}', parameters('AcrName'), 'cssc-scan-image')]", + "location": "[parameters('AcrLocation')]", + "identity": { + "type": "SystemAssigned" + }, + "tags": { + "cssc": "true" + }, + "properties": { + "platform": { + "os": "linux", + "architecture": "amd64" + }, + "agentConfiguration": { + "cpu": 2 + }, + "timeout": 3600, + "step": { + "type": "EncodedTask", + "encodedTaskContent": "[parameters('imageScanningEncodedTask')]", + "values": [] + }, + "isSystemTask": false + } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('AcrName'))]", + "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('AcrName'), 'cssc-scan-image'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb382eab-e894-4461-af04-94435c366c3f'))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb382eab-e894-4461-af04-94435c366c3f')]", + "principalId": "[reference(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('AcrName'), 'cssc-scan-image'), '2019-06-01-preview', 'full').identity.principalId]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('AcrName'), 'cssc-scan-image')]" + ] + }, + { + "type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", + "name": "[format('{0}/{1}', parameters('AcrName'), 'cssc-trigger-workflow')]", + "location": "[parameters('AcrLocation')]", + "identity": { + "type": "SystemAssigned" + }, + "tags": { + "cssc": "true", + "clienttracking": "true" + }, + "properties": { + "platform": { + "os": "linux", + "architecture": "amd64" + }, + "agentConfiguration": { + "cpu": 2 + }, + "timeout": 3600, + "status": "Enabled", + "step": { + "type": "EncodedTask", + "encodedTaskContent": "[parameters('registryScanningEncodedTask')]", + "values": [] + }, + "isSystemTask": false, + "trigger": { + "timerTriggers": [ + { + "name": "azcli_defined_schedule", + "schedule": "[parameters('taskSchedule')]" + } + ] + } + } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('AcrName'))]", + "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('AcrName'), 'cssc-trigger-workflow'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb382eab-e894-4461-af04-94435c366c3f'))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb382eab-e894-4461-af04-94435c366c3f')]", + "principalId": "[reference(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('AcrName'), 'cssc-trigger-workflow'), '2019-06-01-preview', 'full').identity.principalId]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('AcrName'), 'cssc-trigger-workflow')]" + ] + } + ] +} \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/templates/task/cssc_patch_image.yaml b/src/acrcssc/azext_acrcssc/templates/task/cssc_patch_image.yaml new file mode 100644 index 00000000000..d78414c58b6 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/templates/task/cssc_patch_image.yaml @@ -0,0 +1,62 @@ +version: v1.1.0 +alias: + values: + ScanReport : os-vulnerability-report_trivy_{{ regexReplaceAll "[^a-zA-Z0-9]" .Values.SOURCE_REPOSITORY "-" }}_{{.Values.SOURCE_IMAGE_TAG}}_$(date "+%Y-%m-%d").json + cssc : mcr.microsoft.com/acr/cssc:cbcf692 +steps: + - id: print-inputs + cmd: | + bash -c 'echo "Patching OS vulnerabilities for image {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}"' + bash -c 'echo "Patching repo: {{.Values.SOURCE_REPOSITORY}}, Tag:{{.Values.SOURCE_IMAGE_TAG}}, NewPatchTag:{{.Values.SOURCE_IMAGE_NEWPATCH_TAG}}"' + + - id: check-patch-tag + cmd: | + bash -c 'echo "New Patch tag is {{.Values.SOURCE_IMAGE_NEWPATCH_TAG}}" + if [ "{{.Values.SOURCE_IMAGE_NEWPATCH_TAG}}" != "patched" ] && [ {{.Values.SOURCE_IMAGE_NEWPATCH_TAG}} -gt 999 ]; then + echo "New Patch tag is greater than 999. No more than 1000 patches can be created for a tag. Exiting the patching workflow." + exit 1 + fi' + + - id: setup-data-dir + cmd: bash mkdir ./data + - id: generate-trivy-report + retries: 3 + retryDelay: 5 + timeout: 1800 + cmd: | + cssc trivy image \ + {{.Run.Registry}}/{{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}} \ + --pkg-types os \ + --ignore-unfixed \ + --format json \ + --timeout 30m \ + --scanners vuln \ + --db-repository "ghcr.io/aquasecurity/trivy-db:2","public.ecr.aws/aquasecurity/trivy-db" \ + --output /workspace/data/$ScanReport + + - id: buildkitd + cmd: mobybuildkit --addr tcp://0.0.0.0:8888 + entrypoint: buildkitd + detach: true + privileged: true + ports: ["127.0.0.1:8888:8888/tcp"] + + - id: patch-image + retries: 3 + retryDelay: 5 + timeout: 1800 + cmd: | + cssc copa patch \ + -i "{{.Run.Registry}}/{{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}" \ + -r ./data/$ScanReport \ + -t "{{.Values.SOURCE_IMAGE_TAG}}-{{.Values.SOURCE_IMAGE_NEWPATCH_TAG}}" \ + --timeout 30m \ + --addr tcp://127.0.0.1:8888 + network: host + + - id: push-image + retries: 3 + retryDelay: 5 + timeout: 1800 + cmd: docker push {{.Run.Registry}}/{{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}-{{.Values.SOURCE_IMAGE_NEWPATCH_TAG}} + - cmd: bash echo "Patched image pushed to {{.Run.Registry}}/{{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}-{{.Values.SOURCE_IMAGE_NEWPATCH_TAG}}" \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/templates/task/cssc_scan_image.yaml b/src/acrcssc/azext_acrcssc/templates/task/cssc_scan_image.yaml new file mode 100644 index 00000000000..7746e7a25f9 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/templates/task/cssc_scan_image.yaml @@ -0,0 +1,55 @@ +version: v1.1.0 +alias: + values: + patchimagetask: cssc-patch-image + DATE: $(date "+%Y-%m-%d") + cssc : mcr.microsoft.com/acr/cssc:cbcf692 +steps: + - id: print-inputs + cmd: | + bash -c 'echo "Scanning image for vulnerability {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}} for tag {{.Values.SOURCE_IMAGE_ORIGINAL_TAG}}"' + bash -c 'echo "Scanning repo: {{.Values.SOURCE_REPOSITORY}}, Tag:{{.Values.SOURCE_IMAGE_TAG}}, OriginalTag:{{.Values.SOURCE_IMAGE_ORIGINAL_TAG}}"' + - id: setup-data-dir + cmd: bash mkdir ./data + + - id: generate-trivy-report + retries: 3 + retryDelay: 5 + timeout: 1800 + cmd: | + cssc trivy image \ + {{.Run.Registry}}/{{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}} \ + --pkg-types os \ + --ignore-unfixed \ + --format json \ + --timeout 30m \ + --scanners vuln \ + --db-repository "ghcr.io/aquasecurity/trivy-db:2","public.ecr.aws/aquasecurity/trivy-db" \ + --output /workspace/data/vulnerability-report_trivy_$DATE.json + + - cmd: cssc jq 'if .Results == null or (.Results | length) == 0 then 0 else [.Results[] | select(.Vulnerabilities != null) | .Vulnerabilities | length] | add end' /workspace/data/vulnerability-report_trivy_$DATE.json > /workspace/data/vulCount.txt + - cmd: cssc jq 'if .Metadata.OS.EOSL == null then false else .Metadata.OS.EOSL end' /workspace/data/vulnerability-report_trivy_$DATE.json > /workspace/data/eosl.txt + - cmd: | + bash -c 'echo "Vulnerabilities found for image {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}} -> $(cat /workspace/data/vulCount.txt)"' + bash -c 'echo "EOSL for the image {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}} -> $(cat /workspace/data/eosl.txt)"' + + - id: trigger-patch-task + retries: 3 + retryDelay: 10 + timeout: 1800 + cmd: | + az -c ' + vulCount=$(cat /workspace/data/vulCount.txt) && \ + eoslValue=$(cat /workspace/data/eosl.txt) && \ + if ! [[ "$vulCount" =~ ^[0-9]+$ ]]; then vulCount=0; fi && \ + if [ "$eoslValue" = "true" ]; then \ + echo "PATCHING will be skipped as EOSL is $eoslValue for image {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}"; \ + elif [ $vulCount -gt 0 ]; then \ + az login --identity; \ + echo "Total OS vulnerabilities found -> $vulCount"; \ + echo "PATCHING task scheduled for image {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}, new patch tag will be {{.Values.SOURCE_IMAGE_ORIGINAL_TAG}}-{{.Values.SOURCE_IMAGE_NEWPATCH_TAG}}"; \ + az acr task run --name $patchimagetask --registry $RegistryName --set SOURCE_REPOSITORY={{.Values.SOURCE_REPOSITORY}} --set SOURCE_IMAGE_TAG={{.Values.SOURCE_IMAGE_ORIGINAL_TAG}} --set SOURCE_IMAGE_NEWPATCH_TAG={{.Values.SOURCE_IMAGE_NEWPATCH_TAG}} --no-wait; \ + else \ + echo "PATCHING will be skipped as no vulnerability found in the image {{.Values.SOURCE_REPOSITORY}}:{{.Values.SOURCE_IMAGE_TAG}}"; \ + fi' + entryPoint: /bin/bash \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/templates/task/cssc_trigger_workflow.yaml b/src/acrcssc/azext_acrcssc/templates/task/cssc_trigger_workflow.yaml new file mode 100644 index 00000000000..994e6539585 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/templates/task/cssc_trigger_workflow.yaml @@ -0,0 +1,62 @@ +version: v1.1.0 +alias: + values: + ScanImageAndSchedulePatchTask: cssc-scan-image + cssc : mcr.microsoft.com/acr/cssc:cbcf692 + maxLimit: 100 +steps: + - cmd: bash -c 'echo "Inside cssc-trigger-workflow task, getting list of images to be patched based on --filter-policy for Registry {{.Run.Registry}}."' + - cmd: cssc acr cssc patch --filter-policy csscpolicies/patchpolicy:v1 --dry-run > filterRepos.txt + env: + - ACR_EXPERIMENTAL_CSSC=true + - cmd: bash -c 'sed -n "/^Validating/,/^Total/ {/^Validating/b;/^Total/b;p}" filterRepos.txt' > filterReposToDisplay.txt + - cmd: | + bash -c ' + echo "Below images will be scanned and patched (if any os vulnerabilities found) based on --filter-policy.\n$(cat filterReposToDisplay.txt)" + totalImages=$(sed -n "s/^Matches found://p" filterReposToDisplay.txt | tr -d "[:space:]") + if [ $totalImages -gt $maxLimit ]; then + echo "You have exceeded the maximum limit of $maxLimit images that can be scheduled for continuous patching. Adjust the JSON filter to limit the number of images. Failing the workflow." + exit 1 + fi' + - cmd: cssc acr cssc patch --filter-policy csscpolicies/patchpolicy:v1 --show-patch-tags --dry-run> filterReposWithPatchTags.txt + env: + - ACR_EXPERIMENTAL_CSSC=true + - cmd: bash -c 'sed -n "/^Listing/,/^Matches/ {/^Listing/b;/^Matches/b;/^Repo/b;p}" filterReposWithPatchTags.txt' > filteredReposAndTags.txt + - cmd: bash -c 'sed -n "/^Configured Tag Convention:/p" filterReposWithPatchTags.txt' > tagConvention.txt + - cmd: az login --identity + - id: scan-and-schedule-patch + timeout: 1800 + cmd: | + az -c ' + counter=0; \ + batchSize=10; \ + sleepDuration=30; \ + RegistryName={{.Run.Registry}}; \ + while read line;do \ + IFS=',' read -r -a array <<< "${line}" + RepoName=${array[0]} + OriginalTag=${array[1]} + TagName=${array[2]} + IncrementedTagNumber="" + echo "Tag Convention details: $(cat tagConvention.txt)" + if grep -q "floating" tagConvention.txt; then + IncrementedTagNumber="patched" + else + IncrementedTagNumber="1" + fi + + if [ $TagName == "N/A" ]; then + TagName=$OriginalTag + elif [[ $TagName =~ -([0-9]{1,3})$ ]]; then + TagNumber=${BASH_REMATCH[1]} + IncrementedTagNumber=$((TagNumber+1)) + fi + echo "Scheduling $ScanImageAndSchedulePatchTask for $RegistryName/$RepoName, Tag:$TagName, OriginalTag:$OriginalTag, PatchTag:$OriginalTag-$IncrementedTagNumber"; \ + az acr task run --name $ScanImageAndSchedulePatchTask --registry $RegistryName --set SOURCE_REPOSITORY=$RepoName --set SOURCE_IMAGE_TAG=$TagName --set SOURCE_IMAGE_ORIGINAL_TAG=$OriginalTag --set SOURCE_IMAGE_NEWPATCH_TAG=$IncrementedTagNumber --no-wait; \ + counter=$((counter+1)); \ + if [ $((counter%batchSize)) -eq 0 ]; then \ + echo "Waiting for $sleepDuration seconds before scheduling scans for next batch of images"; \ + sleep $sleepDuration; \ + fi; \ + done < filteredReposAndTags.txt;' + entryPoint: /bin/bash \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/templates/tmp_dry_run_template.yaml b/src/acrcssc/azext_acrcssc/templates/tmp_dry_run_template.yaml new file mode 100644 index 00000000000..76ca930618e --- /dev/null +++ b/src/acrcssc/azext_acrcssc/templates/tmp_dry_run_template.yaml @@ -0,0 +1,17 @@ +version: v1.1.0 +alias: + values: + cssc : mcr.microsoft.com/acr/cssc:cbcf692 + maxLimit: 100 +steps: + - id: acr-cli-filter + cmd: cssc acr cssc patch --dry-run --filter-policy-file {{.Values.CONFIGPATH}}> filterRepos.txt; + env: + - ACR_EXPERIMENTAL_CSSC=true + - cmd: | + bash -c ' + echo "$(cat filterRepos.txt)" + totalImages=$(sed -n "s/^Matches found://p" filterRepos.txt | tr -d "[:space:]") + if [ $totalImages -gt $maxLimit ]; then + echo "You have exceeded the maximum limit of $maxLimit images that can be scheduled for continuous patching. Adjust the JSON filter to limit the number of images." + fi' \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/tests/__init__.py b/src/acrcssc/azext_acrcssc/tests/__init__.py new file mode 100644 index 00000000000..2dcf9bb68b3 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/__init__.py @@ -0,0 +1,5 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# ----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/tests/latest/__init__.py b/src/acrcssc/azext_acrcssc/tests/latest/__init__.py new file mode 100644 index 00000000000..2dcf9bb68b3 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/__init__.py @@ -0,0 +1,5 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# ----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/tests/latest/artifact.json b/src/acrcssc/azext_acrcssc/tests/latest/artifact.json new file mode 100644 index 00000000000..116f9ac33dd --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/artifact.json @@ -0,0 +1,12 @@ +{ + "repositories": [ + { + "enabled": true, + "repository": "python", + "tags": [ + "*" + ] + } + ], + "version": "v1" +} \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/tests/latest/config/scenario_test_config.json b/src/acrcssc/azext_acrcssc/tests/latest/config/scenario_test_config.json new file mode 100644 index 00000000000..00e81616e25 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/config/scenario_test_config.json @@ -0,0 +1,13 @@ +{ + "repositories": [ + { + "repository": "alpine", + "tags": [ + "*" + ], + "enabled": true + } + ], + "tag-convention": "incremental", + "version": "v1" +} \ No newline at end of file diff --git a/src/acrcssc/azext_acrcssc/tests/latest/recordings/test_acrcssc_workflow.yaml b/src/acrcssc/azext_acrcssc/tests/latest/recordings/test_acrcssc_workflow.yaml new file mode 100644 index 00000000000..bdf727222aa --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/recordings/test_acrcssc_workflow.yaml @@ -0,0 +1,4949 @@ +interactions: +- request: + body: '{"location": "eastus", "sku": {"name": "Standard"}, "properties": {"adminUserEnabled": + false, "anonymousPullEnabled": false}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + Content-Length: + - '125' + Content-Type: + - application/json + ParameterSetName: + - -n -g --sku --location + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-11-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Creating","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled"}}' + headers: + api-supported-versions: + - 2023-11-01-preview + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-48eb44f2-1fc4-11f0-bbaf-0022487746b7?api-version=2023-11-01-preview&t=638809556423054325&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=XOLd2Ekg7xLG6RWU7-OkFwMbZR9jBuIiAOt8u9cmsuq__EK5Tg3NSNd04uvrxGCrGZ8D2u4J6MQI3R72dCZPB6kTcIgQWkQ3VAwniaSPXzRfuRB2JDlquN8tKORBdv-lLkOwhpdr4aHsTcPeceYaUakCyJo6035tgdXy98vY9XjbHmzhDUC2dz7OEz0mx5gLo5pGw4szltE4cML72xi4FVHxTJZMjup0ckatpXGopQEOlLxTKGh2K6BaQ36o-CAoC6hKxMSZ7tn4KH4p-PbbEPsLRz5DBr1vJY1uXzQ6Q8owUH-hrdSOkDRiAu2CIWfUiEZ41vDii-C9ZDdIvKfhJg&h=dtoeZGAk7r7mo6kcQX5R3MzZoWiScS8aVtzKDhRvUAk + cache-control: + - no-cache + content-length: + - '1396' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/69651348-778f-4dd9-bad6-483b0aa12b81 + x-ms-ratelimit-remaining-subscription-global-writes: + - '12000' + x-ms-ratelimit-remaining-subscription-writes: + - '800' + x-msedge-ref: + - 'Ref A: 95C371E320E3444CB3B7F2BE5E9BD49F Ref B: MWH011020807029 Ref C: 2025-04-22T21:53:54Z' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + ParameterSetName: + - -n -g --sku --location + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-48eb44f2-1fc4-11f0-bbaf-0022487746b7?api-version=2023-11-01-preview&t=638809556423054325&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=XOLd2Ekg7xLG6RWU7-OkFwMbZR9jBuIiAOt8u9cmsuq__EK5Tg3NSNd04uvrxGCrGZ8D2u4J6MQI3R72dCZPB6kTcIgQWkQ3VAwniaSPXzRfuRB2JDlquN8tKORBdv-lLkOwhpdr4aHsTcPeceYaUakCyJo6035tgdXy98vY9XjbHmzhDUC2dz7OEz0mx5gLo5pGw4szltE4cML72xi4FVHxTJZMjup0ckatpXGopQEOlLxTKGh2K6BaQ36o-CAoC6hKxMSZ7tn4KH4p-PbbEPsLRz5DBr1vJY1uXzQ6Q8owUH-hrdSOkDRiAu2CIWfUiEZ41vDii-C9ZDdIvKfhJg&h=dtoeZGAk7r7mo6kcQX5R3MzZoWiScS8aVtzKDhRvUAk + response: + body: + string: '{"status":"Creating"}' + headers: + api-supported-versions: + - 2023-11-01-preview + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-48eb44f2-1fc4-11f0-bbaf-0022487746b7?api-version=2023-11-01-preview&t=638809556425284177&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=w1Bz1l0iQHveS53KHYaMuOFM_XwdBq35tcQRh6I9t05gL7vRbKSyCU3qV3D9Uzyz7tFNFe2D5mYEx-Mqqt44yhDBxZi67Yt63BW17-81xj0iAoXsdHd_sTyLiNdmD_-T0Tpnn5Nmb-qNlUIrfDezTu4dPWUe3vQas9NvbNoOA6pRFZ2q_SMA9JUJaz9iIBkSHv2zk_TNw9UghVOyZILwVIFnEVEerVKUSp0FLVQct5vq7GWtP1As0OpXpr2DCKrtBjwv0zHbA7lWQ6EBFsBYZzhoEsdDPVd8mijD85KjQ7yMTz7k_zl7TkkALVchxPUXZJAGBJMfjamjGANxGd3gmQ&h=gTb3dzw6O_6cxKAx9k7Tx5Vi0cEyb_8d0Clg5jG6voI + cache-control: + - no-cache + content-length: + - '21' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/68b8e095-36cc-4fc8-8516-a542f512ea50 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 0B3B61F3B4AB494BBE6C17B6178F1396 Ref B: MWH011020807029 Ref C: 2025-04-22T21:54:02Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + ParameterSetName: + - -n -g --sku --location + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-48eb44f2-1fc4-11f0-bbaf-0022487746b7?api-version=2023-11-01-preview&t=638809556423054325&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=XOLd2Ekg7xLG6RWU7-OkFwMbZR9jBuIiAOt8u9cmsuq__EK5Tg3NSNd04uvrxGCrGZ8D2u4J6MQI3R72dCZPB6kTcIgQWkQ3VAwniaSPXzRfuRB2JDlquN8tKORBdv-lLkOwhpdr4aHsTcPeceYaUakCyJo6035tgdXy98vY9XjbHmzhDUC2dz7OEz0mx5gLo5pGw4szltE4cML72xi4FVHxTJZMjup0ckatpXGopQEOlLxTKGh2K6BaQ36o-CAoC6hKxMSZ7tn4KH4p-PbbEPsLRz5DBr1vJY1uXzQ6Q8owUH-hrdSOkDRiAu2CIWfUiEZ41vDii-C9ZDdIvKfhJg&h=dtoeZGAk7r7mo6kcQX5R3MzZoWiScS8aVtzKDhRvUAk + response: + body: + string: '{"status":"Succeeded"}' + headers: + api-supported-versions: + - 2023-11-01-preview + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-48eb44f2-1fc4-11f0-bbaf-0022487746b7?api-version=2023-11-01-preview&t=638809556528457045&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=tMaL15myLBRl2fkrP1zAhRZaP2ZwuISKz9HoCD50iDSmgpg9rNq0PEuyMr5nSLsjNZk7lsTvvL2PrhHlzxHJVRkMHdWBaVr8oCU3PG1eUrbrz-7CEgCFV9oLLO8rWiclabreBY1zolD8CyPiNGREzb56elbyWFDNuH8AVrg0XXmKZ5l7Jd_pH6u38Z6FTpn3PpXeZ61X14sT0LCIqswjY0XIZkXDjcaYtK4pe9H2blbjay3ITL92sHrQkCtR9jTtjdur7zOWQgZbqHA2RJ-PSLMInYRleHP1mMy_DFdtvCe69cKkxK7r2EU-Qste_WbDmdoeubHXlXzsH3PtCIprzQ&h=wbdo0BkNx25VSFuJFhlG7jOp5CwZ0YIQVNptffbA6-Y + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:12 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/9479da7f-043a-49e9-9606-af64317cc98b + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 319670C6B5134CBE94D0FC561C807D9C Ref B: MWH011020807029 Ref C: 2025-04-22T21:54:12Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + ParameterSetName: + - -n -g --sku --location + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-11-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Succeeded","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled"}}' + headers: + api-supported-versions: + - 2023-11-01-preview + cache-control: + - no-cache + content-length: + - '1397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:12 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 5E55693A65B744B7A750A9B45769B42C Ref B: MWH011020807029 Ref C: 2025-04-22T21:54:12Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-01-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Succeeded","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2023-01-01-preview + cache-control: + - no-cache + content-length: + - '1369' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:13 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: ED39DFBD97D8441582045683A2BB677F Ref B: CO6AA3150218039 Ref C: 2025-04-22T21:54:13Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image'' + under resource group ''clitest.rg000001'' was not found. For more details + please go to https://aka.ms/ARMResourceNotFoundFix"}}' + headers: + cache-control: + - no-cache + content-length: + - '262' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:14 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-failure-cause: + - gateway + x-msedge-ref: + - 'Ref A: 4ACC28DD830E4031AFFD2A8609BA031F Ref B: MWH011020807040 Ref C: 2025-04-22T21:54:14Z' + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image'' + under resource group ''clitest.rg000001'' was not found. For more details + please go to https://aka.ms/ARMResourceNotFoundFix"}}' + headers: + cache-control: + - no-cache + content-length: + - '261' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:14 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-failure-cause: + - gateway + x-msedge-ref: + - 'Ref A: FD5224D06E21454284487AFA917397E1 Ref B: MWH011020807040 Ref C: 2025-04-22T21:54:14Z' + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow'' + under resource group ''clitest.rg000001'' was not found. For more details + please go to https://aka.ms/ARMResourceNotFoundFix"}}' + headers: + cache-control: + - no-cache + content-length: + - '267' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:14 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-failure-cause: + - gateway + x-msedge-ref: + - 'Ref A: 36361998102F4FB88F57F4B9413D3E17 Ref B: MWH011020807040 Ref C: 2025-04-22T21:54:14Z' + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/listBuildSourceUploadUrl?api-version=2019-06-01-preview + response: + body: + string: '{"uploadUrl":"https://acrtaskprodeus093.blob.core.windows.net/container***tasks-source/202504220000/86a43d4c-71e1-448f-958f-7a312f32918b.tar.gz?skoid=54ea2226-b787-4507-912e-75de6df49d1d&sktid=33e01921-4d64-4f8c-a055-5bdaffd5e33d&skt=2025-04-22T21%3A34%3A20Z&ske=2025-04-29T21%3A39%3A20Z&sks=b&skv=2024-11-04&sv=2024-11-04&se=2025-04-22T22%3A54%3A15Z&sr=b&sp=cw&sig=****","relativePath":"tasks-source/202504220000/86a43d4c-71e1-448f-958f-7a312f32918b.tar.gz"}' + headers: + cache-control: + - no-cache + content-length: + - '536' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:14 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/f29e78c2-17e0-45b4-90fa-10a06a1e0905 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: BA5D1193F5BE4F64A9F109EFE42309ED Ref B: CO6AA3150218031 Ref C: 2025-04-22T21:54:14Z' + status: + code: 200 + message: OK +- request: + body: !!binary | + H4sICAYQCGgC/2NsaV9zb3VyY2VfYXJjaGl2ZV9iN2JiZjdlNTFlMjk0NmZmYjNiZWRlZDJiMWNj + NTQxYi50YXIA7ZdtT9swEID7lUr8h1OEBExLmvewIKahig0m3gRo2oRY5Tpu6ymJo9ipioD/vgtp + KSviG1Ro+PkSx3e+uyQ+38XqWJ0vp2Syz0jCytarYDc8d7Vtz5uP63nHdh2nBZPWEqikIiW6b71P + 3AgyxTO240R+4AVbW4FvhUHk2k67pfn/6SzBR53UURQ9n/84dgLbxk1Xa+J8aAd2CwKd/6+O9SbO + f//p+e/q838p5//W/Pz3nSC0bcdy/DAKfU8XgHeApCwnJRc9xaTqUZEP+ND6I0X+wvkfhuGz+e8F + TsvxoyjwPDfwHcx/z7H9Ftg6/1+dm9U2IEbJCiG5EiVn0ojhcrW9sjKVzZjrXKOGQdKC58z4uKCk + yHBqABYwPhj/Tl4trsWt2E9ZgstVWbG58K4Z1vortQMT9+mY5YqLvI6E57RkGd6TdBaOMWalnIrH + Dvq906n+huu//v97C/9/8/rvRYGvy/97QGVFLymve2WVYwuQFSlRzLomWbq8+u+4nvuk/vuurv/L + YFonYxhj3lv2apuknMi4rqJjklasGQJQKSnEkNHSyjgthRQDZVGRdQgtO7Uwpn06CD+5jXpGJoc8 + 4yoG/KVfbUvFisaSCTyJAReZNOXmgKeKlVMPGQru3aC0GRRE0RGYJm5QEzcojpoFZiFSTq/rOwY3 + N9aP+0it7snx14Nvp7sX+3d3n6FRPat7FktN1DY0blg+jmedhQm73bPe3s/TvbODo73ji93DXvf8 + vLsz6z7MJqjbmX6fSAyHwvpsgtGRAGNtgxK16G/zodlRAhuTg4wMmdxZ25AsATMHQ3Z+H9WPxyQM + RJUncadTGItG4BY7ITATMC5jWRDK4itjc2aXD+AS1h5ZB3OoYG326uFqG9SI5fM2qon2l6hgRMYM + 2IQylmA4qFV/MJ5VGaT3S8XgkR3eGFcjfEhKcugzkBh3UmGrhrHjtxLYiuWVqGTzxXg+tGA3+YOp + dW/7+/nJ8fTJ8GVMXdSCvMr6OIfeGh/Wwzsb8HV9Nms0Go1Go9FoNBqNRqPRvAR/ARsYPSAAKAAA + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '855' + Content-Type: + - application/octet-stream + User-Agent: + - azsdk-python-storage-blob/12.16.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + x-ms-blob-type: + - BlockBlob + x-ms-date: + - Tue, 22 Apr 2025 21:54:15 GMT + x-ms-version: + - '2022-11-02' + method: PUT + uri: https://acrtaskprodeus093.blob.core.windows.net/container***tasks-source/202504220000/86a43d4c-71e1-448f-958f-7a312f32918b.tar.gz?skoid=54ea2226-b787-4507-912e-75de6df49d1d&sktid=33e01921-4d64-4f8c-a055-5bdaffd5e33d&skt=2025-04-22T21%3A34%3A20Z&ske=2025-04-29T21%3A39%3A20Z&sks=b&skv=2024-11-04&sv=2024-11-04&se=2025-04-22T22%3A54%3A15Z&sr=b&sp=cw&sig=**** + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - oGwLilaX2EEYPbmuUT9wkg== + date: + - Tue, 22 Apr 2025 21:54:15 GMT + etag: + - '"0x8DD81E839DA9224"' + last-modified: + - Tue, 22 Apr 2025 21:54:15 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-content-crc64: + - m0U/hdnXogo= + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2022-11-02' + status: + code: 201 + message: Created +- request: + body: '{"type": "FileTaskRunRequest", "isArchiveEnabled": false, "taskFilePath": + "tmp_dry_run_template.yaml", "values": [{"name": "CONFIGPATH", "value": "scenario_test_config.json"}], + "platform": {"os": "Linux", "architecture": "amd64"}, "sourceLocation": "tasks-source/202504220000/86a43d4c-71e1-448f-958f-7a312f32918b.tar.gz", + "credentials": {}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + Content-Length: + - '340' + Content-Type: + - application/json + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scheduleRun?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/runs","properties":{"runId":"ca1","status":"Queued","lastUpdatedTime":"2025-04-22T21:54:16+00:00","provisioningState":"Succeeded","isArchiveEnabled":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1","name":"ca1","systemData":{"lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:16.2203539+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '517' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:16 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/1752911c-08c7-4da2-a407-83ca159f6485 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: FC37895CCA0F46BF8461533DD02A80EC Ref B: CO6AA3150218031 Ref C: 2025-04-22T21:54:16Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1/listLogSasUrl?api-version=2019-06-01-preview + response: + body: + string: '{"logLink":"https://acrtaskprodeus093.blob.core.windows.net/container***logs/ca1/rawtext.log?skoid=54ea2226-b787-4507-912e-75de6df49d1d&sktid=33e01921-4d64-4f8c-a055-5bdaffd5e33d&skt=2025-04-22T21%3A34%3A18Z&ske=2025-04-29T21%3A39%3A18Z&sks=b&skv=2024-11-04&sv=2024-11-04&se=2025-04-22T23%3A04%3A17Z&sr=b&sp=r&sig=****"}' + headers: + cache-control: + - no-cache + content-length: + - '397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:16 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/2734fdea-eeef-4aeb-9ad7-1ee6f3290e0e + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: F7F01D86B24A48398D75742FD5F861E5 Ref B: CO6AA3150219035 Ref C: 2025-04-22T21:54:16Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/runs","properties":{"runId":"ca1","status":"Running","lastUpdatedTime":"2025-04-22T21:54:16+00:00","runType":"QuickRun","createTime":"2025-04-22T21:54:16.5014686+00:00","startTime":"2025-04-22T21:54:16.8311152+00:00","platform":{"os":"Linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"provisioningState":"Succeeded","isArchiveEnabled":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1","name":"ca1","systemData":{"lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:16.2203539+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '716' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:16 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/50660b5c-d3c5-41fa-a4cb-65595e98e1a1 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 47689DA4B4B24475991C571DA40605A1 Ref B: CO6AA3150219035 Ref C: 2025-04-22T21:54:17Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/runs","properties":{"runId":"ca1","status":"Running","lastUpdatedTime":"2025-04-22T21:54:16+00:00","runType":"QuickRun","createTime":"2025-04-22T21:54:16.5014686+00:00","startTime":"2025-04-22T21:54:16.8311152+00:00","platform":{"os":"Linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"provisioningState":"Succeeded","isArchiveEnabled":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1","name":"ca1","systemData":{"lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:16.2203539+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '716' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:18 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/5f3e38b4-00f2-4555-8fa6-3f759b83b681 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 603E4CD045B14D52829879243729B658 Ref B: CO6AA3150219035 Ref C: 2025-04-22T21:54:19Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/runs","properties":{"runId":"ca1","status":"Running","lastUpdatedTime":"2025-04-22T21:54:16+00:00","runType":"QuickRun","createTime":"2025-04-22T21:54:16.5014686+00:00","startTime":"2025-04-22T21:54:16.8311152+00:00","platform":{"os":"Linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"provisioningState":"Succeeded","isArchiveEnabled":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1","name":"ca1","systemData":{"lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:16.2203539+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '716' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:20 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/eba56d27-4bb8-4c2c-a8ef-ad697a77215d + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 5C72F1740931467DAA0E050F8CCD7291 Ref B: CO6AA3150219035 Ref C: 2025-04-22T21:54:21Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/runs","properties":{"runId":"ca1","status":"Succeeded","lastUpdatedTime":"2025-04-22T21:54:23+00:00","runType":"QuickRun","createTime":"2025-04-22T21:54:16.5014686+00:00","startTime":"2025-04-22T21:54:16.8311152+00:00","finishTime":"2025-04-22T21:54:23.5060532+00:00","platform":{"os":"Linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"provisioningState":"Succeeded","isArchiveEnabled":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs/ca1","name":"ca1","systemData":{"lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:16.2203539+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '767' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:26 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/706411a1-8fec-42cc-9c7d-bc119ff4bedd + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 57FFFA52457041258AB90C83806F4AB5 Ref B: CO6AA3150219035 Ref C: 2025-04-22T21:54:22Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.16.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + x-ms-date: + - Tue, 22 Apr 2025 21:54:27 GMT + x-ms-range: + - bytes=0-33554431 + x-ms-version: + - '2022-11-02' + method: GET + uri: https://acrtaskprodeus093.blob.core.windows.net/container***logs/ca1/rawtext.log?skoid=54ea2226-b787-4507-912e-75de6df49d1d&sktid=33e01921-4d64-4f8c-a055-5bdaffd5e33d&skt=2025-04-22T21%3A34%3A18Z&ske=2025-04-29T21%3A39%3A18Z&sks=b&skv=2024-11-04&sv=2024-11-04&se=2025-04-22T23%3A04%3A17Z&sr=b&sp=r&sig=**** + response: + body: + string: "2025/04/22 21:54:17 Downloading source code...\r\n2025/04/22 21:54:17 + Finished downloading source code\r\n2025/04/22 21:54:18 Alias support enabled + for version >= 1.1.0, please see https://aka.ms/acr/tasks/task-aliases for + more information.\n2025/04/22 21:54:18 Creating Docker network: acb_default_network, + driver: 'bridge'\n2025/04/22 21:54:18 Successfully set up Docker network: + acb_default_network\n2025/04/22 21:54:18 Setting up Docker configuration...\n2025/04/22 + 21:54:18 Successfully set up Docker configuration\n2025/04/22 21:54:18 Logging + in to registry: clireg000002.azurecr.io\n2025/04/22 21:54:19 Successfully + logged into clireg000002.azurecr.io\n2025/04/22 21:54:19 Executing step ID: + acr-cli-filter. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'\n2025/04/22 + 21:54:19 Launching container with name: acr-cli-filter\n2025/04/22 21:54:20 + Successfully executed container: acr-cli-filter\n2025/04/22 21:54:20 Executing + step ID: acb_step_1. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'\n2025/04/22 + 21:54:20 Launching container with name: acb_step_1\r\nDRY RUN mode enabled...\nDRY + RUN mode will only list all the repositories and tags that match the filter + and are eligible for continuous scan and patch. During the actual patch operation, + each of the eligible images will first be scanned using trivy and if there + are any vulnerabilities found, a new patched image will be generated with + tag -patched or -x based on the configured tag-convention.\nReading + filter from filter file path...\nValidating filter...\nConfigured Tag Convention: + \ incremental\nArtifacts specified in the filter that do not exist:\nRepo,Tag\nalpine,*\nNot + found: 1\nNo matching repository and tag found!\nMatches found: 0\n2025/04/22 + 21:54:20 Successfully executed container: acb_step_1\n2025/04/22 21:54:20 + Step ID: acr-cli-filter marked as successful (elapsed time in seconds: 0.726135)\n2025/04/22 + 21:54:20 Step ID: acb_step_1 marked as successful (elapsed time in seconds: + 0.501622)\n\r\nRun ID: ca1 was successful after 4s\r\n" + headers: + accept-ranges: + - bytes + content-disposition: + - '' + content-encoding: + - utf-8 + content-length: + - '2060' + content-range: + - bytes 0-2075/2076 + content-type: + - text/plain; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:27 GMT + etag: + - '"0x8DD81E83CD11902"' + last-modified: + - Tue, 22 Apr 2025 21:54:20 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-blob-committed-block-count: + - '5' + x-ms-blob-type: + - AppendBlob + x-ms-creation-time: + - Tue, 22 Apr 2025 21:54:16 GMT + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-meta-complete: + - successful + x-ms-server-encrypted: + - 'true' + x-ms-version: + - '2022-11-02' + status: + code: 206 + message: Partial Content +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image'' + under resource group ''clitest.rg000001'' was not found. For more details + please go to https://aka.ms/ARMResourceNotFoundFix"}}' + headers: + cache-control: + - no-cache + content-length: + - '262' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:28 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-failure-cause: + - gateway + x-msedge-ref: + - 'Ref A: 49216079E1344431BC6C6B03FF16D09C Ref B: CO6AA3150219049 Ref C: 2025-04-22T21:54:28Z' + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image'' + under resource group ''clitest.rg000001'' was not found. For more details + please go to https://aka.ms/ARMResourceNotFoundFix"}}' + headers: + cache-control: + - no-cache + content-length: + - '261' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:28 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-failure-cause: + - gateway + x-msedge-ref: + - 'Ref A: 148435B524DC45C79EFC92826794EBC3 Ref B: CO6AA3150219049 Ref C: 2025-04-22T21:54:28Z' + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The Resource ''Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow'' + under resource group ''clitest.rg000001'' was not found. For more details + please go to https://aka.ms/ARMResourceNotFoundFix"}}' + headers: + cache-control: + - no-cache + content-length: + - '267' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:28 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-failure-cause: + - gateway + x-msedge-ref: + - 'Ref A: 8F886A46B1874D8DBDCDBF9758EE73DD Ref B: CO6AA3150219049 Ref C: 2025-04-22T21:54:28Z' + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/octet-stream + User-Agent: + - python-requests/2.32.3 + method: POST + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/blobs/uploads/ + response: + body: + string: '{"errors":[{"code":"UNAUTHORIZED","message":"authentication required, + visit https://aka.ms/acr/authorization for more information.","detail":[{"Type":"repository","Name":"csscpolicies/patchpolicy","Action":"pull"},{"Type":"repository","Name":"csscpolicies/patchpolicy","Action":"push"}]}]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '290' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:32 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://cliregrutwpbbvyhtugt.azurecr.io/oauth2/token",service="cliregrutwpbbvyhtugt.azurecr.io",scope="repository:csscpolicies/patchpolicy:pull,push",error="malformed_token" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Service: + - cliregrutwpbbvyhtugt.azurecr.io + User-Agent: + - oras-py + method: GET + uri: https://clireg000002.azurecr.io/oauth2/token?service=clireg000002.azurecr.io&scope=repository%3Acsscpolicies%2Fpatchpolicy%3Apull%2Cpush + response: + body: + string: '{"access_token":"***","refresh_token":"***"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:32 GMT + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '166.65' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/octet-stream + User-Agent: + - python-requests/2.32.3 + method: POST + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/blobs/uploads/ + response: + body: + string: '' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:54:32 GMT + docker-distribution-api-version: + - registry/2.0 + docker-upload-uuid: + - cf38fbb1-bf2f-4498-a24a-071027d2ccc2 + location: + - /v2/csscpolicies/patchpolicy/blobs/uploads/cf38fbb1-bf2f-4498-a24a-071027d2ccc2?_nouploadcache=false&_state=b6cE_IOK1p_11wAQ_9Hm1NBbiIDZE6hH5d9reZSgLOV7Ik5hbWUiOiJjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3kiLCJVVUlEIjoiY2YzOGZiYjEtYmYyZi00NDk4LWEyNGEtMDcxMDI3ZDJjY2MyIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDI1LTA0LTIyVDIxOjU0OjMyLjIzNzI2MTMyNVoifQ%3D%3D + range: + - 0-0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 202 + message: Accepted +- request: + body: "{\r\n \"repositories\": [\r\n\t\t{\r\n \"repository\": \"alpine\",\r\n + \ \"tags\": [\r\n \"*\"\r\n ],\r\n \"enabled\": + true\r\n }\r\n ],\r\n\t\"tag-convention\": \"incremental\",\r\n \"version\": + \"v1\"\r\n}" + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '233' + Content-Type: + - application/octet-stream + User-Agent: + - python-requests/2.32.3 + method: PUT + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/blobs/uploads/cf38fbb1-bf2f-4498-a24a-071027d2ccc2?_nouploadcache=false&_state=b6cE_IOK1p_11wAQ_9Hm1NBbiIDZE6hH5d9reZSgLOV7Ik5hbWUiOiJjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3kiLCJVVUlEIjoiY2YzOGZiYjEtYmYyZi00NDk4LWEyNGEtMDcxMDI3ZDJjY2MyIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDI1LTA0LTIyVDIxOjU0OjMyLjIzNzI2MTMyNVoifQ%3D%3D&digest=sha256%3A0b061a62bdaf0be5c085634ee969a2e378b7d09cd8c794674ebcd26d48a20287 + response: + body: + string: '' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:54:32 GMT + docker-content-digest: + - sha256:0b061a62bdaf0be5c085634ee969a2e378b7d09cd8c794674ebcd26d48a20287 + docker-distribution-api-version: + - registry/2.0 + location: + - /v2/csscpolicies/patchpolicy/blobs/sha256:0b061a62bdaf0be5c085634ee969a2e378b7d09cd8c794674ebcd26d48a20287 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/octet-stream + User-Agent: + - python-requests/2.32.3 + method: POST + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/blobs/uploads/ + response: + body: + string: '' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:54:32 GMT + docker-distribution-api-version: + - registry/2.0 + docker-upload-uuid: + - c32ccf12-273f-436e-af5b-3f1248704d2b + location: + - /v2/csscpolicies/patchpolicy/blobs/uploads/c32ccf12-273f-436e-af5b-3f1248704d2b?_nouploadcache=false&_state=ckg8-JSIS0Z4ZSUi-xlf3S2x9_BsVxjA3mgtnXjDR5J7Ik5hbWUiOiJjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3kiLCJVVUlEIjoiYzMyY2NmMTItMjczZi00MzZlLWFmNWItM2YxMjQ4NzA0ZDJiIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDI1LTA0LTIyVDIxOjU0OjMyLjYyMzU1NzAzMVoifQ%3D%3D + range: + - 0-0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 202 + message: Accepted +- request: + body: '{}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2' + Content-Type: + - application/octet-stream + User-Agent: + - python-requests/2.32.3 + method: PUT + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/blobs/uploads/c32ccf12-273f-436e-af5b-3f1248704d2b?_nouploadcache=false&_state=ckg8-JSIS0Z4ZSUi-xlf3S2x9_BsVxjA3mgtnXjDR5J7Ik5hbWUiOiJjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3kiLCJVVUlEIjoiYzMyY2NmMTItMjczZi00MzZlLWFmNWItM2YxMjQ4NzA0ZDJiIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDI1LTA0LTIyVDIxOjU0OjMyLjYyMzU1NzAzMVoifQ%3D%3D&digest=sha256%3A44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a + response: + body: + string: '' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:54:32 GMT + docker-content-digest: + - sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a + docker-distribution-api-version: + - registry/2.0 + location: + - /v2/csscpolicies/patchpolicy/blobs/sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 201 + message: Created +- request: + body: '{"schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", + "config": {"mediaType": "application/vnd.unknown.config.v1+json", "size": 2, + "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}, + "layers": [{"mediaType": "application/vnd.oci.image.layer.v1.tar", "size": 233, + "digest": "sha256:0b061a62bdaf0be5c085634ee969a2e378b7d09cd8c794674ebcd26d48a20287", + "annotations": {"org.opencontainers.image.title": "cssc_config_tmp_nncoqvqf"}}], + "annotations": {}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '507' + Content-Type: + - application/vnd.oci.image.manifest.v1+json + User-Agent: + - python-requests/2.32.3 + method: PUT + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/manifests/v1 + response: + body: + string: '' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:54:33 GMT + docker-content-digest: + - sha256:7f35b408122f42636a4b7a063bf2f678aba6b0122d0242c8e4e5c11b17d30ffd + docker-distribution-api-version: + - registry/2.0 + location: + - /v2/csscpolicies/patchpolicy/manifests/sha256:7f35b408122f42636a4b7a063bf2f678aba6b0122d0242c8e4e5c11b17d30ffd + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 201 + message: Created +- request: + body: '{"properties": {"template": {"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", "parameters": {"AcrName": {"type": "string"}, "AcrLocation": + {"type": "string", "defaultValue": "[resourceGroup().location]"}, "taskSchedule": + {"type": "string"}, "imagePatchingEncodedTask": {"type": "string"}, "imageScanningEncodedTask": + {"type": "string"}, "registryScanningEncodedTask": {"type": "string"}}, "resources": + [{"type": "Microsoft.ContainerRegistry/registries/tasks", "apiVersion": "2019-06-01-preview", + "name": "[format(''{0}/{1}'', parameters(''AcrName''), ''cssc-patch-image'')]", + "location": "[parameters(''AcrLocation'')]", "tags": {"cssc": "true", "clienttracking": + "true"}, "properties": {"platform": {"os": "linux", "architecture": "amd64"}, + "agentConfiguration": {"cpu": 2}, "timeout": 3600, "step": {"type": "EncodedTask", + "encodedTaskContent": "[parameters(''imagePatchingEncodedTask'')]", "values": + []}, "isSystemTask": false}}, {"type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", "name": "[format(''{0}/{1}'', parameters(''AcrName''), + ''cssc-scan-image'')]", "location": "[parameters(''AcrLocation'')]", "identity": + {"type": "SystemAssigned"}, "tags": {"cssc": "true"}, "properties": {"platform": + {"os": "linux", "architecture": "amd64"}, "agentConfiguration": {"cpu": 2}, + "timeout": 3600, "step": {"type": "EncodedTask", "encodedTaskContent": "[parameters(''imageScanningEncodedTask'')]", + "values": []}, "isSystemTask": false}}, {"type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", "scope": "[format(''Microsoft.ContainerRegistry/registries/{0}'', + parameters(''AcrName''))]", "name": "[guid(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-scan-image''), subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', + ''fb382eab-e894-4461-af04-94435c366c3f''))]", "properties": {"roleDefinitionId": + "[subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', ''fb382eab-e894-4461-af04-94435c366c3f'')]", + "principalId": "[reference(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-scan-image''), ''2019-06-01-preview'', ''full'').identity.principalId]", + "principalType": "ServicePrincipal"}, "dependsOn": ["[resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-scan-image'')]"]}, {"type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", "name": "[format(''{0}/{1}'', parameters(''AcrName''), + ''cssc-trigger-workflow'')]", "location": "[parameters(''AcrLocation'')]", "identity": + {"type": "SystemAssigned"}, "tags": {"cssc": "true", "clienttracking": "true"}, + "properties": {"platform": {"os": "linux", "architecture": "amd64"}, "agentConfiguration": + {"cpu": 2}, "timeout": 3600, "status": "Enabled", "step": {"type": "EncodedTask", + "encodedTaskContent": "[parameters(''registryScanningEncodedTask'')]", "values": + []}, "isSystemTask": false, "trigger": {"timerTriggers": [{"name": "azcli_defined_schedule", + "schedule": "[parameters(''taskSchedule'')]"}]}}}, {"type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", "scope": "[format(''Microsoft.ContainerRegistry/registries/{0}'', + parameters(''AcrName''))]", "name": "[guid(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-trigger-workflow''), subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', + ''fb382eab-e894-4461-af04-94435c366c3f''))]", "properties": {"roleDefinitionId": + "[subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', ''fb382eab-e894-4461-af04-94435c366c3f'')]", + "principalId": "[reference(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-trigger-workflow''), ''2019-06-01-preview'', + ''full'').identity.principalId]", "principalType": "ServicePrincipal"}, "dependsOn": + ["[resourceId(''Microsoft.ContainerRegistry/registries/tasks'', parameters(''AcrName''), + ''cssc-trigger-workflow'')]"]}]}, "parameters": {"AcrName": {"value": "clireg000002"}, + "AcrLocation": {"value": "eastus"}, "taskSchedule": {"value": "54 21 */7 * *"}, + "imagePatchingEncodedTask": {"value": "dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI="}, + "imageScanningEncodedTask": {"value": "dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}, + "registryScanningEncodedTask": {"value": "dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}}, + "mode": "Incremental"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + Content-Length: + - '15976' + Content-Type: + - application/json + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.Resources/deployments/mock-deployment/validate?api-version=2022-09-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Resources/deployments/continuouspatchingdeployment","name":"continuouspatchingdeployment","type":"Microsoft.Resources/deployments","properties":{"templateHash":"10134497220426740808","parameters":{"acrName":{"type":"String","value":"clireg000002"},"acrLocation":{"type":"String","value":"eastus"},"taskSchedule":{"type":"String","value":"54 + 21 */7 * *"},"imagePatchingEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI="},"imageScanningEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"},"registryScanningEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}},"mode":"Incremental","provisioningState":"Succeeded","timestamp":"2025-04-22T21:54:33.942931Z","duration":"PT0S","correlationId":"ddb1673c-63fd-4911-9512-f31c6e0ebc24","providers":[{"namespace":"Microsoft.ContainerRegistry","resourceTypes":[{"resourceType":"registries/tasks","locations":["eastus"]}]},{"namespace":"Microsoft.Authorization","resourceTypes":[{"resourceType":"roleAssignments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-scan-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-scan-image","apiVersion":"2019-06-01-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe","resourceType":"Microsoft.Authorization/roleAssignments","resourceName":"6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"},{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-trigger-workflow"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-trigger-workflow","apiVersion":"2019-06-01-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6","resourceType":"Microsoft.Authorization/roleAssignments","resourceName":"c40df73a-b6a5-5458-a0a5-dc5aa98facc6"}],"validatedResources":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6"}]}}' + headers: + cache-control: + - no-cache + content-length: + - '15745' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:33 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: BD10F9D9710941789761E1455A89D2E4 Ref B: MWH011020809036 Ref C: 2025-04-22T21:54:33Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"template": {"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", "parameters": {"AcrName": {"type": "string"}, "AcrLocation": + {"type": "string", "defaultValue": "[resourceGroup().location]"}, "taskSchedule": + {"type": "string"}, "imagePatchingEncodedTask": {"type": "string"}, "imageScanningEncodedTask": + {"type": "string"}, "registryScanningEncodedTask": {"type": "string"}}, "resources": + [{"type": "Microsoft.ContainerRegistry/registries/tasks", "apiVersion": "2019-06-01-preview", + "name": "[format(''{0}/{1}'', parameters(''AcrName''), ''cssc-patch-image'')]", + "location": "[parameters(''AcrLocation'')]", "tags": {"cssc": "true", "clienttracking": + "true"}, "properties": {"platform": {"os": "linux", "architecture": "amd64"}, + "agentConfiguration": {"cpu": 2}, "timeout": 3600, "step": {"type": "EncodedTask", + "encodedTaskContent": "[parameters(''imagePatchingEncodedTask'')]", "values": + []}, "isSystemTask": false}}, {"type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", "name": "[format(''{0}/{1}'', parameters(''AcrName''), + ''cssc-scan-image'')]", "location": "[parameters(''AcrLocation'')]", "identity": + {"type": "SystemAssigned"}, "tags": {"cssc": "true"}, "properties": {"platform": + {"os": "linux", "architecture": "amd64"}, "agentConfiguration": {"cpu": 2}, + "timeout": 3600, "step": {"type": "EncodedTask", "encodedTaskContent": "[parameters(''imageScanningEncodedTask'')]", + "values": []}, "isSystemTask": false}}, {"type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", "scope": "[format(''Microsoft.ContainerRegistry/registries/{0}'', + parameters(''AcrName''))]", "name": "[guid(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-scan-image''), subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', + ''fb382eab-e894-4461-af04-94435c366c3f''))]", "properties": {"roleDefinitionId": + "[subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', ''fb382eab-e894-4461-af04-94435c366c3f'')]", + "principalId": "[reference(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-scan-image''), ''2019-06-01-preview'', ''full'').identity.principalId]", + "principalType": "ServicePrincipal"}, "dependsOn": ["[resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-scan-image'')]"]}, {"type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", "name": "[format(''{0}/{1}'', parameters(''AcrName''), + ''cssc-trigger-workflow'')]", "location": "[parameters(''AcrLocation'')]", "identity": + {"type": "SystemAssigned"}, "tags": {"cssc": "true", "clienttracking": "true"}, + "properties": {"platform": {"os": "linux", "architecture": "amd64"}, "agentConfiguration": + {"cpu": 2}, "timeout": 3600, "status": "Enabled", "step": {"type": "EncodedTask", + "encodedTaskContent": "[parameters(''registryScanningEncodedTask'')]", "values": + []}, "isSystemTask": false, "trigger": {"timerTriggers": [{"name": "azcli_defined_schedule", + "schedule": "[parameters(''taskSchedule'')]"}]}}}, {"type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", "scope": "[format(''Microsoft.ContainerRegistry/registries/{0}'', + parameters(''AcrName''))]", "name": "[guid(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-trigger-workflow''), subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', + ''fb382eab-e894-4461-af04-94435c366c3f''))]", "properties": {"roleDefinitionId": + "[subscriptionResourceId(''Microsoft.Authorization/roleDefinitions'', ''fb382eab-e894-4461-af04-94435c366c3f'')]", + "principalId": "[reference(resourceId(''Microsoft.ContainerRegistry/registries/tasks'', + parameters(''AcrName''), ''cssc-trigger-workflow''), ''2019-06-01-preview'', + ''full'').identity.principalId]", "principalType": "ServicePrincipal"}, "dependsOn": + ["[resourceId(''Microsoft.ContainerRegistry/registries/tasks'', parameters(''AcrName''), + ''cssc-trigger-workflow'')]"]}]}, "parameters": {"AcrName": {"value": "clireg000002"}, + "AcrLocation": {"value": "eastus"}, "taskSchedule": {"value": "54 21 */7 * *"}, + "imagePatchingEncodedTask": {"value": "dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI="}, + "imageScanningEncodedTask": {"value": "dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}, + "registryScanningEncodedTask": {"value": "dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}}, + "mode": "Incremental"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + Content-Length: + - '15976' + Content-Type: + - application/json + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.Resources/deployments/mock-deployment?api-version=2022-09-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Resources/deployments/continuouspatchingdeployment","name":"continuouspatchingdeployment","type":"Microsoft.Resources/deployments","properties":{"templateHash":"10134497220426740808","parameters":{"acrName":{"type":"String","value":"clireg000002"},"acrLocation":{"type":"String","value":"eastus"},"taskSchedule":{"type":"String","value":"54 + 21 */7 * *"},"imagePatchingEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI="},"imageScanningEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"},"registryScanningEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}},"mode":"Incremental","provisioningState":"Accepted","timestamp":"2025-04-22T21:54:34.8881987Z","duration":"PT0.0004374S","correlationId":"831f1c10-650f-4a7c-a386-be0be48ae4e2","providers":[{"namespace":"Microsoft.ContainerRegistry","resourceTypes":[{"resourceType":"registries/tasks","locations":["eastus"]}]},{"namespace":"Microsoft.Authorization","resourceTypes":[{"resourceType":"roleAssignments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-scan-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-scan-image","apiVersion":"2019-06-01-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe","resourceType":"Microsoft.Authorization/roleAssignments","resourceName":"6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"},{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-trigger-workflow"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-trigger-workflow","apiVersion":"2019-06-01-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6","resourceType":"Microsoft.Authorization/roleAssignments","resourceName":"c40df73a-b6a5-5458-a0a5-dc5aa98facc6"}]}}' + headers: + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.Resources/deployments/continuouspatchingdeployment/operationStatuses/08584562480105788352?api-version=2022-09-01&t=638809556755758598&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=byAWtdLUs1FYwj1gzIi-BdIfOc60gWFPjZECuF-3bU0wtS1EN7VDn5mekFwR13SEvEwfCE5EInqeNcBl-bEsv_-PO17Qoyfw1Yj89NF9TGaFVp3f22PqIR_j_OvotkWEZWjo8jcFOEYygN4LqPHO0fmCWuyhAagdT4dLVXh2IlyIK7k-FEmZqe2iW5fAXt-R2vBo-Rp492pbhgcBmcEuM4dJn3DUF4bOV_WbGLvod3NdG4q7AP0_hxTRRRuHZJM0J8XMcgBBcmVyDUP1ea-jkVb64nDUsmzT4rCXxWnTfoG8n9cr5e0OT3cUa-fR2GMvUXYawDJoz-igNhaK_x0Yaw&h=-aL6oA4im2mws1ZyVE87jM71U6U6WEEckRioF1S6veI + cache-control: + - no-cache + content-length: + - '14708' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:35 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-deployment-engine-version: + - 1.309.0 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 4BD13EE0AACC4A1EAA2EE3D3CC684C1D Ref B: MWH011020809025 Ref C: 2025-04-22T21:54:34Z' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08584562480105788352?api-version=2022-09-01&t=638809556755758598&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=byAWtdLUs1FYwj1gzIi-BdIfOc60gWFPjZECuF-3bU0wtS1EN7VDn5mekFwR13SEvEwfCE5EInqeNcBl-bEsv_-PO17Qoyfw1Yj89NF9TGaFVp3f22PqIR_j_OvotkWEZWjo8jcFOEYygN4LqPHO0fmCWuyhAagdT4dLVXh2IlyIK7k-FEmZqe2iW5fAXt-R2vBo-Rp492pbhgcBmcEuM4dJn3DUF4bOV_WbGLvod3NdG4q7AP0_hxTRRRuHZJM0J8XMcgBBcmVyDUP1ea-jkVb64nDUsmzT4rCXxWnTfoG8n9cr5e0OT3cUa-fR2GMvUXYawDJoz-igNhaK_x0Yaw&h=-aL6oA4im2mws1ZyVE87jM71U6U6WEEckRioF1S6veI + response: + body: + string: '{"status":"Accepted"}' + headers: + cache-control: + - no-cache + content-length: + - '21' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:54:35 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: DD2139B571A64ABE96CD44C6C511C85D Ref B: MWH011020809025 Ref C: 2025-04-22T21:54:35Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.Resources/deployments/mock-deployment/operationStatuses/08584562480105788352?api-version=2022-09-01&t=638809556755758598&c=MIIHpTCCBo2gAwIBAgITOgWZuFmLREgOyTdeugAEBZm4WTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSU5GUkEgQ0EgMDEwHhcNMjUwNDE5MTQyMjI3WhcNMjUxMDE2MTQyMjI3WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPxDlNdj6r6H0vTzKfz228nqLQPXYSxPqEGQSSSCczQcCX3f_Xtnvc-lFdoleay-OVQlgfbWiMkGazl2q7FVj9BZUHJ3KXFg833nlMDzzIkfrA17t4t3OW-6po21aPw9TdEBtH-GReYxdd8YmK-hHhKfpllLkKKn29Z8r3ecn-VJ1URRr4gV1Dnhd8h62eio4oVWmqq_9ITkiyfphE8gKB3n-2ZGTlftv1uEX4hpgnUbyhP4GBPp9Ni0RdYmpukMEr1-GI3W5OnXgKOvoCRB0HZQKU-5u630M-76UA_GFyALd1X_xQwHcCHKvtBzX5EEcQ4AOj_B540c3Mp0HnljQsECAwEAAaOCBJIwggSOMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFghfmRS4WsmTQCAWQCAQcwggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CWTJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSU5GUkElMjBDQSUyMDAxKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMElORlJBJTIwQ0ElMjAwMSg0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3J0MB0GA1UdDgQWBBRgocSx-jjjSuZiJXHuNlAhZPhmbjAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJTkZSQSUyMENBJTIwMDEoNCkuY3JsMIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAfBgNVHSMEGDAWgBTl2Ztn_PjsurvwwKidileIud8-YzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAK5mT0Rrym5x1NF2yah7nxZLo1y0madgpRkCREZyGAoW02DZD68DX6wagq4RbcOr_MAlhvWOTjVB8J52ZIsydOGq5NSpxte9Cy10m7-zSXWMn0yNE8YUToarDNRzmshQ5pEBXhjU6kSMEvqeNG8Fr3KrDZEVieQc5By_ZV8F9vtuv90XjrjiLw1qOrPVVvUFOTx-JlUR4aErF4Jldd_YA0aWCiYbvu3Bd1vWtXdnrkJSX-natlKNqGimVnj86nKEao8ktK5pKaHq6C8vbOLeNreXRy5C2fC1tgiZ00V2pHuk1qbOdhlzTDv8G0HZLm_T7_s92OBqMAwBJ1uChKnQm6M&s=byAWtdLUs1FYwj1gzIi-BdIfOc60gWFPjZECuF-3bU0wtS1EN7VDn5mekFwR13SEvEwfCE5EInqeNcBl-bEsv_-PO17Qoyfw1Yj89NF9TGaFVp3f22PqIR_j_OvotkWEZWjo8jcFOEYygN4LqPHO0fmCWuyhAagdT4dLVXh2IlyIK7k-FEmZqe2iW5fAXt-R2vBo-Rp492pbhgcBmcEuM4dJn3DUF4bOV_WbGLvod3NdG4q7AP0_hxTRRRuHZJM0J8XMcgBBcmVyDUP1ea-jkVb64nDUsmzT4rCXxWnTfoG8n9cr5e0OT3cUa-fR2GMvUXYawDJoz-igNhaK_x0Yaw&h=-aL6oA4im2mws1ZyVE87jM71U6U6WEEckRioF1S6veI + response: + body: + string: '{"status":"Succeeded"}' + headers: + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:05 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 8F14539AC2F34FB88F3DC28000D87706 Ref B: MWH011020809025 Ref C: 2025-04-22T21:55:05Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow create + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --config --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.Resources/deployments/mock-deployment?api-version=2022-09-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Resources/deployments/continuouspatchingdeployment","name":"continuouspatchingdeployment","type":"Microsoft.Resources/deployments","properties":{"templateHash":"10134497220426740808","parameters":{"acrName":{"type":"String","value":"clireg000002"},"acrLocation":{"type":"String","value":"eastus"},"taskSchedule":{"type":"String","value":"54 + 21 */7 * *"},"imagePatchingEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI="},"imageScanningEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"},"registryScanningEncodedTask":{"type":"String","value":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo"}},"mode":"Incremental","provisioningState":"Succeeded","timestamp":"2025-04-22T21:54:46.9539407Z","duration":"PT12.065742S","correlationId":"831f1c10-650f-4a7c-a386-be0be48ae4e2","providers":[{"namespace":"Microsoft.ContainerRegistry","resourceTypes":[{"resourceType":"registries/tasks","locations":["eastus"]}]},{"namespace":"Microsoft.Authorization","resourceTypes":[{"resourceType":"roleAssignments","locations":[null]}]}],"dependencies":[{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-scan-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-scan-image","apiVersion":"2019-06-01-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe","resourceType":"Microsoft.Authorization/roleAssignments","resourceName":"6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"},{"dependsOn":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-trigger-workflow"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","resourceType":"Microsoft.ContainerRegistry/registries/tasks","resourceName":"clireg000002/cssc-trigger-workflow","apiVersion":"2019-06-01-preview"}],"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6","resourceType":"Microsoft.Authorization/roleAssignments","resourceName":"c40df73a-b6a5-5458-a0a5-dc5aa98facc6"}],"outputResources":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow"}]}}' + headers: + cache-control: + - no-cache + content-length: + - '15751' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:05 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 3AAC140936D64A16A10CAAEABD938FFB Ref B: MWH011020809025 Ref C: 2025-04-22T21:55:06Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow list + Connection: + - keep-alive + ParameterSetName: + - -r -g -t + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-01-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Succeeded","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2023-01-01-preview + cache-control: + - no-cache + content-length: + - '1369' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:06 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 6B295CB0C1404B59A4B4B5B4E95BA718 Ref B: MWH011020809042 Ref C: 2025-04-22T21:55:06Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow list + Connection: + - keep-alive + ParameterSetName: + - -r -g -t + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.0725326+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI=","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image","name":"cssc-patch-image","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0161883+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '4141' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:07 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 397DBCC761B54A57A8CD7399A1FA2287 Ref B: CO6AA3150220039 Ref C: 2025-04-22T21:55:07Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow list + Connection: + - keep-alive + ParameterSetName: + - -r -g -t + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"bf3cc95b-2385-4201-97fc-6244ff57c814","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.6313971+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","name":"cssc-scan-image","tags":{"cssc":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0318135+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0318135+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5107' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:08 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: D3C13A8D131B4ED1AC74E9001DD13B13 Ref B: CO6AA3150220039 Ref C: 2025-04-22T21:55:07Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow list + Connection: + - keep-alive + ParameterSetName: + - -r -g -t + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"2b92364e-0017-4a35-a4c6-12936548d247","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.615486+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"trigger":{"timerTriggers":[{"schedule":"54 + 21 */7 * *","status":"Enabled","name":"azcli_defined_schedule"}]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","name":"cssc-trigger-workflow","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0161883+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5396' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:08 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 4856EB4A5B3D4F45BB2D8BE3B42C3436 Ref B: CO6AA3150220039 Ref C: 2025-04-22T21:55:08Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/vnd.oci.image.manifest.v1+json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/manifests/v1 + response: + body: + string: '{"errors":[{"code":"UNAUTHORIZED","message":"authentication required, + visit https://aka.ms/acr/authorization for more information.","detail":[{"Type":"repository","Name":"csscpolicies/patchpolicy","Action":"pull"}]}]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '218' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:11 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://cliregrutwpbbvyhtugt.azurecr.io/oauth2/token",service="cliregrutwpbbvyhtugt.azurecr.io",scope="repository:csscpolicies/patchpolicy:pull",error="malformed_token" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Service: + - cliregrutwpbbvyhtugt.azurecr.io + User-Agent: + - oras-py + method: GET + uri: https://clireg000002.azurecr.io/oauth2/token?service=clireg000002.azurecr.io&scope=repository%3Acsscpolicies%2Fpatchpolicy%3Apull + response: + body: + string: '{"access_token":"***","refresh_token":"***"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:11 GMT + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '166.6' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/vnd.oci.image.manifest.v1+json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/manifests/v1 + response: + body: + string: '{"schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", + "config": {"mediaType": "application/vnd.unknown.config.v1+json", "size": + 2, "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}, + "layers": [{"mediaType": "application/vnd.oci.image.layer.v1.tar", "size": + 233, "digest": "sha256:0b061a62bdaf0be5c085634ee969a2e378b7d09cd8c794674ebcd26d48a20287", + "annotations": {"org.opencontainers.image.title": "cssc_config_tmp_nncoqvqf"}}], + "annotations": {}}' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '507' + content-type: + - application/vnd.oci.image.manifest.v1+json + date: + - Tue, 22 Apr 2025 21:55:12 GMT + docker-content-digest: + - sha256:7f35b408122f42636a4b7a063bf2f678aba6b0122d0242c8e4e5c11b17d30ffd + docker-distribution-api-version: + - registry/2.0 + etag: + - '"sha256:7f35b408122f42636a4b7a063bf2f678aba6b0122d0242c8e4e5c11b17d30ffd"' + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/csscpolicies/patchpolicy/blobs/sha256:0b061a62bdaf0be5c085634ee969a2e378b7d09cd8c794674ebcd26d48a20287 + response: + body: + string: '= 1.1.0, please see https://aka.ms/acr/tasks/task-aliases for + more information.\n2025/04/22 21:55:25 Creating Docker network: acb_default_network, + driver: 'bridge'\n2025/04/22 21:55:25 Successfully set up Docker network: + acb_default_network\n2025/04/22 21:55:25 Setting up Docker configuration...\n2025/04/22 + 21:55:25 Successfully set up Docker configuration\n2025/04/22 21:55:25 Logging + in to registry: clireg000002.azurecr.io\n2025/04/22 21:55:26 Successfully + logged into clireg000002.azurecr.io\n2025/04/22 21:55:26 Executing step ID: + acr-cli-filter. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'\n2025/04/22 + 21:55:26 Launching container with name: acr-cli-filter\n2025/04/22 21:55:27 + Successfully executed container: acr-cli-filter\n2025/04/22 21:55:27 Executing + step ID: acb_step_1. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'\n2025/04/22 + 21:55:27 Launching container with name: acb_step_1\nDRY RUN mode enabled...\nDRY + RUN mode will only list all the repositories and tags that match the filter + and are eligible for continuous scan and patch. During the actual patch operation, + each of the eligible images will first be scanned using trivy and if there + are any vulnerabilities found, a new patched image will be generated with + tag -patched or -x based on the configured tag-convention.\nReading + filter from filter file path...\nValidating filter...\nConfigured Tag Convention: + \ incremental\nArtifacts specified in the filter that do not exist:\nRepo,Tag\nalpine,*\nNot + found: 1\nNo matching repository and tag found!\nMatches found: 0\r\n2025/04/22 + 21:55:27 Successfully executed container: acb_step_1\n2025/04/22 21:55:27 + Step ID: acr-cli-filter marked as successful (elapsed time in seconds: 0.581848)\n2025/04/22 + 21:55:27 Step ID: acb_step_1 marked as successful (elapsed time in seconds: + 0.490031)\n\r\nRun ID: ca2 was successful after 4s\r\n" + headers: + accept-ranges: + - bytes + content-disposition: + - '' + content-encoding: + - utf-8 + content-length: + - '2060' + content-range: + - bytes 0-2075/2076 + content-type: + - text/plain; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:28 GMT + etag: + - '"0x8DD81E864BA075E"' + last-modified: + - Tue, 22 Apr 2025 21:55:27 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-blob-committed-block-count: + - '5' + x-ms-blob-type: + - AppendBlob + x-ms-creation-time: + - Tue, 22 Apr 2025 21:55:24 GMT + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-meta-complete: + - successful + x-ms-server-encrypted: + - 'true' + x-ms-version: + - '2022-11-02' + status: + code: 206 + message: Partial Content +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow update + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.0725326+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI=","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image","name":"cssc-patch-image","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0161883+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '4141' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:28 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: DE47CB93C6934D4F8F73E0AF651121E3 Ref B: MWH011020809052 Ref C: 2025-04-22T21:55:28Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow update + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"bf3cc95b-2385-4201-97fc-6244ff57c814","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.6313971+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","name":"cssc-scan-image","tags":{"cssc":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0318135+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0318135+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5107' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:28 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 7524BD4E3E9F44E1AE40979DF0C35562 Ref B: MWH011020809052 Ref C: 2025-04-22T21:55:29Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow update + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"2b92364e-0017-4a35-a4c6-12936548d247","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.615486+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"trigger":{"timerTriggers":[{"schedule":"54 + 21 */7 * *","status":"Enabled","name":"azcli_defined_schedule"}]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","name":"cssc-trigger-workflow","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0161883+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5396' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:29 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: D550A10691C54DA39F6806F54679C15C Ref B: MWH011020809052 Ref C: 2025-04-22T21:55:29Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"trigger": {"timerTriggers": [{"schedule": "55 21 */14 + * *", "name": "azcli_defined_schedule"}]}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow update + Connection: + - keep-alive + Content-Length: + - '114' + Content-Type: + - application/json + ParameterSetName: + - -r -g -t --schedule + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: PATCH + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"2b92364e-0017-4a35-a4c6-12936548d247","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.615486+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"trigger":{"timerTriggers":[{"schedule":"55 + 21 */14 * *","status":"Enabled","name":"azcli_defined_schedule"}]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","name":"cssc-trigger-workflow","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:55:30.4483201+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:30 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/5c5afaf9-dff0-4453-a804-18ff93351513 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 51F15B4EECD744D18E52B2DC35AA16B3 Ref B: CO6AA3150218029 Ref C: 2025-04-22T21:55:30Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-01-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Succeeded","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2023-01-01-preview + cache-control: + - no-cache + content-length: + - '1369' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:30 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 725B83291549475B9807FC7FFA890E26 Ref B: MWH011020809042 Ref C: 2025-04-22T21:55:31Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.0725326+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI=","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image","name":"cssc-patch-image","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0161883+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '4141' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:31 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 5ECC662C554A4E8EA0AB2F7ABF84B0AE Ref B: CO6AA3150218053 Ref C: 2025-04-22T21:55:31Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"bf3cc95b-2385-4201-97fc-6244ff57c814","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.6313971+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","name":"cssc-scan-image","tags":{"cssc":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0318135+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0318135+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5107' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:31 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 1B956CD5F6804CA898DE53523EC5810D Ref B: CO6AA3150218053 Ref C: 2025-04-22T21:55:31Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"2b92364e-0017-4a35-a4c6-12936548d247","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.615486+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"trigger":{"timerTriggers":[{"schedule":"55 + 21 */14 * *","status":"Enabled","name":"azcli_defined_schedule"}]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","name":"cssc-trigger-workflow","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:55:30.4483201+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:32 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: DF46E53C89B4417DA32D02269F00FAD4 Ref B: CO6AA3150218053 Ref C: 2025-04-22T21:55:32Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resources?$filter=resourceType%20eq%20%27Microsoft.ContainerRegistry%2Fregistries%27&api-version=2022-09-01 + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graybugbash","name":"graybugbash","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus3","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2024-07-02T22:12:00.2729923Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2024-07-02T22:12:00.2729923Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graycsscsec","name":"graycsscsec","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"swedencentral","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2024-09-10T17:32:40.0833148Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-10T00:08:28.5420628Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/csscbugbash2/providers/Microsoft.ContainerRegistry/registries/graybugbash2","name":"graybugbash2","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-03-28T17:03:34.0143535Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-03-28T17:03:34.0143535Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graycsscemptytoken","name":"graycsscemptytoken","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus2","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-02T18:21:07.0460694Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-02T18:21:07.0460694Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graybasic","name":"graybasic","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Basic","tier":"Basic"},"location":"westus2","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-09T23:42:34.4937063Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-09T23:42:34.4937063Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/grayeus2euap","name":"grayeus2euap","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus2euap","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2022-10-06T16:30:06.2025526Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2022-10-06T16:34:13.6789203Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graywus2","name":"graywus2","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus2","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2022-06-15T23:36:48.7494742Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-05-08T20:13:10.5096692Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '4245' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:35 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 2908B90A6CE24A2CB055FDAD48E01431 Ref B: MWH011020808025 Ref C: 2025-04-22T21:55:35Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-11-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Succeeded","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled"}}' + headers: + api-supported-versions: + - 2023-11-01-preview + cache-control: + - no-cache + content-length: + - '1397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:35 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 1A543D8F12664D2A9B5D30075B896FEB Ref B: MWH011020808034 Ref C: 2025-04-22T21:55:35Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/ + response: + body: + string: '{"errors":[{"code":"UNAUTHORIZED","message":"authentication required, + visit https://aka.ms/acr/authorization for more information.","detail":null}]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '149' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:36 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://cliregrutwpbbvyhtugt.azurecr.io/oauth2/token",service="cliregrutwpbbvyhtugt.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/ + response: + body: + string: '{"errors":[{"code":"UNAUTHORIZED","message":"authentication required, + visit https://aka.ms/acr/authorization for more information.","detail":null}]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '149' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:36 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://cliregrutwpbbvyhtugt.azurecr.io/oauth2/token",service="cliregrutwpbbvyhtugt.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: service=cliregrutwpbbvyhtugt.azurecr.io&grant_type=password&username=00000000-0000-0000-0000-000000000000&password=***&scope=repository%3Acsscpolicies%2Fpatchpolicy%3Ametadata_read + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '1339' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.32.3 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/token + response: + body: + string: '{"access_token":"***","refresh_token":"***"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:36 GMT + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '166.616667' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/acr/v1/csscpolicies/patchpolicy + response: + body: + string: '{"registry":"clireg000002.azurecr.io","imageName":"csscpolicies/patchpolicy","createdTime":"2025-04-22T21:54:33.0512957Z","lastUpdateTime":"2025-04-22T21:54:33.1677403Z","manifestCount":1,"tagCount":1,"changeableAttributes":{"deleteEnabled":true,"writeEnabled":true,"readEnabled":true,"listEnabled":true}} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '306' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:37 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/runs?api-version=2019-06-01-preview&$filter=TaskName%20in%20%28%27cssc-trigger-workflow%27%2C%20%27cssc-scan-image%27%2C%20%27cssc-patch-image%27%29%20and%20Status%20in%20%28%27Running%27%2C%20%27Queued%27%2C%20%27Started%27%29&$top=1000 + response: + body: + string: '{"value":[]}' + headers: + cache-control: + - no-cache + content-length: + - '12' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:36 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/9a2b3a84-e14f-45a8-b7dd-c29161672849 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: A3CC5C3204ED41BEBA80EBE5DDCB4001 Ref B: MWH011020809052 Ref C: 2025-04-22T21:55:37Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.0725326+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5SZXBvcnQgOiBvcy12dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV97eyByZWdleFJlcGxhY2VBbGwgIlteYS16QS1aMC05XSIgLlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWSAiLSIgfX1fe3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fV8kKGRhdGUgIislWS0lbS0lZCIpLmpzb24NCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0Kc3RlcHM6DQogIC0gaWQ6IHByaW50LWlucHV0cw0KICAgIGNtZDogfA0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyBPUyB2dWxuZXJhYmlsaXRpZXMgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0iJw0KICAgICAgICBiYXNoIC1jICdlY2hvICJQYXRjaGluZyByZXBvOiB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fSwgVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIE5ld1BhdGNoVGFnOnt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iJw0KDQogIC0gaWQ6IGNoZWNrLXBhdGNoLXRhZw0KICAgIGNtZDogfA0KICAgICAgIGJhc2ggLWMgJ2VjaG8gIk5ldyBQYXRjaCB0YWcgaXMge3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSINCiAgICAgICBpZiBbICJ7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319IiAhPSAicGF0Y2hlZCIgXSAmJiBbIHt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLWd0IDk5OSBdOyB0aGVuDQogICAgICAgICAgZWNobyAiTmV3IFBhdGNoIHRhZyBpcyBncmVhdGVyIHRoYW4gOTk5LiBObyBtb3JlIHRoYW4gMTAwMCBwYXRjaGVzIGNhbiBiZSBjcmVhdGVkIGZvciBhIHRhZy4gRXhpdGluZyB0aGUgcGF0Y2hpbmcgd29ya2Zsb3cuIg0KICAgICAgICAgIGV4aXQgMQ0KICAgICAgIGZpJw0KDQogIC0gaWQ6IHNldHVwLWRhdGEtZGlyDQogICAgY21kOiBiYXNoIG1rZGlyIC4vZGF0YQ0KICAtIGlkOiBnZW5lcmF0ZS10cml2eS1yZXBvcnQNCiAgICByZXRyaWVzOiAzDQogICAgcmV0cnlEZWxheTogNQ0KICAgIHRpbWVvdXQ6IDE4MDANCiAgICBjbWQ6IHwNCiAgICAgIGNzc2MgdHJpdnkgaW1hZ2UgXA0KICAgICAge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSBcDQogICAgICAtLXBrZy10eXBlcyBvcyBcDQogICAgICAtLWlnbm9yZS11bmZpeGVkIFwNCiAgICAgIC0tZm9ybWF0IGpzb24gXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLXNjYW5uZXJzIHZ1bG4gXA0KICAgICAgLS1kYi1yZXBvc2l0b3J5ICJnaGNyLmlvL2FxdWFzZWN1cml0eS90cml2eS1kYjoyIiwicHVibGljLmVjci5hd3MvYXF1YXNlY3VyaXR5L3RyaXZ5LWRiIiBcDQogICAgICAtLW91dHB1dCAvd29ya3NwYWNlL2RhdGEvJFNjYW5SZXBvcnQNCg0KICAtIGlkOiBidWlsZGtpdGQNCiAgICBjbWQ6IG1vYnlidWlsZGtpdCAtLWFkZHIgdGNwOi8vMC4wLjAuMDo4ODg4DQogICAgZW50cnlwb2ludDogYnVpbGRraXRkDQogICAgZGV0YWNoOiB0cnVlDQogICAgcHJpdmlsZWdlZDogdHJ1ZQ0KICAgIHBvcnRzOiBbIjEyNy4wLjAuMTo4ODg4Ojg4ODgvdGNwIl0NCg0KICAtIGlkOiBwYXRjaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgY3NzYyBjb3BhIHBhdGNoIFwNCiAgICAgIC1pICJ7ey5SdW4uUmVnaXN0cnl9fS97ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IiBcDQogICAgICAtciAuL2RhdGEvJFNjYW5SZXBvcnQgXA0KICAgICAgLXQgInt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSIgXA0KICAgICAgLS10aW1lb3V0IDMwbSBcDQogICAgICAtLWFkZHIgdGNwOi8vMTI3LjAuMC4xOjg4ODgNCiAgICBuZXR3b3JrOiBob3N0DQoNCiAgLSBpZDogcHVzaC1pbWFnZQ0KICAgIHJldHJpZXM6IDMNCiAgICByZXRyeURlbGF5OiA1DQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogZG9ja2VyIHB1c2gge3suUnVuLlJlZ2lzdHJ5fX0ve3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fS17ey5WYWx1ZXMuU09VUkNFX0lNQUdFX05FV1BBVENIX1RBR319DQogIC0gY21kOiBiYXNoIGVjaG8gIlBhdGNoZWQgaW1hZ2UgcHVzaGVkIHRvIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0te3suVmFsdWVzLlNPVVJDRV9JTUFHRV9ORVdQQVRDSF9UQUd9fSI=","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image","name":"cssc-patch-image","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0161883+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '4141' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:37 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 0B45D57269B14FCBA2DE224AE5065CD6 Ref B: MWH011020806054 Ref C: 2025-04-22T21:55:37Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-patch-image?api-version=2019-06-01-preview + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:55:38 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/dc087108-c684-4407-a4fc-58955acdf829 + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: 8704252F83FD4BCF8DDABD120662291F Ref B: MWH011020806054 Ref C: 2025-04-22T21:55:38Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"bf3cc95b-2385-4201-97fc-6244ff57c814","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.6313971+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIHBhdGNoaW1hZ2V0YXNrOiBjc3NjLXBhdGNoLWltYWdlDQogICAgREFURTogJChkYXRlICIrJVktJW0tJWQiKQ0KICAgIGNzc2MgOiBtY3IubWljcm9zb2Z0LmNvbS9hY3IvY3NzYzpjYmNmNjkyDQpzdGVwczoNCiAgLSBpZDogcHJpbnQtaW5wdXRzDQogICAgY21kOiB8DQogICAgICAgIGJhc2ggLWMgJ2VjaG8gIlNjYW5uaW5nIGltYWdlIGZvciB2dWxuZXJhYmlsaXR5IHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gZm9yIHRhZyB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiU2Nhbm5pbmcgcmVwbzoge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX0sIFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319LCBPcmlnaW5hbFRhZzp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319IicNCiAgLSBpZDogc2V0dXAtZGF0YS1kaXINCiAgICBjbWQ6IGJhc2ggbWtkaXIgLi9kYXRhDQoNCiAgLSBpZDogZ2VuZXJhdGUtdHJpdnktcmVwb3J0DQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDUNCiAgICB0aW1lb3V0OiAxODAwDQogICAgY21kOiB8DQogICAgICBjc3NjIHRyaXZ5IGltYWdlIFwNCiAgICAgIHt7LlJ1bi5SZWdpc3RyeX19L3t7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gXA0KICAgICAgLS1wa2ctdHlwZXMgb3MgXA0KICAgICAgLS1pZ25vcmUtdW5maXhlZCBcDQogICAgICAtLWZvcm1hdCBqc29uIFwNCiAgICAgIC0tdGltZW91dCAzMG0gXA0KICAgICAgLS1zY2FubmVycyB2dWxuIFwNCiAgICAgIC0tZGItcmVwb3NpdG9yeSAiZ2hjci5pby9hcXVhc2VjdXJpdHkvdHJpdnktZGI6MiIsInB1YmxpYy5lY3IuYXdzL2FxdWFzZWN1cml0eS90cml2eS1kYiIgXA0KICAgICAgLS1vdXRwdXQgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24NCg0KICAtIGNtZDogY3NzYyBqcSAnaWYgLlJlc3VsdHMgPT0gbnVsbCBvciAoLlJlc3VsdHMgfCBsZW5ndGgpID09IDAgdGhlbiAwIGVsc2UgWy5SZXN1bHRzW10gfCBzZWxlY3QoLlZ1bG5lcmFiaWxpdGllcyAhPSBudWxsKSB8IC5WdWxuZXJhYmlsaXRpZXMgfCBsZW5ndGhdIHwgYWRkIGVuZCcgL3dvcmtzcGFjZS9kYXRhL3Z1bG5lcmFiaWxpdHktcmVwb3J0X3RyaXZ5XyREQVRFLmpzb24gPiAvd29ya3NwYWNlL2RhdGEvdnVsQ291bnQudHh0DQogIC0gY21kOiBjc3NjIGpxICdpZiAuTWV0YWRhdGEuT1MuRU9TTCA9PSBudWxsIHRoZW4gZmFsc2UgZWxzZSAuTWV0YWRhdGEuT1MuRU9TTCBlbmQnIC93b3Jrc3BhY2UvZGF0YS92dWxuZXJhYmlsaXR5LXJlcG9ydF90cml2eV8kREFURS5qc29uID4gL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0DQogIC0gY21kOiB8ICAgICAgICANCiAgICAgICAgYmFzaCAtYyAnZWNobyAiVnVsbmVyYWJpbGl0aWVzIGZvdW5kIGZvciBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IC0+ICQoY2F0IC93b3Jrc3BhY2UvZGF0YS92dWxDb3VudC50eHQpIicNCiAgICAgICAgYmFzaCAtYyAnZWNobyAiRU9TTCBmb3IgdGhlIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0gLT4gJChjYXQgL3dvcmtzcGFjZS9kYXRhL2Vvc2wudHh0KSInDQoNCiAgLSBpZDogdHJpZ2dlci1wYXRjaC10YXNrDQogICAgcmV0cmllczogMw0KICAgIHJldHJ5RGVsYXk6IDEwDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgYXogLWMgJw0KICAgICAgdnVsQ291bnQ9JChjYXQgL3dvcmtzcGFjZS9kYXRhL3Z1bENvdW50LnR4dCkgJiYgXA0KICAgICAgZW9zbFZhbHVlPSQoY2F0IC93b3Jrc3BhY2UvZGF0YS9lb3NsLnR4dCkgJiYgXA0KICAgICAgaWYgISBbWyAiJHZ1bENvdW50IiA9fiBeWzAtOV0rJCBdXTsgdGhlbiB2dWxDb3VudD0wOyBmaSAmJiBcDQogICAgICBpZiBbICIkZW9zbFZhbHVlIiA9ICJ0cnVlIiBdOyB0aGVuIFwNCiAgICAgICAgZWNobyAiUEFUQ0hJTkcgd2lsbCBiZSBza2lwcGVkIGFzIEVPU0wgaXMgJGVvc2xWYWx1ZSBmb3IgaW1hZ2Uge3suVmFsdWVzLlNPVVJDRV9SRVBPU0lUT1JZfX06e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9UQUd9fSI7IFwNCiAgICAgIGVsaWYgWyAkdnVsQ291bnQgLWd0IDAgXTsgdGhlbiBcDQogICAgICAgICAgYXogbG9naW4gLS1pZGVudGl0eTsgXA0KICAgICAgICAgIGVjaG8gIlRvdGFsIE9TIHZ1bG5lcmFiaWxpdGllcyBmb3VuZCAtPiAkdnVsQ291bnQiOyBcDQogICAgICAgICAgZWNobyAiUEFUQ0hJTkcgdGFzayBzY2hlZHVsZWQgZm9yIGltYWdlIHt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19Ont7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfVEFHfX0sIG5ldyBwYXRjaCB0YWcgd2lsbCBiZSB7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX09SSUdJTkFMX1RBR319LXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0iOyBcDQogICAgICAgICAgYXogYWNyIHRhc2sgcnVuIC0tbmFtZSAkcGF0Y2hpbWFnZXRhc2sgLS1yZWdpc3RyeSAkUmVnaXN0cnlOYW1lIC0tc2V0IFNPVVJDRV9SRVBPU0lUT1JZPXt7LlZhbHVlcy5TT1VSQ0VfUkVQT1NJVE9SWX19IC0tc2V0IFNPVVJDRV9JTUFHRV9UQUc9e3suVmFsdWVzLlNPVVJDRV9JTUFHRV9PUklHSU5BTF9UQUd9fSAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPXt7LlZhbHVlcy5TT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHfX0gLS1uby13YWl0OyBcDQogICAgICAgIGVsc2UgXA0KICAgICAgICAgIGVjaG8gIlBBVENISU5HIHdpbGwgYmUgc2tpcHBlZCBhcyBubyB2dWxuZXJhYmlsaXR5IGZvdW5kIGluIHRoZSBpbWFnZSB7ey5WYWx1ZXMuU09VUkNFX1JFUE9TSVRPUll9fTp7ey5WYWx1ZXMuU09VUkNFX0lNQUdFX1RBR319IjsgXA0KICAgICAgZmknDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image","name":"cssc-scan-image","tags":{"cssc":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0318135+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:54:38.0318135+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5107' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:39 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 1451ED274B2C4D889D472221FFFBD221 Ref B: CO6AA3150220051 Ref C: 2025-04-22T21:55:39Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments?$filter=principalId%20eq%20'bf3cc95b-2385-4201-97fc-6244ff57c814'&api-version=2022-04-01 + response: + body: + string: '{"value":[{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/fb382eab-e894-4461-af04-94435c366c3f","principalId":"bf3cc95b-2385-4201-97fc-6244ff57c814","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","condition":null,"conditionVersion":null,"createdOn":"2025-04-22T21:54:42.1959968Z","updatedOn":"2025-04-22T21:54:42.1959968Z","createdBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","updatedBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe","type":"Microsoft.Authorization/roleAssignments","name":"6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"}]}' + headers: + cache-control: + - no-cache + content-length: + - '1057' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:39 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/3e0ded3d-f8d4-49ac-9d40-aec19a0ad3f5 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: FF815C9E136E41589CFC39CF8559F450 Ref B: CO6AA3150217027 Ref C: 2025-04-22T21:55:39Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe?api-version=2022-04-01 + response: + body: + string: '{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/fb382eab-e894-4461-af04-94435c366c3f","principalId":"bf3cc95b-2385-4201-97fc-6244ff57c814","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","condition":null,"conditionVersion":null,"createdOn":"2025-04-22T21:54:42.1959968Z","updatedOn":"2025-04-22T21:55:40.7734243Z","createdBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","updatedBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe","type":"Microsoft.Authorization/roleAssignments","name":"6e4d47fa-a1f3-56ff-85aa-45eb4f49b1fe"}' + headers: + cache-control: + - no-cache + content-length: + - '1045' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:43 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/355d2d1a-d713-483c-81b9-362510507ea2 + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: 02CA46C57CC343118D688A3D71118521 Ref B: CO6AA3150217027 Ref C: 2025-04-22T21:55:40Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-scan-image?api-version=2019-06-01-preview + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:55:44 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/13bbcbe4-550b-405b-92ec-c5e64c6dfddc + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: EA2B70AEE9E34462A00A1B6D68292927 Ref B: CO6AA3150220051 Ref C: 2025-04-22T21:55:43Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tasks","identity":{"principalId":"2b92364e-0017-4a35-a4c6-12936548d247","tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","type":"SystemAssigned"},"properties":{"provisioningState":"Succeeded","creationDate":"2025-04-22T21:54:38.615486+00:00","status":"Enabled","platform":{"os":"linux","architecture":"amd64"},"agentConfiguration":{"cpu":2},"timeout":3600,"step":{"type":"EncodedTask","encodedTaskContent":"dmVyc2lvbjogdjEuMS4wDQphbGlhczoNCiAgdmFsdWVzOg0KICAgIFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrOiBjc3NjLXNjYW4taW1hZ2UNCiAgICBjc3NjIDogbWNyLm1pY3Jvc29mdC5jb20vYWNyL2Nzc2M6Y2JjZjY5Mg0KICAgIG1heExpbWl0OiAxMDANCnN0ZXBzOg0KICAtIGNtZDogYmFzaCAtYyAnZWNobyAiSW5zaWRlIGNzc2MtdHJpZ2dlci13b3JrZmxvdyB0YXNrLCBnZXR0aW5nIGxpc3Qgb2YgaW1hZ2VzIHRvIGJlIHBhdGNoZWQgYmFzZWQgb24gLS1maWx0ZXItcG9saWN5IGZvciBSZWdpc3RyeSB7ey5SdW4uUmVnaXN0cnl9fS4iJw0KICAtIGNtZDogY3NzYyBhY3IgY3NzYyBwYXRjaCAtLWZpbHRlci1wb2xpY3kgY3NzY3BvbGljaWVzL3BhdGNocG9saWN5OnYxIC0tZHJ5LXJ1biA+IGZpbHRlclJlcG9zLnR4dA0KICAgIGVudjoNCiAgICAgIC0gQUNSX0VYUEVSSU1FTlRBTF9DU1NDPXRydWUNCiAgLSBjbWQ6IGJhc2ggLWMgJ3NlZCAtbiAiL15WYWxpZGF0aW5nLywvXlRvdGFsLyB7L15WYWxpZGF0aW5nL2I7L15Ub3RhbC9iO3B9IiBmaWx0ZXJSZXBvcy50eHQnID4gZmlsdGVyUmVwb3NUb0Rpc3BsYXkudHh0DQogIC0gY21kOiB8DQogICAgICBiYXNoIC1jICcNCiAgICAgIGVjaG8gIkJlbG93IGltYWdlcyB3aWxsIGJlIHNjYW5uZWQgYW5kIHBhdGNoZWQgKGlmIGFueSBvcyB2dWxuZXJhYmlsaXRpZXMgZm91bmQpIGJhc2VkIG9uIC0tZmlsdGVyLXBvbGljeS5cbiQoY2F0IGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCkiDQogICAgICB0b3RhbEltYWdlcz0kKHNlZCAtbiAicy9eTWF0Y2hlcyBmb3VuZDovL3AiIGZpbHRlclJlcG9zVG9EaXNwbGF5LnR4dCB8IHRyIC1kICJbOnNwYWNlOl0iKQ0KICAgICAgaWYgWyAkdG90YWxJbWFnZXMgLWd0ICRtYXhMaW1pdCBdOyB0aGVuDQogICAgICAgIGVjaG8gIllvdSBoYXZlIGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0IG9mICRtYXhMaW1pdCBpbWFnZXMgdGhhdCBjYW4gYmUgc2NoZWR1bGVkIGZvciBjb250aW51b3VzIHBhdGNoaW5nLiBBZGp1c3QgdGhlIEpTT04gZmlsdGVyIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgaW1hZ2VzLiBGYWlsaW5nIHRoZSB3b3JrZmxvdy4iDQogICAgICAgIGV4aXQgMQ0KICAgICAgZmknDQogIC0gY21kOiBjc3NjIGFjciBjc3NjIHBhdGNoIC0tZmlsdGVyLXBvbGljeSBjc3NjcG9saWNpZXMvcGF0Y2hwb2xpY3k6djEgLS1zaG93LXBhdGNoLXRhZ3MgLS1kcnktcnVuPiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0DQogICAgZW52Og0KICAgICAgLSBBQ1JfRVhQRVJJTUVOVEFMX0NTU0M9dHJ1ZQ0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkxpc3RpbmcvLC9eTWF0Y2hlcy8gey9eTGlzdGluZy9iOy9eTWF0Y2hlcy9iOy9eUmVwby9iO3B9IiBmaWx0ZXJSZXBvc1dpdGhQYXRjaFRhZ3MudHh0JyA+IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dA0KICAtIGNtZDogYmFzaCAtYyAnc2VkIC1uICIvXkNvbmZpZ3VyZWQgVGFnIENvbnZlbnRpb246L3AiIGZpbHRlclJlcG9zV2l0aFBhdGNoVGFncy50eHQnID4gdGFnQ29udmVudGlvbi50eHQNCiAgLSBjbWQ6IGF6IGxvZ2luIC0taWRlbnRpdHkgDQogIC0gaWQ6IHNjYW4tYW5kLXNjaGVkdWxlLXBhdGNoDQogICAgdGltZW91dDogMTgwMA0KICAgIGNtZDogfA0KICAgICAgICBheiAtYyAnDQogICAgICAgIGNvdW50ZXI9MDsgXA0KICAgICAgICBiYXRjaFNpemU9MTA7IFwNCiAgICAgICAgc2xlZXBEdXJhdGlvbj0zMDsgXA0KICAgICAgICBSZWdpc3RyeU5hbWU9e3suUnVuLlJlZ2lzdHJ5fX07IFwNCiAgICAgICAgd2hpbGUgcmVhZCBsaW5lO2RvIFwNCiAgICAgICAgSUZTPScsJyByZWFkIC1yIC1hIGFycmF5IDw8PCAiJHtsaW5lfSINCiAgICAgICAgUmVwb05hbWU9JHthcnJheVswXX0NCiAgICAgICAgT3JpZ2luYWxUYWc9JHthcnJheVsxXX0NCiAgICAgICAgVGFnTmFtZT0ke2FycmF5WzJdfQ0KICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0iIg0KICAgICAgICBlY2hvICJUYWcgQ29udmVudGlvbiBkZXRhaWxzOiAkKGNhdCB0YWdDb252ZW50aW9uLnR4dCkiDQogICAgICAgIGlmIGdyZXAgLXEgImZsb2F0aW5nIiB0YWdDb252ZW50aW9uLnR4dDsgdGhlbg0KICAgICAgICAgIEluY3JlbWVudGVkVGFnTnVtYmVyPSJwYXRjaGVkIg0KICAgICAgICBlbHNlDQogICAgICAgICAgSW5jcmVtZW50ZWRUYWdOdW1iZXI9IjEiDQogICAgICAgIGZpDQoNCiAgICAgICAgaWYgWyAkVGFnTmFtZSA9PSAiTi9BIiBdOyB0aGVuDQogICAgICAgICAgVGFnTmFtZT0kT3JpZ2luYWxUYWcNCiAgICAgICAgZWxpZiBbWyAkVGFnTmFtZSA9fiAtKFswLTldezEsM30pJCBdXTsgdGhlbg0KICAgICAgICAgIFRhZ051bWJlcj0ke0JBU0hfUkVNQVRDSFsxXX0NCiAgICAgICAgICBJbmNyZW1lbnRlZFRhZ051bWJlcj0kKChUYWdOdW1iZXIrMSkpDQogICAgICAgIGZpDQogICAgICAgIGVjaG8gIlNjaGVkdWxpbmcgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIGZvciAkUmVnaXN0cnlOYW1lLyRSZXBvTmFtZSwgVGFnOiRUYWdOYW1lLCBPcmlnaW5hbFRhZzokT3JpZ2luYWxUYWcsIFBhdGNoVGFnOiRPcmlnaW5hbFRhZy0kSW5jcmVtZW50ZWRUYWdOdW1iZXIiOyBcDQogICAgICAgIGF6IGFjciB0YXNrIHJ1biAtLW5hbWUgJFNjYW5JbWFnZUFuZFNjaGVkdWxlUGF0Y2hUYXNrIC0tcmVnaXN0cnkgJFJlZ2lzdHJ5TmFtZSAtLXNldCBTT1VSQ0VfUkVQT1NJVE9SWT0kUmVwb05hbWUgLS1zZXQgU09VUkNFX0lNQUdFX1RBRz0kVGFnTmFtZSAtLXNldCBTT1VSQ0VfSU1BR0VfT1JJR0lOQUxfVEFHPSRPcmlnaW5hbFRhZyAtLXNldCBTT1VSQ0VfSU1BR0VfTkVXUEFUQ0hfVEFHPSRJbmNyZW1lbnRlZFRhZ051bWJlciAtLW5vLXdhaXQ7IFwNCiAgICAgICAgY291bnRlcj0kKChjb3VudGVyKzEpKTsgXA0KICAgICAgICBpZiBbICQoKGNvdW50ZXIlYmF0Y2hTaXplKSkgLWVxIDAgXTsgdGhlbiBcDQogICAgICAgICAgZWNobyAiV2FpdGluZyBmb3IgJHNsZWVwRHVyYXRpb24gc2Vjb25kcyBiZWZvcmUgc2NoZWR1bGluZyBzY2FucyBmb3IgbmV4dCBiYXRjaCBvZiBpbWFnZXMiOyBcDQogICAgICAgICAgc2xlZXAgJHNsZWVwRHVyYXRpb247IFwNCiAgICAgICAgZmk7IFwNCiAgICAgICAgZG9uZSA8IGZpbHRlcmVkUmVwb3NBbmRUYWdzLnR4dDsnDQogICAgZW50cnlQb2ludDogL2Jpbi9iYXNo","values":[]},"trigger":{"timerTriggers":[{"schedule":"55 + 21 */14 * *","status":"Enabled","name":"azcli_defined_schedule"}]},"isSystemTask":false},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow","name":"cssc-trigger-workflow","tags":{"cssc":"true","clienttracking":"true"},"location":"eastus","systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:54:38.0161883+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:55:30.4483201+00:00"}}' + headers: + cache-control: + - no-cache + content-length: + - '5397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:44 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 9835E06FFA34475FB6ACB03CF52B87FB Ref B: MWH011020807036 Ref C: 2025-04-22T21:55:44Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments?$filter=principalId%20eq%20'2b92364e-0017-4a35-a4c6-12936548d247'&api-version=2022-04-01 + response: + body: + string: '{"value":[{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/fb382eab-e894-4461-af04-94435c366c3f","principalId":"2b92364e-0017-4a35-a4c6-12936548d247","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","condition":null,"conditionVersion":null,"createdOn":"2025-04-22T21:54:42.4610522Z","updatedOn":"2025-04-22T21:54:42.4610522Z","createdBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","updatedBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6","type":"Microsoft.Authorization/roleAssignments","name":"c40df73a-b6a5-5458-a0a5-dc5aa98facc6"}]}' + headers: + cache-control: + - no-cache + content-length: + - '1057' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:45 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/3d5bb66f-0e08-4884-9279-d5bcf2e6c0d8 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 917C0274728F4AC68C5271609B4522E5 Ref B: MWH011020808029 Ref C: 2025-04-22T21:55:45Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6?api-version=2022-04-01 + response: + body: + string: '{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/fb382eab-e894-4461-af04-94435c366c3f","principalId":"2b92364e-0017-4a35-a4c6-12936548d247","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","condition":null,"conditionVersion":null,"createdOn":"2025-04-22T21:54:42.4610522Z","updatedOn":"2025-04-22T21:55:45.5576117Z","createdBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","updatedBy":"58f99769-d43b-4ea0-86a9-9547c8fac070","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/providers/Microsoft.Authorization/roleAssignments/c40df73a-b6a5-5458-a0a5-dc5aa98facc6","type":"Microsoft.Authorization/roleAssignments","name":"c40df73a-b6a5-5458-a0a5-dc5aa98facc6"}' + headers: + cache-control: + - no-cache + content-length: + - '1045' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:47 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/58b15269-18bf-4c4c-8174-656d05f8da40 + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: D0FAA1CB32A44614A68AE38415A5F072 Ref B: MWH011020808029 Ref C: 2025-04-22T21:55:45Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tasks/cssc-trigger-workflow?api-version=2019-06-01-preview + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:55:47 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/b799edcd-4be1-40fd-a5ef-7e8d0f3c51d2 + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: D26B6C4BB27748F59AE15EE9AC93BF36 Ref B: MWH011020807036 Ref C: 2025-04-22T21:55:47Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resources?$filter=resourceType%20eq%20%27Microsoft.ContainerRegistry%2Fregistries%27&api-version=2022-09-01 + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/grayeus2euap","name":"grayeus2euap","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus2euap","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2022-10-06T16:30:06.2025526Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2022-10-06T16:34:13.6789203Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graywus2","name":"graywus2","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus2","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2022-06-15T23:36:48.7494742Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-05-08T20:13:10.5096692Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graybugbash","name":"graybugbash","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus3","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2024-07-02T22:12:00.2729923Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2024-07-02T22:12:00.2729923Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graycsscsec","name":"graycsscsec","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"swedencentral","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2024-09-10T17:32:40.0833148Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-10T00:08:28.5420628Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/csscbugbash2/providers/Microsoft.ContainerRegistry/registries/graybugbash2","name":"graybugbash2","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-03-28T17:03:34.0143535Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-03-28T17:03:34.0143535Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graycsscemptytoken","name":"graycsscemptytoken","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus2","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-02T18:21:07.0460694Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-02T18:21:07.0460694Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/grayrgdev/providers/Microsoft.ContainerRegistry/registries/graybasic","name":"graybasic","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Basic","tier":"Basic"},"location":"westus2","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-09T23:42:34.4937063Z","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-09T23:42:34.4937063Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '4245' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:51 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 539C8B48E7CF41879BDF7AAE6C788100 Ref B: CO6AA3150218009 Ref C: 2025-04-22T21:55:52Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr supply-chain workflow delete + Connection: + - keep-alive + ParameterSetName: + - -r -g -t --yes + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-11-01-preview + response: + body: + string: '{"sku":{"name":"Standard","tier":"Standard"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"cegraybl@microsoft.com","createdByType":"User","createdAt":"2025-04-22T21:53:55.3050482+00:00","lastModifiedBy":"cegraybl@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2025-04-22T21:53:55.3050482+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2025-04-22T21:53:55.3050482Z","provisioningState":"Succeeded","adminUserEnabled":false,"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2025-04-22T21:54:02.0227876+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2025-04-22T21:54:02.022829+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled"}}' + headers: + api-supported-versions: + - 2023-11-01-preview + cache-control: + - no-cache + content-length: + - '1397' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:52 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 169B3CE0382A4D07BBE7B733710237E3 Ref B: CO6AA3150220021 Ref C: 2025-04-22T21:55:52Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/ + response: + body: + string: '{"errors":[{"code":"UNAUTHORIZED","message":"authentication required, + visit https://aka.ms/acr/authorization for more information.","detail":null}]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '149' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:53 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://cliregrutwpbbvyhtugt.azurecr.io/oauth2/token",service="cliregrutwpbbvyhtugt.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.3 + method: GET + uri: https://clireg000002.azurecr.io/v2/ + response: + body: + string: '{"errors":[{"code":"UNAUTHORIZED","message":"authentication required, + visit https://aka.ms/acr/authorization for more information.","detail":null}]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '149' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:53 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://cliregrutwpbbvyhtugt.azurecr.io/oauth2/token",service="cliregrutwpbbvyhtugt.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: service=cliregrutwpbbvyhtugt.azurecr.io&grant_type=password&username=00000000-0000-0000-0000-000000000000&password=***&scope=repository%3Acsscpolicies%2Fpatchpolicy%3Adelete%2Cmetadata_read + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '1348' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.32.3 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/token + response: + body: + string: '{"access_token":"***","refresh_token":"***"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:53 GMT + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '166.616667' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - python-requests/2.32.3 + method: DELETE + uri: https://clireg000002.azurecr.io/acr/v1/csscpolicies/patchpolicy + response: + body: + string: '{"manifestsDeleted":["sha256:7f35b408122f42636a4b7a063bf2f678aba6b0122d0242c8e4e5c11b17d30ffd"],"tagsDeleted":["v1"]} + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '118' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 22 Apr 2025 21:55:58 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - AzureContainerRegistry + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-calls-per-second: + - '8.000000' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.68.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2023-11-01-preview + response: + body: + string: '' + headers: + api-supported-versions: + - 2023-11-01-preview + cache-control: + - no-cache + content-length: + - '0' + date: + - Tue, 22 Apr 2025 21:56:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=58f99769-d43b-4ea0-86a9-9547c8fac070/westus2/a8e9c409-d04f-4149-8110-237928538328 + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: 34CF8D8973334EB482F3C3CD0380D860 Ref B: MWH011020807060 Ref C: 2025-04-22T21:55:58Z' + status: + code: 200 + message: OK +version: 1 diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_cssc.py b/src/acrcssc/azext_acrcssc/tests/latest/test_cssc.py new file mode 100644 index 00000000000..482c9dd7829 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_cssc.py @@ -0,0 +1,56 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import unittest +from unittest import mock +from unittest.mock import MagicMock +from azext_acrcssc.cssc import create_acrcssc, update_acrcssc, delete_acrcssc, show_acrcssc, cancel_runs, list_scan_status + +class AcrcsscTest(unittest.TestCase): + def __init__(self, method_name): + super().__init__(method_name) + self.cmd = mock.MagicMock() + self.cmd.cli_ctx = MagicMock() + self.registry = MagicMock() + self.registry.name = "mockregistry" + self.registry.id = f"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mockrg/providers/Microsoft.ContainerRegistry/registries/{self.registry.name}" + self.config = MagicMock() + + @mock.patch("azext_acrcssc.cssc._perform_continuous_patch_operation") + def test_create_acrcssc(self, mock_perform_continuous_patch_operation): + create_acrcssc(self.cmd, "mockrg", self.registry.name, "continuouspatchv1", "mockconfig", "1d", False, False) + mock_perform_continuous_patch_operation.assert_called_once_with(self.cmd, "mockrg", self.registry.name, "mockconfig", "1d", False, False, is_create=True) + + @mock.patch("azext_acrcssc.cssc._perform_continuous_patch_operation") + def test_update_acrcssc(self, mock_perform_continuous_patch_operation): + update_acrcssc(self.cmd, "mockrg", self.registry.name, "continuouspatchv1", "mockconfig", "1d", False, False) + mock_perform_continuous_patch_operation.assert_called_once_with(self.cmd, "mockrg", self.registry.name, "mockconfig", "1d", False, False, is_create=False) + + @mock.patch("azext_acrcssc.cssc.delete_continuous_patch_v1") + @mock.patch("azext_acrcssc.cssc.cf_acr_registries") + @mock.patch("azure.cli.core.util.user_confirmation") + def test_delete_acrcssc(self, mock_user_confirmation, mock_cf_acr_registries, mock_delete_continuous_patch_v1): + mock_cf_acr_registries.return_value.get.return_value = self.registry + delete_acrcssc(self.cmd, "mockrg", self.registry.name, "continuouspatchv1", True) + mock_delete_continuous_patch_v1.assert_called_once_with(self.cmd, self.registry, yes=True) + + @mock.patch("azext_acrcssc.cssc.list_continuous_patch_v1") + @mock.patch("azext_acrcssc.cssc.cf_acr_registries") + def test_show_acrcssc(self, mock_cf_acr_registries, mock_list_continuous_patch_v1): + mock_cf_acr_registries.return_value.get.return_value = self.registry + show_acrcssc(self.cmd, "mockrg", self.registry.name, "continuouspatchv1") + mock_list_continuous_patch_v1.assert_called_once_with(self.cmd, self.registry) + + @mock.patch("azext_acrcssc.cssc.cancel_continuous_patch_runs") + def test_cancel_runs(self, mock_cancel_continuous_patch_runs): + cancel_runs(self.cmd, "mockrg", self.registry.name, "continuouspatchv1") + mock_cancel_continuous_patch_runs.assert_called_once_with(self.cmd, "mockrg", self.registry.name) + + @mock.patch("azext_acrcssc.cssc.track_scan_progress") + @mock.patch("azext_acrcssc.cssc.cf_acr_registries") + def test_list_scan_status(self, mock_cf_acr_registries, mock_track_scan_progress): + mock_cf_acr_registries.return_value.get.return_value = self.registry + list_scan_status(self.cmd, self.registry.name, "mockrg", "mockstatus", "continuouspatchv1") + mock_track_scan_progress.assert_called_once_with(self.cmd, "mockrg", self.registry, "mockstatus") diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_cssc_scenario.py b/src/acrcssc/azext_acrcssc/tests/latest/test_cssc_scenario.py new file mode 100644 index 00000000000..a2d6ac6044b --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_cssc_scenario.py @@ -0,0 +1,39 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import os +from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer, live_only + + +class AcrcsscScenarioTest(ScenarioTest): + @live_only() + @ResourceGroupPreparer() + def test_acrcssc_workflow(self, resource_group): + curr_dir = os.path.dirname(os.path.abspath(__file__)) + self.kwargs.update({ + 'registry_name': self.create_random_name('clireg', 20), + 'rg': resource_group, + 'location': 'eastus', + 'workflow_type': 'ContinuousPatchV1', + 'config': os.path.normpath(os.path.join(curr_dir, 'config', 'scenario_test_config.json')), + 'schedule': '7d' + }) + + self.cmd('acr create -n {registry_name} -g {rg} --sku Standard --location {location}', + checks=[self.check('name', '{registry_name}'), + self.check('provisioningState', 'Succeeded')]) + + self.cmd('acr supply-chain workflow create -r {registry_name} -g {rg} -t {workflow_type} --config "{config}" --schedule {schedule}') + + self.cmd('acr supply-chain workflow list -r {registry_name} -g {rg} -t {workflow_type}') + + self.cmd('acr supply-chain workflow show -r {registry_name} -g {rg} -t {workflow_type}', + checks=[self.check('length(@)', 3)]) + + self.cmd('acr supply-chain workflow update -r {registry_name} -g {rg} -t {workflow_type} --schedule 14d') + + self.cmd('acr supply-chain workflow delete -r {registry_name} -g {rg} -t {workflow_type} --yes') + + self.cmd('acr delete -n {registry_name} -g {rg} -y') diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_helper_ociartifactoperations.py b/src/acrcssc/azext_acrcssc/tests/latest/test_helper_ociartifactoperations.py new file mode 100644 index 00000000000..7a45e4be88a --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_helper_ociartifactoperations.py @@ -0,0 +1,106 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import tempfile +import unittest +from unittest import mock +from unittest.mock import MagicMock, patch +from azext_acrcssc.helper._ociartifactoperations import create_oci_artifact_continuous_patch, delete_oci_artifact_continuous_patch +from azure.cli.core.mock import DummyCli + + +class TestCreateOciArtifactContinuousPatch(unittest.TestCase): + @patch('azext_acrcssc.helper._ociartifactoperations._oras_client') + @patch('azext_acrcssc.helper._ociartifactoperations.NamedTemporaryFile') + @patch('shutil.copyfileobj') + @patch('builtins.open') + def test_create_oci_artifact_continuous_patch(self, mock_open, mock_copyfileobj, mock_NamedTemporaryFile, mock_oras_client): + # Mock the necessary dependencies + temp_artifact = MagicMock() + temp_artifact.name = "mock_temp_file_path" + mock_NamedTemporaryFile.return_value.__enter__.return_value = temp_artifact + + # Configure the open() mock to return a mock file object + mock_file = MagicMock() + mock_open.return_value = mock_file + mock_copyfileobj.return_value = None + + registry = MagicMock() + registry.login_server = "test@azurecr.io" + cssc_config_file = temp_artifact.name # Use the mocked file path + dryrun = False + oras_client = MagicMock() + oras_client.push = MagicMock() + mock_oras_client.return_value = oras_client + + # Call the function + with patch('os.path.exists', return_value=True), patch('os.remove', return_value=True): + create_oci_artifact_continuous_patch(registry, cssc_config_file, dryrun) + + # Assert that the necessary functions were called with the correct arguments + mock_oras_client.assert_called_once_with(registry) + oras_client.push.assert_called_once_with(target='csscpolicies/patchpolicy:v1', files=[temp_artifact.name]) + + @mock.patch('azext_acrcssc.helper._ociartifactoperations._get_acr_token') + @mock.patch('azext_acrcssc.helper._ociartifactoperations.logger') + @mock.patch('azext_acrcssc.helper._ociartifactoperations.parse_resource_id') + @mock.patch('azext_acrcssc.helper._ociartifactoperations.acr_repository_delete') + def test_delete_oci_artifact_continuous_patch(self, mock_acr_repository_delete, mock_parse_resource_id, mock_logger, mock_get_acr_token): + # Mock the necessary dependencies + cmd = self._setup_cmd() + registry = MagicMock() + mock_parse_resource_id.return_value = { + "resource_group": "test_rg", + "subscription": "test_subscription" + } + mock_get_acr_token.return_value = "test_token" + + # Call the function + delete_oci_artifact_continuous_patch(cmd, registry) + + # Assert the function calls + mock_parse_resource_id.assert_called_once_with(registry.id) + mock_get_acr_token.assert_called_once_with(registry.name, "test_subscription") + mock_acr_repository_delete.assert_called_once_with( + cmd=cmd, + registry_name=registry.name, + repository="csscpolicies/patchpolicy", + username="00000000-0000-0000-0000-000000000000", + password="test_token", + yes=True + ) + mock_logger.warning.assert_not_called() + mock_acr_repository_delete.assert_called_once() + + + @mock.patch('azext_acrcssc.helper._ociartifactoperations._get_acr_token') + @mock.patch('azext_acrcssc.helper._ociartifactoperations.logger') + @mock.patch('azext_acrcssc.helper._ociartifactoperations.parse_resource_id') + @mock.patch('azext_acrcssc.helper._ociartifactoperations.acr_repository_delete') + def test_delete_oci_artifact_continuous_patch_exception(self, mock_acr_repository_delete, mock_parse_resource_id, mock_logger, mock_get_acr_token): + # Mock the necessary dependencies + cmd = self._setup_cmd() + registry = MagicMock() + mock_parse_resource_id.return_value = { + "resource_group": "test_rg", + "subscription": "test_subscription" + } + + mock_get_acr_token.return_value = "test_token" + mock_acr_repository_delete.side_effect = Exception("Test exception") + + # Run the function and assert the exception + with (self.assertRaises(Exception)): + delete_oci_artifact_continuous_patch(cmd, registry) + + # Assert the function calls + mock_parse_resource_id.assert_called_once_with(registry.id) + mock_get_acr_token.assert_called_once_with(registry.name, "test_subscription") + mock_logger.warning.assert_not_called() + + def _setup_cmd(self): + cmd = mock.MagicMock() + cmd.cli_ctx = DummyCli() + return cmd diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_helper_taskoperations.py b/src/acrcssc/azext_acrcssc/tests/latest/test_helper_taskoperations.py new file mode 100644 index 00000000000..63cfe5e265e --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_helper_taskoperations.py @@ -0,0 +1,277 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import tempfile +import unittest +from unittest import mock +from azure.cli.core.mock import DummyCli +from azext_acrcssc.helper._taskoperations import (create_update_continuous_patch_v1, delete_continuous_patch_v1, list_continuous_patch_v1, acr_cssc_dry_run, cancel_continuous_patch_runs, track_scan_progress) + + +class TestCreateContinuousPatchV1(unittest.TestCase): + def __init__(self, methodName): + super().__init__(methodName) + self.cmd = self._setup_cmd() + self.registry = mock.MagicMock() + self.registry.name = "mockregistry" + self.registry.id = f"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mockrg/providers/Microsoft.ContainerRegistry/registries/{self.registry.name}" + self.config = mock.MagicMock() + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.convert_timespan_to_cron") + @mock.patch("azext_acrcssc.helper._taskoperations.create_oci_artifact_continuous_patch") + @mock.patch("azext_acrcssc.helper._taskoperations.validate_and_deploy_template") + @mock.patch("azext_acrcssc.helper._taskoperations._eval_trigger_run") + def test_create_continuous_patch_v1(self, mock_eval_trigger_run, mock_validate_and_deploy_template, mock_create_oci_artifact_continuous_patch, mock_convert_timespan_to_cron, mock_check_continuoustask_exists): + # Mock the necessary dependencies + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + mock_check_continuoustask_exists.return_value = False, [] + mock_convert_timespan_to_cron.return_value = "0 0 * * *" + + # Call the function + create_update_continuous_patch_v1(self.cmd, self.registry, temp_file_path, "1d", False, False) + + # Assert that the dependencies were called with the correct arguments + mock_convert_timespan_to_cron.assert_called_once_with("1d") + mock_create_oci_artifact_continuous_patch.assert_called_once() + mock_validate_and_deploy_template.assert_called_once() + mock_eval_trigger_run.assert_called_once() + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.convert_timespan_to_cron") + @mock.patch("azext_acrcssc.helper._taskoperations.create_oci_artifact_continuous_patch") + @mock.patch("azext_acrcssc.helper._taskoperations.validate_and_deploy_template") + @mock.patch("azext_acrcssc.helper._taskoperations._eval_trigger_run") + def test_create_continuous_patch_v1_create_run_immediately_triggers_task(self, mock_eval_trigger_run, mock_validate_and_deploy_template, mock_create_oci_artifact_continuous_patch, mock_convert_timespan_to_cron, mock_check_continuoustask_exists): + # Mock the necessary dependencies + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + mock_check_continuoustask_exists.return_value = False, [] + mock_convert_timespan_to_cron.return_value = "0 0 * * *" + + # Call the function + create_update_continuous_patch_v1(self.cmd, self.registry, temp_file_path, "1d", False, True) + + # Assert that the dependencies were called with the correct arguments + mock_convert_timespan_to_cron.assert_called_once_with("1d") + mock_create_oci_artifact_continuous_patch.assert_called_once() + mock_validate_and_deploy_template.assert_called_once() + mock_eval_trigger_run.assert_called_once() + + @mock.patch("azext_acrcssc.helper._taskoperations._update_task_schedule") + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.convert_timespan_to_cron") + @mock.patch("azext_acrcssc.helper._taskoperations.create_oci_artifact_continuous_patch") + @mock.patch("azext_acrcssc.helper._taskoperations.validate_and_deploy_template") + @mock.patch("azext_acrcssc.helper._taskoperations._eval_trigger_run") + @mock.patch('azext_acrcssc.helper._taskoperations.cf_acr_tasks') + def test_update_continuous_patch_v1_schedule_update_should_not_update_config(self, mock_cf_acr_tasks, mock_eval_trigger_run, mock_validate_and_deploy_template, mock_create_oci_artifact_continuous_patch, mock_convert_timespan_to_cron, mock_check_continuoustask_exists, mock_update_task_schedule): + # Mock the necessary dependencies + mock_acr_tasks_client = mock.MagicMock() + mock_cf_acr_tasks.return_value = mock_acr_tasks_client + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + mock_check_continuoustask_exists.return_value = True, [] + mock_convert_timespan_to_cron.return_value = "0 0 * * *" + + # Call the function + create_update_continuous_patch_v1(self.cmd, self.registry, None, "2d", False, False, False) + + # Assert that the dependencies were called with the correct arguments + mock_convert_timespan_to_cron.assert_called_once_with("2d") + mock_create_oci_artifact_continuous_patch.assert_not_called() + mock_validate_and_deploy_template.assert_not_called() + mock_eval_trigger_run.assert_called_once() + mock_update_task_schedule.assert_called_once() + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.convert_timespan_to_cron") + @mock.patch("azext_acrcssc.helper._taskoperations.create_oci_artifact_continuous_patch") + def test_update_continuous_patch_v1__update_without_tasks_workflow_should_fail(self, mock_create_oci_artifact_continuous_patch, mock_convert_timespan_to_cron, mock_check_continuoustask_exists): + # Mock the necessary dependencies + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + mock_check_continuoustask_exists.return_value = False, [] + mock_convert_timespan_to_cron.return_value = "0 0 * * *" + + # Call the function + self.assertRaises(Exception,create_update_continuous_patch_v1, self.cmd, self.registry, None, "2d", False, False, False) + + # Assert that the dependencies were called with the correct arguments + mock_convert_timespan_to_cron.assert_called_once_with("2d") + mock_create_oci_artifact_continuous_patch.assert_not_called() + + @mock.patch("azext_acrcssc.helper._taskoperations._update_task_schedule") + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.convert_timespan_to_cron") + @mock.patch("azext_acrcssc.helper._taskoperations.create_oci_artifact_continuous_patch") + @mock.patch("azext_acrcssc.helper._taskoperations.validate_and_deploy_template") + @mock.patch("azext_acrcssc.helper._taskoperations._eval_trigger_run") + @mock.patch('azext_acrcssc.helper._taskoperations.cf_acr_tasks') + @mock.patch('azext_acrcssc.helper._taskoperations.cf_authorization') + def test_update_continuous_patch_v1_schedule_update_run_immediately_triggers_task(self, mock_cf_authorization, mock_cf_acr_tasks, mock_eval_trigger_run, mock_validate_and_deploy_template, mock_create_oci_artifact_continuous_patch, mock_convert_timespan_to_cron, mock_check_continuoustask_exists, mock_update_task_schedule): + # Mock the necessary dependencies + mock_acr_tasks_client = mock.MagicMock() + mock_cf_acr_tasks.return_value = mock_acr_tasks_client + mock_role_client = mock.MagicMock() + mock_cf_authorization.return_value = mock_role_client + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + mock_check_continuoustask_exists.return_value = True, [] + mock_convert_timespan_to_cron.return_value = "0 0 * * *" + + # Call the function + create_update_continuous_patch_v1(self.cmd, self.registry, None, "2d", False, True, False) + + # Assert that the dependencies were called with the correct arguments + mock_convert_timespan_to_cron.assert_called_once_with("2d") + mock_create_oci_artifact_continuous_patch.assert_not_called() + mock_validate_and_deploy_template.assert_not_called() + mock_eval_trigger_run.assert_called_once() + mock_update_task_schedule.assert_called_once() + + @mock.patch("azext_acrcssc.helper._taskoperations._cancel_task_runs") + @mock.patch("azext_acrcssc.helper._taskoperations.WorkflowTaskStatus.get_taskruns_with_filter") + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_config_exists") + @mock.patch('azext_acrcssc.helper._taskoperations.delete_oci_artifact_continuous_patch') + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.cf_acr_runs") + @mock.patch('azext_acrcssc.helper._taskoperations.cf_acr_tasks') + @mock.patch('azext_acrcssc.helper._taskoperations.cf_authorization') + def test_delete_continuous_patch_v1(self, mock_cf_authorization, mock_cf_acr_tasks, mock_cf_acr_runs, mock_check_continuoustask_exists, mock_delete_oci_artifact_continuous_patch, mock_check_continuous_task_config_exists, mock_get_taskruns_with_filter, mock_cancel_task_runs): + # Mock the necessary dependencies + mock_check_continuoustask_exists.return_value = True, [] + mock_check_continuous_task_config_exists.return_value = True + mock_resource_group = mock.MagicMock() + mock_resource_group.name = 'resource_group_name' + mock_acr_tasks_client = mock.MagicMock() + mock_cf_acr_tasks.return_value = mock_acr_tasks_client + mock_role_client = mock.MagicMock() + mock_cf_authorization.return_value = mock_role_client + mock_acr_run_client = mock.MagicMock() + mock_cf_acr_runs.return_value = mock_acr_run_client + mock_task = mock.MagicMock() + mock_task.identity = mock.MagicMock()(principal_id='principal_id') + mock_acr_tasks_client.get.return_value = mock_task + mock_get_taskruns_with_filter.return_value = [mock.MagicMock()] + + delete_continuous_patch_v1(self.cmd, self.registry, yes=True) + ## Assert here + mock_delete_oci_artifact_continuous_patch.assert_called_once() + mock_cancel_task_runs.assert_called_once() + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.convert_timespan_to_cron") + @mock.patch("azext_acrcssc.helper._taskoperations.create_oci_artifact_continuous_patch") + @mock.patch("azext_acrcssc.helper._taskoperations.validate_and_deploy_template") + @mock.patch("azext_acrcssc.helper._taskoperations._eval_trigger_run") + def test_create_continuous_patch_v1_dryrun(self, mock_eval_trigger_run, mock_validate_and_deploy_template, mock_create_oci_artifact_continuous_patch, mock_convert_timespan_to_cron, mock_check_continuous_task_exists): + # Mock the necessary dependencies + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + mock_check_continuous_task_exists.return_value = False, [] + mock_convert_timespan_to_cron.return_value = "0 0 * * *" + + # Call the function + create_update_continuous_patch_v1(self.cmd, self.registry, temp_file_path, "1d", True, False) + + # Assert that the dependencies were called with the correct arguments + mock_convert_timespan_to_cron.assert_called_once_with("1d") + mock_create_oci_artifact_continuous_patch.assert_called_once() + mock_validate_and_deploy_template.assert_called_once() + mock_eval_trigger_run.assert_called_once() + + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations._transform_task_list") + def test_list_continuous_patch_v1(self, mock_transform_task_list, mock_check_continuous_task_exists): + # Mock the necessary dependencies + mock_check_continuous_task_exists.return_value = True, [] + mock_transform_task_list.return_value = [] + + # Call the function + result = list_continuous_patch_v1(self.cmd, self.registry) + + # Assert that the dependencies were called with the correct arguments + mock_check_continuous_task_exists.assert_called_once() + mock_transform_task_list.assert_called_once() + self.assertEqual(result, []) + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.WorkflowTaskStatus.generate_logs") + @mock.patch("azext_acrcssc.helper._taskoperations.create_temporary_dry_run_file") + @mock.patch("azext_acrcssc.helper._taskoperations.delete_temporary_dry_run_file") + @mock.patch("azext_acrcssc.helper._taskoperations.prepare_source_location") + @mock.patch("azext_acrcssc.helper._taskoperations.cf_acr_registries_tasks") + @mock.patch("azext_acrcssc.helper._taskoperations.cf_acr_runs") + @mock.patch('azext_acrcssc._validators.cf_acr_tasks') + @mock.patch('azext_acrcssc.helper._taskoperations.cf_acr_tasks') + @mock.patch("azext_acrcssc.helper._taskoperations.LongRunningOperation") + def test_acr_cssc_dry_run(self, mock_LongRunningOperation, mock_cf_acr_tasks_taskoperations, mock_cf_acr_tasks_validator, mock_cf_acr_runs, mock_cf_acr_registries_tasks, mock_prepare_source_location, mock_delete_temporary_dry_run_file, mock_create_temporary_dry_run_file, mock_generate_logs, mock_check_continuous_task_exists): + # Mock the necessary dependencies + config_file_path = "test_config_file_path" + mock_acr_registries_task_client = mock.MagicMock() + mock_cf_acr_registries_tasks.return_value = mock_acr_registries_task_client + mock_acr_run_client = mock.MagicMock() + mock_cf_acr_runs.return_value = mock_acr_run_client + mock_acr_task_client = mock.MagicMock() + mock_cf_acr_tasks_validator.return_value = mock_acr_task_client + mock_cf_acr_tasks_taskoperations.return_value = mock_acr_task_client + mock_LongRunningOperation.return_value.return_value.run_id = "test_run_id" + mock_generate_logs.return_value = "mock_logs" + mock_check_continuous_task_exists.return_value = False, [] + + # Call the function + result = acr_cssc_dry_run(self.cmd, self.registry, config_file_path) + + # Assert that the dependencies were called with the correct arguments + mock_create_temporary_dry_run_file.assert_called_once_with(config_file_path, mock.ANY) + mock_prepare_source_location.assert_called_once() + mock_LongRunningOperation.assert_called_once() + mock_delete_temporary_dry_run_file.assert_called_once() + mock_generate_logs.assert_called_once() + self.assertIsNotNone(result) + + @mock.patch("azext_acrcssc.helper._taskoperations.WorkflowTaskStatus.get_taskruns_with_filter") + @mock.patch("azext_acrcssc.helper._taskoperations.cf_acr_runs") + def test_cancel_continuous_patch_runs(self, mock_cf_acr_runs, mock_get_taskruns_with_filter): + # Mock the necessary dependencies + resource_group_name = "test_rg" + registry_name = "test_registry" + mock_acr_task_run_client = mock.MagicMock() + mock_cf_acr_runs.return_value = mock_acr_task_run_client + mock_get_taskruns_with_filter.return_value = [mock.MagicMock()] + + # Call the function + cancel_continuous_patch_runs(self.cmd, resource_group_name, registry_name) + + # Assert that the dependencies were called with the correct arguments + mock_get_taskruns_with_filter.assert_called_once() + mock_acr_task_run_client.begin_cancel.assert_called_once() + + @mock.patch("azext_acrcssc.helper._taskoperations.check_continuous_task_exists") + @mock.patch("azext_acrcssc.helper._taskoperations.get_oci_artifact_continuous_patch") + @mock.patch("azext_acrcssc.helper._taskoperations._retrieve_logs_for_image") + def test_track_scan_progress(self, mock_retrieve_logs_for_image, mock_get_oci_artifact_continuous_patch, mock_check_continuous_task_exists): + # Mock the necessary dependencies + mock_check_continuous_task_exists.return_value = True, [] + resource_group_name = "test_rg" + status = "test_status" + mock_get_oci_artifact_continuous_patch.return_value = mock.MagicMock(schedule="1d"), mock.MagicMock() + + # Call the function + result = track_scan_progress(self.cmd, resource_group_name, self.registry, status) + + # Assert that the dependencies were called with the correct arguments + mock_check_continuous_task_exists.assert_called_once() + mock_get_oci_artifact_continuous_patch.assert_called_once() + mock_retrieve_logs_for_image.assert_called_once() + self.assertIsNotNone(result) + + def _setup_cmd(self): + cmd = mock.MagicMock() + cmd.cli_ctx = DummyCli() + return cmd diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_helper_utility.py b/src/acrcssc/azext_acrcssc/tests/latest/test_helper_utility.py new file mode 100644 index 00000000000..29f7d4d7128 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_helper_utility.py @@ -0,0 +1,46 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import unittest +from azext_acrcssc.helper._utility import convert_cron_to_schedule, convert_timespan_to_cron +from azure.cli.core.azclierror import InvalidArgumentValueError + + +class TestCSSCUtilities(unittest.TestCase): + def test_convert_timespan_to_cron_valid(self): + # convert_timespan_to_cron() will return a cron that will include the current minute and hour, + # only match with the day of the month + test_cases = [ + ('1d', r'\d+ \d+ \*/1 \* \*'), + ('5d', r'\d+ \d+ \*/5 \* \*'), + ('10d', r'\d+ \d+ \*/10 \* \*') + ] + + for timespan, result in test_cases: + converted_value = convert_timespan_to_cron(timespan) + self.assertRegex(converted_value, result) + + def test_convert_timespan_to_cron_invalid(self): + test_cases = [('12'), ('0d'), ('99d'), ('dd'), ('d')] + + for timespan in test_cases: + self.assertRaises(InvalidArgumentValueError, convert_timespan_to_cron, timespan) + + def test_convert_cron_to_schedule_valid(self): + test_cases = [ + ('0 0 */1 * *', '1d'), + ('0 0 */5 * *', '5d'), + ('0 0 */10 * *', '10d') + ] + + for cron, result in test_cases: + self.assertEqual(convert_cron_to_schedule(cron), result) + + def test_convert_cron_to_schedule_invalid(self): + test_cases = [('*'), (''), ('* * * * *'), ('dd'), ('d')] + + for cron in test_cases: + self.assertEqual(convert_cron_to_schedule(cron), None) + diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_validators.py b/src/acrcssc/azext_acrcssc/tests/latest/test_validators.py new file mode 100644 index 00000000000..f25614bb304 --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_validators.py @@ -0,0 +1,234 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import os +import tempfile +import unittest +from unittest import mock +from ..._validators import ( + _validate_schedule, validate_run_type, check_continuous_task_exists, validate_continuouspatch_config_v1 +) + +from azure.cli.core.azclierror import AzCLIError, InvalidArgumentValueError +from azure.cli.core.mock import DummyCli +from unittest.mock import patch + + +class AcrCsscCommandsTests(unittest.TestCase): + + def test_validate_schedule_valid(self): + test_cases = [ + ('1d'), + ('5d'), + ('10d') + ] + + for timespan in test_cases: + with self.subTest(timespan=timespan): + _validate_schedule(timespan) + + def test_validate_schedule_invalid(self): + test_cases = [('df'),('12'),('dd'),('41d'), ('21dd'), ('0d'), ('-1d'), ('d')] + + for timespan in test_cases: + self.assertRaises(InvalidArgumentValueError, _validate_schedule, timespan) + + def test_validate_run_type_valid(self): + test_cases = [ + (True, False), + (False, True), + (False, False) + ] + + for dryrun, run_immediately in test_cases: + with self.subTest(dryrun=dryrun, run_immediately=run_immediately): + validate_run_type(dryrun, run_immediately) + + def test_validate_run_type_invalid(self): + test_cases = [ + (True, True) + ] + + for dryrun, run_immediately in test_cases: + with self.subTest(dryrun=dryrun, run_immediately=run_immediately): + self.assertRaises(InvalidArgumentValueError, validate_run_type, dryrun, run_immediately) + + @patch('azext_acrcssc._validators.cf_acr_tasks') + def test_check_continuoustask_exists(self, mock_cf_acr_tasks): + cmd = self._setup_cmd() + registry = mock.MagicMock() + registry.id = "/subscriptions/11111111-0000-0000-0000-0000000000006/resourceGroups/test-rg/providers/Microsoft.ContainerRegistry/registries/testregistry" + cf_acr_tasks_mock = mock.MagicMock() + + mock_cf_acr_tasks.return_value = cf_acr_tasks_mock + cf_acr_tasks_mock.get.return_value = {"name": "my_task"} + exists, _ = check_continuous_task_exists(cmd, registry) + self.assertTrue(exists) + + @patch('azext_acrcssc._validators.cf_acr_tasks') + def test_task_does_not_exist(self, mock_cf_acr_tasks): + cmd = self._setup_cmd() + registry = mock.MagicMock() + registry.id = "/subscriptions/11111111-0000-0000-0000-0000000000006/resourceGroups/test-rg/providers/Microsoft.ContainerRegistry/registries/testregistry" + cf_acr_tasks_mock = mock.MagicMock() + + mock_cf_acr_tasks.return_value = cf_acr_tasks_mock + cf_acr_tasks_mock.get.return_value = None + + exists, _ = check_continuous_task_exists(cmd, registry) + self.assertFalse(exists) + + def test_validate_continuouspatch_file(self): + # Create a temporary file for testing + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + + # Test when the file does not exist + with patch('os.path.exists', return_value=False): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + # Test when the path is not a file + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=False): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + # Test when the file size exceeds the limit + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=10485761): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + # Test when the file is empty + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=0): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + # Test when the file is not readable + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=False): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + @patch('azext_acrcssc.helper._ociartifactoperations.json.loads') + def test_validate_continuouspatch_json_valid_json_should_parse(self, mock_load): + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + + mock_config = { + "repositories": [ + { + "repository": "docker-local", + "tags": ["v1"], + "enabled": True + }], + "version": "v1" + } + mock_load.return_value = mock_config + + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=True): + validate_continuouspatch_config_v1(temp_file_path) + mock_load.assert_called_once_with(mock.ANY) + + @patch('azext_acrcssc.helper._ociartifactoperations.json.loads') + def test_validate_continuouspatch_json_invalid_json_should_fail(self, mock_load): + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + + # Test when version is missing + mock_invalid_config = { + "repositories": [ + { + "repository": "docker-local", + "tags": ["v1"], + }] + } + mock_load.return_value = mock_invalid_config + + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=True): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + # Test when repositories is empty + mock_invalid_config = { + "repositories": [], + "version": "v1" + } + mock_load.return_value = mock_invalid_config + + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=True): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + # Test when same repository is repeated + mock_invalid_config = { + "repositories": [ + { + "repository": "docker-local", + "tags": ["v1"], + }, + { + "repository": "docker-local", + "tags": ["v1"], + }], + "version": "v1" + } + mock_load.return_value = mock_invalid_config + + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=True): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + @patch('azext_acrcssc.helper._ociartifactoperations.json.loads') + def test_validate_continuouspatch_json_invalid_tags_should_fail(self, mock_load): + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = temp_file.name + + mock_invalid_config = { + "repositories": [ + { + "repository": "docker-local", + "tags": ["v1-patched"], + }], + "version": "v1" + } + mock_load.return_value = mock_invalid_config + + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=True): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + mock_invalid_config = { + "repositories": [ + { + "repository": "docker-local", + "tags": ["v1-999"], + }], + "version": "v1" + } + mock_load.return_value = mock_invalid_config + + with patch('os.path.exists', return_value=True), \ + patch('os.path.isfile', return_value=True), \ + patch('os.path.getsize', return_value=100), \ + patch('os.access', return_value=True): + self.assertRaises(AzCLIError, validate_continuouspatch_config_v1, temp_file_path) + + def _setup_cmd(self): + cmd = mock.MagicMock() + cmd.cli_ctx = DummyCli() + return cmd diff --git a/src/acrcssc/azext_acrcssc/tests/latest/test_workflow_status.py b/src/acrcssc/azext_acrcssc/tests/latest/test_workflow_status.py new file mode 100644 index 00000000000..c1efcbae4ad --- /dev/null +++ b/src/acrcssc/azext_acrcssc/tests/latest/test_workflow_status.py @@ -0,0 +1,364 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import unittest +from unittest import mock +from unittest.mock import MagicMock +from azure.cli.core.mock import DummyCli +from azext_acrcssc.helper._constants import TaskRunStatus +from azext_acrcssc.helper._workflow_status import WorkflowTaskStatus, WorkflowTaskState + + +class TestWorkflowTaskStatus(unittest.TestCase): + + def setUp(self): + self.image = "repository:tag" + self.workflow_task_status = WorkflowTaskStatus(self.image) + + def test_init(self): + self.assertEqual(self.workflow_task_status.repository, "repository") + self.assertEqual(self.workflow_task_status.tag, "tag") + self.assertIsNone(self.workflow_task_status.scan_task) + self.assertEqual(self.workflow_task_status.scan_logs, "") + self.assertIsNone(self.workflow_task_status.patch_task) + self.assertEqual(self.workflow_task_status.patch_logs, "") + + def test_image(self): + self.assertEqual(self.workflow_task_status.image(), "repository:tag") + + def test_task_status_to_workflow_status(self): + from azext_acrcssc.helper._constants import TaskRunStatus + task = mock.MagicMock() + task.status = TaskRunStatus.Succeeded.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.SUCCEEDED.value) + task.status = TaskRunStatus.Running.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.RUNNING.value) + task.status = TaskRunStatus.Started.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.RUNNING.value) + task.status = TaskRunStatus.Queued.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.QUEUED.value) + task.status = TaskRunStatus.Canceled.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.CANCELED.value) + task.status = TaskRunStatus.Failed.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.FAILED.value) + task.status = TaskRunStatus.Error.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.FAILED.value) + task.status = TaskRunStatus.Timeout.value + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(task), WorkflowTaskState.FAILED.value) + + self.assertEqual(WorkflowTaskStatus._task_status_to_workflow_status(None), WorkflowTaskState.UNKNOWN.value) + + def test_workflow_status(self): + workflow = WorkflowTaskStatus("mock_repo:mock_tag") + workflow.scan_task = mock.MagicMock() + workflow.patch_task = mock.MagicMock() + + workflow.scan_task.status = TaskRunStatus.Succeeded.value + workflow.patch_task.status = TaskRunStatus.Succeeded.value + self.assertEqual(workflow.status(), WorkflowTaskState.SUCCEEDED.value) + + workflow.scan_task.status = TaskRunStatus.Succeeded.value + workflow.patch_task.status = TaskRunStatus.Failed.value + self.assertEqual(workflow.status(), WorkflowTaskState.FAILED.value) + + workflow.scan_task.status = TaskRunStatus.Succeeded.value + workflow.patch_task.status = TaskRunStatus.Running.value + self.assertEqual(workflow.status(), WorkflowTaskState.RUNNING.value) + + workflow.scan_task.status = TaskRunStatus.Canceled.value + workflow.patch_task = None + self.assertEqual(workflow.status(), WorkflowTaskState.CANCELED.value) + + workflow.scan_task.status = TaskRunStatus.Succeeded.value + workflow.patch_task = None + self.assertEqual(workflow.status(), WorkflowTaskState.SUCCEEDED.value) + + workflow.scan_task = None + workflow.patch_task = None + self.assertEqual(workflow.status(), WorkflowTaskState.UNKNOWN.value) + + def test_get_image_from_tasklog(self): + logs = "Scanning image for vulnerability and patch mock-repo:mock-tag for tag mock-tag" + self.assertEqual(WorkflowTaskStatus._get_image_from_tasklog(logs), "mock-repo:mock-tag") + + logs = "Scanning repo: mock-repo, Tag:mock-tag, OriginalTag:mock-tag" + self.assertEqual(WorkflowTaskStatus._get_image_from_tasklog(logs), "mock-repo:mock-tag") + + # logs = "Scan, Upload scan report and Schedule Patch for mock-repo:mock-tag" + # self.assertEqual(WorkflowTaskStatus._get_image_from_tasklog(logs), "mock-repo:mock-tag") + + logs = "Patching OS vulnerabilities for image mock-repo:mock-tag" + self.assertEqual(WorkflowTaskStatus._get_image_from_tasklog(logs), "mock-repo:mock-tag") + + def test_get_patch_error_reason_from_tasklog(self): + error_logs = """2025/02/11 23:46:22 Launching container with name: patch-image +#1 resolve image config for docker-image://test.azurecr.io/repo:tag-9.9.99.20202020-amd64 +Error: unsupported osType azurelinux specified +2025/02/11 23:46:23 Container failed during run: patch-image. No retries remaining. +failed to run step ID: patch-image: exit status 1 + +Run ID: dt2rw failed after 37s. Error: failed during run, err: exit status 1""" + + assert_error_log = """Error: failed during run, err: exit status 1 +Error: unsupported osType azurelinux specified""" + error_output = self.workflow_task_status._get_errors_from_tasklog(error_logs) + self.assertEqual(error_output, assert_error_log) + + @mock.patch('azext_acrcssc.helper._workflow_status.WorkflowTaskStatus._get_missing_taskrun') + @mock.patch('azext_acrcssc.helper._workflow_status.WorkflowTaskStatus._retrieve_all_tasklogs') + def test_from_taskrun(self, mock_retrieve_all_tasklogs, mock_get_missing_taskrun): + cmd = mock.MagicMock() + cmd.cli_ctx = DummyCli() + taskrun_client = MagicMock() + registry = MagicMock() + scan_taskruns = [self._generate_test_taskrun(True, repository="mock1"), self._generate_test_taskrun(True, repository="mock2"), self._generate_test_taskrun(True, repository="mock3")] + patch_taskruns = [] + + mock_retrieve_all_tasklogs.return_value = scan_taskruns + mock_get_missing_taskrun.return_value = None + + # Test with 3 simple scan tasks and no patch tasks + result = WorkflowTaskStatus.from_taskrun(cmd, taskrun_client, registry, scan_taskruns, patch_taskruns) + self.assertIsInstance(result, list) + self.assertEqual(len(result), len(scan_taskruns)) + self.assertTrue(all("patch_status" in workflow for workflow in result)) + self.assertTrue(all(workflow["patch_status"] == WorkflowTaskState.SKIPPED.value for workflow in result)) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.SUCCEEDED.value for workflow in result)) + self.assertTrue(all("patch_skipped_reason" in workflow for workflow in result)) + self.assertTrue(all("scan_error_reason" not in workflow for workflow in result)) + self.assertTrue(all("patch_error_reason" not in workflow for workflow in result)) + + # Test with 1 scan task and 1 failed patch task + patch_task = self._generate_test_taskrun(True, status=TaskRunStatus.Failed.value) + scan_taskruns = [self._generate_test_taskrun(True, patch_taskid_in_scan=patch_task.run_id)] + patch_taskruns = [patch_task] + result = WorkflowTaskStatus.from_taskrun(cmd, taskrun_client, registry, scan_taskruns, patch_taskruns) + self.assertIsInstance(result, list) + self.assertEqual(len(result), 1) + self.assertTrue(all("patch_status" in workflow for workflow in result)) + self.assertTrue(all(workflow["patch_status"] == WorkflowTaskState.FAILED.value for workflow in result)) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.SUCCEEDED.value for workflow in result)) + self.assertTrue(all("scan_error_reason" not in workflow for workflow in result)) + self.assertTrue(all("patch_error_reason" in workflow for workflow in result)) + + # Test where the patch task is missing, but mentioned in the scan task logs + patch_task = self._generate_test_taskrun(True, status=TaskRunStatus.Succeeded.value) + scan_taskruns = [self._generate_test_taskrun(True, patch_taskid_in_scan=patch_task.run_id)] + patch_taskruns = [] + mock_get_missing_taskrun.return_value = patch_task + result = WorkflowTaskStatus.from_taskrun(cmd, taskrun_client, registry, scan_taskruns, patch_taskruns) + self.assertIsInstance(result, list) + self.assertEqual(len(result), len(scan_taskruns)) + mock_get_missing_taskrun.assert_called_once() + self.assertTrue("patch_status" in result[0]) + self.assertTrue("patch_task_ID" in result[0]) + self.assertTrue("last_patched_image" in result[0]) + self.assertTrue(not result[0]["last_patched_image"].startswith("---")) + self.assertTrue(result[0]["patch_status"] == WorkflowTaskState.SUCCEEDED.value) + + # Test with mixed scan and patch tasks status + patch_taskruns = [self._generate_test_taskrun(False, status=TaskRunStatus.Succeeded.value, tag="tag0"), + self._generate_test_taskrun(False, status=TaskRunStatus.Canceled.value, tag="tag1"), + self._generate_test_taskrun(False, status=TaskRunStatus.Queued.value, tag="tag2"), + self._generate_test_taskrun(False, status=TaskRunStatus.Running.value, tag="tag3"), + self._generate_test_taskrun(False, status=TaskRunStatus.Failed.value, tag="tag4")] + + scan_taskruns = [self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[0].run_id, tag="tag0"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[1].run_id, tag="tag1"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[2].run_id, tag="tag2"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[3].run_id, tag="tag3"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[4].run_id, tag="tag4"), + self._generate_test_taskrun(True, status=TaskRunStatus.Failed.value, tag="tag5"), + self._generate_test_taskrun(True, status=TaskRunStatus.Canceled.value, tag="tag6"), + self._generate_test_taskrun(True, status=TaskRunStatus.Queued.value, tag="tag7"), + self._generate_test_taskrun(True, status=TaskRunStatus.Running.value, tag="tag8"),] + + mock_get_missing_taskrun.return_value = patch_task + result = WorkflowTaskStatus.from_taskrun(cmd, taskrun_client, registry, scan_taskruns, patch_taskruns) + self.assertIsInstance(result, list) + self.assertEqual(len(result), len(scan_taskruns)) + self.assertTrue(all("patch_status" in workflow for workflow in result)) + self.assertTrue(all("scan_status" in workflow for workflow in result)) + self.assertTrue(all("image" in workflow for workflow in result)) + self.assertTrue(all("scan_date" in workflow for workflow in result)) + self.assertTrue(all("scan_task_ID" in workflow for workflow in result)) + self.assertTrue(all("patch_date" in workflow for workflow in result)) + self.assertTrue(all("patch_task_ID" in workflow for workflow in result)) + self.assertTrue(all("last_patched_image" in workflow for workflow in result)) + self.assertTrue(all("workflow_type" in workflow for workflow in result)) + self.assertTrue(all(True if workflow["patch_status"] != TaskRunStatus.Failed.value or "patch_error_reason" in workflow else False for workflow in result)) + self.assertTrue(all(True if workflow["scan_status"] != TaskRunStatus.Failed.value or "scan_error_reason" in workflow else False for workflow in result)) + # test that a successful patch has a patched image reference + self.assertTrue(all(True if workflow["patch_status"] != TaskRunStatus.Succeeded.value or not workflow["last_patched_image"].startswith("---") else False for workflow in result)) + + + @mock.patch('azext_acrcssc.helper._workflow_status.WorkflowTaskStatus._get_missing_taskrun') + @mock.patch('azext_acrcssc.helper._workflow_status.WorkflowTaskStatus._retrieve_all_tasklogs') + def test_from_taskrun_with_filter(self, mock_retrieve_all_tasklogs, mock_get_missing_taskrun): + cmd = mock.MagicMock() + cmd.cli_ctx = DummyCli() + taskrun_client = MagicMock() + registry = MagicMock() + scan_taskruns = [] + patch_taskruns = [] + + mock_retrieve_all_tasklogs.return_value = scan_taskruns + mock_get_missing_taskrun.return_value = None + + # Test with mixed scan and patch tasks status + patch_taskruns = [self._generate_test_taskrun(False, status=TaskRunStatus.Succeeded.value, tag="tag0"), + self._generate_test_taskrun(False, status=TaskRunStatus.Canceled.value, tag="tag1"), + self._generate_test_taskrun(False, status=TaskRunStatus.Queued.value, tag="tag2"), + self._generate_test_taskrun(False, status=TaskRunStatus.Running.value, tag="tag3"), + self._generate_test_taskrun(False, status=TaskRunStatus.Failed.value, tag="tag4")] + + scan_taskruns = [self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[0].run_id, tag="tag0"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[1].run_id, tag="tag1"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[2].run_id, tag="tag2"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[3].run_id, tag="tag3"), + self._generate_test_taskrun(True, patch_taskid_in_scan=patch_taskruns[4].run_id, tag="tag4"), + self._generate_test_taskrun(True, status=TaskRunStatus.Failed.value, tag="tag5"), + self._generate_test_taskrun(True, status=TaskRunStatus.Canceled.value, tag="tag6"), + self._generate_test_taskrun(True, status=TaskRunStatus.Queued.value, tag="tag7"), + self._generate_test_taskrun(True, status=TaskRunStatus.Running.value, tag="tag8"), + self._generate_test_taskrun(True, status=TaskRunStatus.Succeeded.value, tag="tag9")] + + result = WorkflowTaskStatus.from_taskrun(cmd, + taskrun_client, + registry, + scan_taskruns, + patch_taskruns, + workflow_status_filter=WorkflowTaskState.SUCCEEDED.value) + self.assertTrue(len(result) > 0) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.SUCCEEDED.value + for workflow in result)) + self.assertTrue(all(workflow["patch_status"] == WorkflowTaskState.SUCCEEDED.value or + workflow["patch_status"] == WorkflowTaskState.SKIPPED.value + for workflow in result)) + + result = WorkflowTaskStatus.from_taskrun(cmd, + taskrun_client, + registry, + scan_taskruns, + patch_taskruns, + workflow_status_filter=WorkflowTaskState.FAILED.value) + self.assertTrue(len(result) > 0) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.FAILED.value or + workflow["patch_status"] == WorkflowTaskState.FAILED.value + for workflow in result)) + + result = WorkflowTaskStatus.from_taskrun(cmd, + taskrun_client, + registry, + scan_taskruns, + patch_taskruns, + workflow_status_filter=WorkflowTaskState.RUNNING.value) + self.assertTrue(len(result) > 0) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.RUNNING.value or + workflow["patch_status"] == WorkflowTaskState.RUNNING.value or + workflow["scan_status"] == WorkflowTaskState.QUEUED.value or + workflow["patch_status"] == WorkflowTaskState.QUEUED.value + for workflow in result)) + + result = WorkflowTaskStatus.from_taskrun(cmd, + taskrun_client, + registry, + scan_taskruns, + patch_taskruns, + workflow_status_filter=WorkflowTaskState.CANCELED.value) + self.assertTrue(len(result) > 0) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.CANCELED.value or + workflow["patch_status"] == WorkflowTaskState.CANCELED.value + for workflow in result)) + + result = WorkflowTaskStatus.from_taskrun(cmd, + taskrun_client, + registry, + scan_taskruns, + patch_taskruns, + workflow_status_filter=WorkflowTaskState.SKIPPED.value) + self.assertTrue(len(result) > 0) + self.assertTrue(all(workflow["scan_status"] == WorkflowTaskState.SUCCEEDED.value and + workflow["patch_status"] == WorkflowTaskState.SKIPPED.value + for workflow in result)) + + + # generate a random scan or patch taskrun with the desired properties + def _generate_test_taskrun(self, scan_task=True, status=TaskRunStatus.Succeeded.value, repository="mock-repo", tag="mock-tag", patch_taskid_in_scan=""): + import random + import string + import datetime + taskrun = MagicMock() + taskrun.status = status + taskrun.create_time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ") + + letters = ''.join(random.choices(string.ascii_lowercase, k=3)) + number = random.randint(0, 9) + taskrun.run_id = f"{letters}{number}" + task_log_result = "" + + if scan_task: + task_log_result = f"Scanning image for vulnerability and patch {repository}:{tag} for tag {tag}" + task_log_result += f"\nScanning repo: {repository}, Tag:{tag}, OriginalTag:{tag}" + if taskrun.status == TaskRunStatus.Failed.value or taskrun.status == TaskRunStatus.Error.value: + task_log_result += "\nerror: mock error on scan" + elif taskrun.status == TaskRunStatus.Succeeded.value: + task_log_result += "\nmock patch logs" + else: + task_log_result += "\ngeneric mock scan logs" + if patch_taskid_in_scan != "": + task_log_result += f"\nPATCHING task scheduled for image {repository}:{tag}, new patch tag will be {tag}-patched" + task_log_result += f"\nWARNING: Queued a run with ID: {patch_taskid_in_scan}" + + else: + task_log_result += f"Patching OS vulnerabilities for image {repository}:{tag}" + if taskrun.status == TaskRunStatus.Failed.value or taskrun.status == TaskRunStatus.Error.value: + task_log_result += "\nerror: mock error on patch" + elif taskrun.status == TaskRunStatus.Succeeded.value: + task_log_result += f"\nPATCHING task scheduled for image {repository}:{tag}, new patch tag will be {tag}-patched" + else: + task_log_result += "\nmock patch logs" + + taskrun.task_log_result = task_log_result + + return taskrun + + @mock.patch('azext_acrcssc.helper._workflow_status.WorkflowTaskStatus._download_logs') + @mock.patch('azext_acrcssc.helper._workflow_status.get_sdk') + @mock.patch('azure.cli.core.profiles.get_sdk') + def test_generate_logs(self, mock_core_get_sdk, mock_wf_get_sdk, mock_download_logs): + cmd = mock.MagicMock() + cmd.cli_ctx = DummyCli() + client = mock.MagicMock() + run_id = "cgb5" + registry_name = "myregistry" + resource_group_name = "myresourcegroup" + + # Mock the response from client.get_log_sas_url() + response = mock.MagicMock() + response.log_link = "https://example.com/logs" + client.get_log_sas_url.return_value = response + + run_response = mock.MagicMock() + run_response.status = "Succeeded" + client.get.return_value = run_response + + # Create a mock for the blob client + mock_blob_client = mock.MagicMock() + #mock_blob_client.from_blob_url = mock.MagicMock() + mock_blob_client.from_blob_url.return_value = "mock_blob_client" + + mock_core_get_sdk.return_value = mock_blob_client + mock_wf_get_sdk.return_value = mock_blob_client + mock_download_logs.return_value = "mock logs" + + # Call the function + result = WorkflowTaskStatus.generate_logs(cmd, client, run_id, registry_name, resource_group_name) + + # Assert the function calls + mock_download_logs.assert_called() + mock_blob_client.from_blob_url.assert_called() + client.get_log_sas_url.assert_called() + self.assertEqual(result, "mock logs") diff --git a/src/acrcssc/setup.cfg b/src/acrcssc/setup.cfg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/acrcssc/setup.py b/src/acrcssc/setup.py new file mode 100644 index 00000000000..c03ee877499 --- /dev/null +++ b/src/acrcssc/setup.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from codecs import open +from setuptools import setup, find_packages +try: + from azure_bdist_wheel import cmdclass +except ImportError: + from distutils import log as logger + logger.warn("Wheel is not available, disabling bdist_wheel hook") + +VERSION = '1.0.0b1' + +# The full list of classifiers is available at +# https://pypi.python.org/pypi?%3Aaction=list_classifiers +CLASSIFIERS = [ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'License :: OSI Approved :: MIT License', +] + +# TODO: Add any additional SDK dependencies here +DEPENDENCIES = ["oras==0.2.25", "croniter~=3.0.0"] + +with open('README.rst', 'r', encoding='utf-8') as f: + README = f.read() +with open('HISTORY.rst', 'r', encoding='utf-8') as f: + HISTORY = f.read() + +setup( + name='acrcssc', + version=VERSION, + description='Microsoft Azure Container Registry Container Secure Supply Chain (CSSC) Extension', + author='Microsoft Corporation', + author_email='kraterdev@microsoft.com', + url='https://github.com/Azure/azure-cli-extensions/tree/master/src/acrcssc', + long_description=README + '\n\n' + HISTORY, + license='MIT', + classifiers=CLASSIFIERS, + packages=find_packages(), + install_requires=DEPENDENCIES, + package_data={ + 'azext_acrcssc': [ + "azext_metadata.json", + "templates/tmp_dry_run_template.yaml", + "templates/arm/*", + "templates/task/*" + ] + } +)