From 9ed61b254613df7ebbecea46ae2521cb636c7252 Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Thu, 19 Oct 2023 10:02:45 -0700 Subject: [PATCH 1/8] add check blob function --- .../azure/cli/command_modules/acr/_params.py | 4 + .../cli/command_modules/acr/check_health.py | 106 ++++++++++++++++-- 2 files changed, 103 insertions(+), 7 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_params.py b/src/azure-cli/azure/cli/command_modules/acr/_params.py index 2f509cea913..b803d9d0759 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_params.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_params.py @@ -424,6 +424,10 @@ def load_arguments(self, _): # pylint: disable=too-many-statements c.argument('ignore_errors', options_list=['--ignore-errors'], help='Provide all health checks, even if errors are found', action='store_true', required=False) c.argument('vnet', options_list=['--vnet'], help="Virtual network ID so to run this command inside a VNET to verify the DNS routing to private endpoints", required=False) + c.argument('registry_name', options_list=['--name', '-n'], help="The name of the registry.") + c.argument('repository_name', options_list=['--repository', '-r'], help="The target repository namespace such as 'ubuntu'.") + c.argument('image', options_list=['--image','-t'], + help="The digest of the manifest such as '--image sha256@abc123', or the tag such as '-t latest'") with self.argument_context('acr scope-map') as c: c.argument('registry_name', options_list=['--registry', '-r']) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index a9b213b0df6..0abd714ea17 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -70,7 +70,7 @@ def _subprocess_communicate(command_parts, shell=False): # Checks docker command, docker daemon, docker version and docker pull def _get_docker_status_and_version(ignore_errors, yes): from ._errors import DOCKER_DAEMON_ERROR, DOCKER_PULL_ERROR, DOCKER_VERSION_ERROR - + print_pass("Get docker status") # Docker command and docker daemon check docker_command, error = get_docker_command(is_diagnostics_context=True) docker_daemon_available = True @@ -126,7 +126,7 @@ def _get_docker_status_and_version(ignore_errors, yes): def _get_cli_version(): from azure.cli.core import __version__ as core_version logger.warning('Azure CLI version: %s', core_version) - +print_pass("Get CLI version") # Get helm versions def _get_helm_version(ignore_errors): @@ -292,9 +292,9 @@ def _get_endpoint_and_token_status(cmd, login_server, ignore_errors): print_pass("Fetch refresh token for registry '{}'".format(login_server)) print_pass("Fetch access token for registry '{}'".format(login_server)) - def _check_registry_health(cmd, registry_name, ignore_errors): from azure.cli.core.profiles import ResourceType + print_pass("Check registry health") if registry_name is None: logger.warning("Registry name must be provided to check connectivity.") return @@ -343,7 +343,7 @@ def _check_registry_health(cmd, registry_name, ignore_errors): def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # pylint: disable=too-many-locals, too-many-statements import socket from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id - + print_pass("Check private endpoint") if registry_name is None: raise CLIError("Registry name must be provided to verify DNS routings of its private endpoints") @@ -415,23 +415,116 @@ def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # py print_pass('DNS routing to private endpoint') else: raise CLIError('DNS routing verification failed') + +# Validate if specific blob can be pulled +def _check_blob_exists(cmd, + registry_name, + repository_name, + image): + import sys + import requests + from .repository import get_access_credentials + print_pass("Check blob exists") + if registry_name is None: + raise CLIError("Registry name must be provided to verify if image exists in registry.") + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) + login_server = registry.login_server.rstrip('/') + + if repository_name is None: + raise CLIError("Repository name must be provided to verify if image exists in registry.") + + if image is None: + raise CLIError("Image or tag must be provided to verify if image exists in registry.") + + # Get the access credentials for the registry + registry_name, username, password = get_access_credentials( + cmd, + registry_name=registry_name, + tenant_suffix=None, + username=None, + password=None, + repository=repository_name, + permission='pull') + + # Get manifest + # GET {url}/v2/{name}/manifests/{reference} + manifest_url = 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, image) + + response = requests.get( + manifest_url, + headers={'Accept': 'application/vnd.oci.artifact.manifest.v1+json' + ', application/vnd.cncf.oras.artifact.manifest.v1+json' + ', application/vnd.oci.image.manifest.v1+json' + ', application/vnd.oci.image.index.v1+json' + ', application/vnd.docker.distribution.manifest.v2+json' + ', application/vnd.docker.distribution.manifest.list.v2+json'}, + auth=(username, password)) + + manifest = response.json() + + # get the digest of the smallest blob for performance purposes + # check if manifest has been pulled using a tag or digest - may not need this + def get_smallest_blob_digest(manifest): + # check if manifest has fsLayers which indicates that the manifest was pulled using a tag + if 'fsLayers' in manifest: + # Find the smallest layer in the manifest + smallest_blob = {'digest': '', 'size': sys.maxsize} + for layer in manifest['fsLayers']: + layer_digest = layer['blobSum'] + + # Find the smallest blob + layer_size_url = 'https://{}/v2/{}/blobs/{}'.format(login_server, repository_name, layer_digest) + layer_size_response = requests.head(layer_size_url, auth=(username, password)) + layer_size = int(layer_size_response.headers['Content-Length']) + + + if layer_size < smallest_blob['size'] : + # Get the digest number of the smallest blob + smallest_blob = {'digest': layer_digest, 'size': layer_size} + + return smallest_blob['digest'] + else: + # Find the smallest blob when user pulls using a digest + smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) + smallest_blob_digest = smallest_blob['digest'] + + return smallest_blob_digest + + digest = get_smallest_blob_digest(manifest) + + # Pull blob - GET {url}/v2/{name}/blobs/{digest} + request_url = 'https://' + login_server + '/v2/' + repository_name + '/blobs/' + digest + + logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) + + response = requests.get(request_url, auth=(username, password)) + + if response.status_code < 400: + print_pass("The blob identified by image {} is available to pull from registry {}.".format(image, login_server)) + else: + raise CLIError("'Blob identified by image {} cannot be pulled from registry {}.".format(image, login_server)) # General command def acr_check_health(cmd, # pylint: disable useless-return vnet=None, ignore_errors=False, yes=False, - registry_name=None): + registry_name=None, + repository_name=None, + image=None): from azure.cli.core.util import in_cloud_console + print_pass("Check health 1 passed") in_cloud_console = in_cloud_console() if in_cloud_console: logger.warning("Environment checks are not supported in Azure Cloud Shell.") else: + print_pass("Check health 2 passed") _get_docker_status_and_version(ignore_errors, yes) _get_cli_version() - + _check_registry_health(cmd, registry_name, ignore_errors) + _check_blob_exists(cmd, registry_name, repository_name, image) if vnet: _check_private_endpoint(cmd, registry_name, vnet) @@ -439,5 +532,4 @@ def acr_check_health(cmd, # pylint: disable useless-return if not in_cloud_console: _get_helm_version(ignore_errors) _get_notary_version(ignore_errors) - logger.warning(FAQ_MESSAGE) From 7e4f85454d8bfe6589815a78fc16c69d32f454f1 Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Tue, 24 Oct 2023 15:32:39 -0700 Subject: [PATCH 2/8] add check blob function in check-health --- .../azure/cli/command_modules/acr/_help.py | 6 + .../azure/cli/command_modules/acr/_params.py | 2 +- .../cli/command_modules/acr/check_health.py | 126 ++++++++++-------- 3 files changed, 77 insertions(+), 57 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index f1b2c23e70a..a59d33ea20c 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -49,6 +49,12 @@ - name: Gets health state of the environment, without stopping on first error. text: > az acr check-health --ignore-errors + - name: Verifies if specific blob identified by image 'sha256:abc123' is available to pull from the repository. + text: > + az acr check-health -n MyRegistry -r MyRepository --image sha256:abc123 + - name: Verifies if specific blob identified by tag 'latest' is available to pull from the repository. + text: > + az acr check-health -n MyRegistry -r MyRepository -t latest """ helps['acr check-name'] = """ diff --git a/src/azure-cli/azure/cli/command_modules/acr/_params.py b/src/azure-cli/azure/cli/command_modules/acr/_params.py index b803d9d0759..6552b3ad84f 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_params.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_params.py @@ -427,7 +427,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements c.argument('registry_name', options_list=['--name', '-n'], help="The name of the registry.") c.argument('repository_name', options_list=['--repository', '-r'], help="The target repository namespace such as 'ubuntu'.") c.argument('image', options_list=['--image','-t'], - help="The digest of the manifest such as '--image sha256@abc123', or the tag such as '-t latest'") + help="The image digest of the manifest such as '--image sha256@abc123', or the tag such as '-t latest'") with self.argument_context('acr scope-map') as c: c.argument('registry_name', options_list=['--registry', '-r']) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 0abd714ea17..5d5a3282041 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -26,7 +26,8 @@ RECOMMENDED_NOTARY_VERSION = "0.6.0" NOTARY_VERSION_REGEX = re.compile(r'Version:\s+([.\d]+)') DOCKER_PULL_WRONG_PLATFORM = 'cannot be used on this platform' - +IMAGE_INPUT_ERROR_MESSAGE = "The specified image tag was not found. Please check image name for --image." +REPOSITORY_INPUT_ERROR_MESSAGE = "Invalid repository name. Please check repository name for --repository." # Utilities functions def print_pass(message): @@ -70,7 +71,6 @@ def _subprocess_communicate(command_parts, shell=False): # Checks docker command, docker daemon, docker version and docker pull def _get_docker_status_and_version(ignore_errors, yes): from ._errors import DOCKER_DAEMON_ERROR, DOCKER_PULL_ERROR, DOCKER_VERSION_ERROR - print_pass("Get docker status") # Docker command and docker daemon check docker_command, error = get_docker_command(is_diagnostics_context=True) docker_daemon_available = True @@ -126,7 +126,6 @@ def _get_docker_status_and_version(ignore_errors, yes): def _get_cli_version(): from azure.cli.core import __version__ as core_version logger.warning('Azure CLI version: %s', core_version) -print_pass("Get CLI version") # Get helm versions def _get_helm_version(ignore_errors): @@ -294,7 +293,7 @@ def _get_endpoint_and_token_status(cmd, login_server, ignore_errors): def _check_registry_health(cmd, registry_name, ignore_errors): from azure.cli.core.profiles import ResourceType - print_pass("Check registry health") + if registry_name is None: logger.warning("Registry name must be provided to check connectivity.") return @@ -343,7 +342,7 @@ def _check_registry_health(cmd, registry_name, ignore_errors): def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # pylint: disable=too-many-locals, too-many-statements import socket from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id - print_pass("Check private endpoint") + if registry_name is None: raise CLIError("Registry name must be provided to verify DNS routings of its private endpoints") @@ -415,38 +414,68 @@ def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # py print_pass('DNS routing to private endpoint') else: raise CLIError('DNS routing verification failed') + +# Validate inputs for --repository and --image +def validate_repository_and_image(cmd, registry_name, repository_name, image): + from .repository import get_access_credentials + from ._docker_utils import request_data_from_registry + from azure.cli.core.azclierror import ResourceNotFoundError + + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) + login_server = registry.login_server.rstrip('/') + path = '/v2/' + repository_name + '/manifests/' + image + + # Get the access credentials for the registry + registry_name, username, password = get_access_credentials( + cmd, + registry_name=registry_name, + tenant_suffix=None, + username=None, + password=None, + repository=repository_name, + permission='pull') + try: + request_data_from_registry( + http_method='get', + login_server=login_server, + path=path, + username=username, + password=password, + json_payload=None, + file_payload=None, + manifest_headers={'Accept': 'application/vnd.docker.distribution.manifest.v2+json'}, + params=image) + except CLIError as e: + # Error is due to the image tag not being found on manifest + if "manifest tagged by" in str(e): + raise ResourceNotFoundError(IMAGE_INPUT_ERROR_MESSAGE) + # Error is due to the repository not being found + else: + raise ResourceNotFoundError(REPOSITORY_INPUT_ERROR_MESSAGE) + # Validate if specific blob can be pulled def _check_blob_exists(cmd, registry_name, repository_name, image): - import sys + import requests from .repository import get_access_credentials - print_pass("Check blob exists") - if registry_name is None: - raise CLIError("Registry name must be provided to verify if image exists in registry.") - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) login_server = registry.login_server.rstrip('/') - if repository_name is None: - raise CLIError("Repository name must be provided to verify if image exists in registry.") - - if image is None: - raise CLIError("Image or tag must be provided to verify if image exists in registry.") - # Get the access credentials for the registry registry_name, username, password = get_access_credentials( - cmd, - registry_name=registry_name, - tenant_suffix=None, - username=None, - password=None, - repository=repository_name, - permission='pull') - + cmd, + registry_name=registry_name, + tenant_suffix=None, + username=None, + password=None, + repository=repository_name, + permission='pull') + # Get manifest # GET {url}/v2/{name}/manifests/{reference} manifest_url = 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, image) @@ -460,37 +489,17 @@ def _check_blob_exists(cmd, ', application/vnd.docker.distribution.manifest.v2+json' ', application/vnd.docker.distribution.manifest.list.v2+json'}, auth=(username, password)) - + manifest = response.json() - # get the digest of the smallest blob for performance purposes - # check if manifest has been pulled using a tag or digest - may not need this + # Get the digest of the smallest blob for performance purposes def get_smallest_blob_digest(manifest): - # check if manifest has fsLayers which indicates that the manifest was pulled using a tag - if 'fsLayers' in manifest: - # Find the smallest layer in the manifest - smallest_blob = {'digest': '', 'size': sys.maxsize} - for layer in manifest['fsLayers']: - layer_digest = layer['blobSum'] - - # Find the smallest blob - layer_size_url = 'https://{}/v2/{}/blobs/{}'.format(login_server, repository_name, layer_digest) - layer_size_response = requests.head(layer_size_url, auth=(username, password)) - layer_size = int(layer_size_response.headers['Content-Length']) - - - if layer_size < smallest_blob['size'] : - # Get the digest number of the smallest blob - smallest_blob = {'digest': layer_digest, 'size': layer_size} - - return smallest_blob['digest'] - else: - # Find the smallest blob when user pulls using a digest - smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) - smallest_blob_digest = smallest_blob['digest'] + + smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) + smallest_blob_digest = smallest_blob['digest'] + + return smallest_blob_digest - return smallest_blob_digest - digest = get_smallest_blob_digest(manifest) # Pull blob - GET {url}/v2/{name}/blobs/{digest} @@ -501,9 +510,9 @@ def get_smallest_blob_digest(manifest): response = requests.get(request_url, auth=(username, password)) if response.status_code < 400: - print_pass("The blob identified by image {} is available to pull from registry {}.".format(image, login_server)) + print_pass("Blob identified by image '{}' is available to pull from registry '{}'".format(image, login_server)) else: - raise CLIError("'Blob identified by image {} cannot be pulled from registry {}.".format(image, login_server)) + raise CLIError("'Blob identified by image '{}' cannot be pulled from registry '{}'".format(image, login_server)) # General command def acr_check_health(cmd, # pylint: disable useless-return @@ -514,17 +523,22 @@ def acr_check_health(cmd, # pylint: disable useless-return repository_name=None, image=None): from azure.cli.core.util import in_cloud_console - print_pass("Check health 1 passed") + + # If repository and image are provided, validate them first before running other checks + if (image and repository_name): + validate_repository_and_image(cmd, registry_name, repository_name, image) + in_cloud_console = in_cloud_console() if in_cloud_console: logger.warning("Environment checks are not supported in Azure Cloud Shell.") else: - print_pass("Check health 2 passed") _get_docker_status_and_version(ignore_errors, yes) _get_cli_version() _check_registry_health(cmd, registry_name, ignore_errors) - _check_blob_exists(cmd, registry_name, repository_name, image) + + if image and repository_name: + _check_blob_exists(cmd, registry_name, repository_name, image) if vnet: _check_private_endpoint(cmd, registry_name, vnet) From fe7a8cadeb17d1f7d44b55d171953cd41fdbd05f Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Tue, 31 Oct 2023 17:36:56 -0700 Subject: [PATCH 3/8] add check blob function --- .../azure/cli/command_modules/acr/_help.py | 4 +- .../cli/command_modules/acr/check_health.py | 112 ++++++++++++------ 2 files changed, 76 insertions(+), 40 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index a59d33ea20c..ca5903965c5 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -49,10 +49,10 @@ - name: Gets health state of the environment, without stopping on first error. text: > az acr check-health --ignore-errors - - name: Verifies if specific blob identified by image 'sha256:abc123' is available to pull from the repository. + - name: Verifies if specific artifact identified by image 'sha256:abc123' is available to pull from the repository. text: > az acr check-health -n MyRegistry -r MyRepository --image sha256:abc123 - - name: Verifies if specific blob identified by tag 'latest' is available to pull from the repository. + - name: Verifies if specific artifact identified by tag 'latest' is available to pull from the repository. text: > az acr check-health -n MyRegistry -r MyRepository -t latest """ diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 5d5a3282041..54cc7170507 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -415,18 +415,21 @@ def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # py else: raise CLIError('DNS routing verification failed') -# Validate inputs for --repository and --image -def validate_repository_and_image(cmd, registry_name, repository_name, image): - from .repository import get_access_credentials - from ._docker_utils import request_data_from_registry - from azure.cli.core.azclierror import ResourceNotFoundError - - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) +# Validate --image input +def validate_image(cmd, registry_name, repository_name, image): + from .repository import get_access_credentials, acr_repository_show_tags, _get_manifest_path, _obtain_data_from_registry + from ._docker_utils import request_data_from_registry, get_manifest_authorization_header, RegistryException + from ._utils import get_resource_group_name_by_registry_name + from difflib import get_close_matches + + rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, None) + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) login_server = registry.login_server.rstrip('/') - path = '/v2/' + repository_name + '/manifests/' + image - # Get the access credentials for the registry - registry_name, username, password = get_access_credentials( + path = '/v2/' + repository_name + '/manifests/'+ image + + # Get the access credentials for the registry + login_server, username, password = get_access_credentials( cmd, registry_name=registry_name, tenant_suffix=None, @@ -434,7 +437,7 @@ def validate_repository_and_image(cmd, registry_name, repository_name, image): password=None, repository=repository_name, permission='pull') - + try: request_data_from_registry( http_method='get', @@ -444,26 +447,61 @@ def validate_repository_and_image(cmd, registry_name, repository_name, image): password=password, json_payload=None, file_payload=None, - manifest_headers={'Accept': 'application/vnd.docker.distribution.manifest.v2+json'}, + manifest_headers=get_manifest_authorization_header(username, password), params=image) - except CLIError as e: - # Error is due to the image tag not being found on manifest - if "manifest tagged by" in str(e): - raise ResourceNotFoundError(IMAGE_INPUT_ERROR_MESSAGE) - # Error is due to the repository not being found + + except RegistryException as e: + if e.status_code == 404: + # If tag is used, get all tags + if 'sha256' not in image: + tags = acr_repository_show_tags( + cmd, + registry_name=registry_name, + repository=repository_name, + orderby=None, + username=username, + password=password) + # Get a list of tags that have at least 20% similarity with the inputted image name + matches = get_close_matches(image, tags, n=1, cutoff=0.2) + if matches: + raise CLIError("Tag not found: {}. Did you mean to input '{}'?".format(image, matches[0])) + else: + raise CLIError("Invalid tag: {}".format(str(e))) + + # If digest is used, get all digests + else: + image_digest_list = _obtain_data_from_registry( + login_server=login_server, + path=_get_manifest_path(repository_name), + username=username, + password=password, + result_index='manifests', + orderby=None) + + # Get a list of digests that have at least 20% similarity with the inputted image name + digests = [item['digest'] for item in image_digest_list] + matches = get_close_matches(image, digests, n=1, cutoff=0.2) + # if there is a match, give a suggestion on the intended image name + if matches: + raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) + else: + raise CLIError("Invalid image: {}".format(str(e))) + # if the error is not 404, raise the appropriate error from backend else: - raise ResourceNotFoundError(REPOSITORY_INPUT_ERROR_MESSAGE) + raise -# Validate if specific blob can be pulled -def _check_blob_exists(cmd, - registry_name, - repository_name, - image): +# Validate if specific artifact can be pulled +def _check_artifact(cmd, + registry_name, + repository_name, + image): import requests from .repository import get_access_credentials + from ._utils import get_resource_group_name_by_registry_name - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) + rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, None) + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) login_server = registry.login_server.rstrip('/') # Get the access credentials for the registry @@ -480,7 +518,7 @@ def _check_blob_exists(cmd, # GET {url}/v2/{name}/manifests/{reference} manifest_url = 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, image) - response = requests.get( + manifest_response = requests.get( manifest_url, headers={'Accept': 'application/vnd.oci.artifact.manifest.v1+json' ', application/vnd.cncf.oras.artifact.manifest.v1+json' @@ -490,29 +528,29 @@ def _check_blob_exists(cmd, ', application/vnd.docker.distribution.manifest.list.v2+json'}, auth=(username, password)) - manifest = response.json() + manifest = manifest_response.json() # Get the digest of the smallest blob for performance purposes - def get_smallest_blob_digest(manifest): + def get_smallest_artifact_digest(manifest): smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) smallest_blob_digest = smallest_blob['digest'] return smallest_blob_digest - digest = get_smallest_blob_digest(manifest) + digest = get_smallest_artifact_digest(manifest) # Pull blob - GET {url}/v2/{name}/blobs/{digest} request_url = 'https://' + login_server + '/v2/' + repository_name + '/blobs/' + digest logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) - response = requests.get(request_url, auth=(username, password)) + res = requests.get(request_url, auth=(username, password)) - if response.status_code < 400: - print_pass("Blob identified by image '{}' is available to pull from registry '{}'".format(image, login_server)) + if res.status_code < 400: + print_pass("Artifact identified by image '{}' is available to pull from registry '{}'".format(image, login_server)) else: - raise CLIError("'Blob identified by image '{}' cannot be pulled from registry '{}'".format(image, login_server)) + raise CLIError("'Artifact identified by image '{}' cannot be pulled from registry '{}'".format(image, login_server)) # General command def acr_check_health(cmd, # pylint: disable useless-return @@ -524,10 +562,6 @@ def acr_check_health(cmd, # pylint: disable useless-return image=None): from azure.cli.core.util import in_cloud_console - # If repository and image are provided, validate them first before running other checks - if (image and repository_name): - validate_repository_and_image(cmd, registry_name, repository_name, image) - in_cloud_console = in_cloud_console() if in_cloud_console: logger.warning("Environment checks are not supported in Azure Cloud Shell.") @@ -537,8 +571,10 @@ def acr_check_health(cmd, # pylint: disable useless-return _check_registry_health(cmd, registry_name, ignore_errors) - if image and repository_name: - _check_blob_exists(cmd, registry_name, repository_name, image) + # If repository and image are provided, validate image input + if (image and repository_name): + validate_image(cmd, registry_name, repository_name, image) + _check_artifact(cmd, registry_name, repository_name, image) if vnet: _check_private_endpoint(cmd, registry_name, vnet) From 61a9b1e985e5b936be5345d5522dd7fe45156dec Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Mon, 6 Nov 2023 16:50:18 -0800 Subject: [PATCH 4/8] changed help text, added validation for image --- .../azure/cli/command_modules/acr/_help.py | 4 +- .../cli/command_modules/acr/check_health.py | 128 +++++++++--------- 2 files changed, 69 insertions(+), 63 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index ca5903965c5..eb56e94ecd8 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -49,10 +49,10 @@ - name: Gets health state of the environment, without stopping on first error. text: > az acr check-health --ignore-errors - - name: Verifies if specific artifact identified by image 'sha256:abc123' is available to pull from the repository. + - name: Verify that blobs within a given image 'sha256:abc123' can be downloaded from the repository. text: > az acr check-health -n MyRegistry -r MyRepository --image sha256:abc123 - - name: Verifies if specific artifact identified by tag 'latest' is available to pull from the repository. + - name: Verify that blobs within a given tag 'latest' can be downloaded from the repository. text: > az acr check-health -n MyRegistry -r MyRepository -t latest """ diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 54cc7170507..3d3ad4c8bf7 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -26,8 +26,6 @@ RECOMMENDED_NOTARY_VERSION = "0.6.0" NOTARY_VERSION_REGEX = re.compile(r'Version:\s+([.\d]+)') DOCKER_PULL_WRONG_PLATFORM = 'cannot be used on this platform' -IMAGE_INPUT_ERROR_MESSAGE = "The specified image tag was not found. Please check image name for --image." -REPOSITORY_INPUT_ERROR_MESSAGE = "Invalid repository name. Please check repository name for --repository." # Utilities functions def print_pass(message): @@ -67,6 +65,10 @@ def _subprocess_communicate(command_parts, shell=False): return output, warning, stderr +# Retrieve blob identified by digest - GET {url}/v2/{name}/blobs/{digest} +def _get_blob(login_server, repository_name, digest): + return 'https://{}/v2/{}/blobs/{}'.format(login_server, repository_name, digest) + # Checks for the environment # Checks docker command, docker daemon, docker version and docker pull def _get_docker_status_and_version(ignore_errors, yes): @@ -417,17 +419,27 @@ def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # py # Validate --image input def validate_image(cmd, registry_name, repository_name, image): - from .repository import get_access_credentials, acr_repository_show_tags, _get_manifest_path, _obtain_data_from_registry - from ._docker_utils import request_data_from_registry, get_manifest_authorization_header, RegistryException - from ._utils import get_resource_group_name_by_registry_name from difflib import get_close_matches + from ._utils import get_resource_group_name_by_registry_name + from .manifest import _get_v2_manifest_path + + from ._docker_utils import ( + request_data_from_registry, + get_manifest_authorization_header, + RegistryException + ) + + from .repository import ( + get_access_credentials, + acr_repository_show_tags, + _get_manifest_path, + _obtain_data_from_registry + ) rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, None) - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) login_server = registry.login_server.rstrip('/') - path = '/v2/' + repository_name + '/manifests/'+ image - # Get the access credentials for the registry login_server, username, password = get_access_credentials( cmd, @@ -442,17 +454,18 @@ def validate_image(cmd, registry_name, repository_name, image): request_data_from_registry( http_method='get', login_server=login_server, - path=path, + path=_get_v2_manifest_path(repository_name, image), username=username, password=password, json_payload=None, file_payload=None, manifest_headers=get_manifest_authorization_header(username, password), params=image) - + except RegistryException as e: if e.status_code == 404: # If tag is used, get all tags + # TO DO: Make this into its own function and then call it if 'sha256' not in image: tags = acr_repository_show_tags( cmd, @@ -461,41 +474,38 @@ def validate_image(cmd, registry_name, repository_name, image): orderby=None, username=username, password=password) - # Get a list of tags that have at least 20% similarity with the inputted image name - matches = get_close_matches(image, tags, n=1, cutoff=0.2) + # Get a list of tags that have at least 80% similarity with the inputted image name + matches = get_close_matches(image, tags, n=1, cutoff=0.8) if matches: raise CLIError("Tag not found: {}. Did you mean to input '{}'?".format(image, matches[0])) - else: - raise CLIError("Invalid tag: {}".format(str(e))) - + raise CLIError("Invalid tag: {}".format(str(e))) + # If digest is used, get all digests - else: - image_digest_list = _obtain_data_from_registry( - login_server=login_server, - path=_get_manifest_path(repository_name), - username=username, - password=password, - result_index='manifests', - orderby=None) - - # Get a list of digests that have at least 20% similarity with the inputted image name - digests = [item['digest'] for item in image_digest_list] - matches = get_close_matches(image, digests, n=1, cutoff=0.2) - # if there is a match, give a suggestion on the intended image name - if matches: - raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) - else: - raise CLIError("Invalid image: {}".format(str(e))) + image_digest_list = _obtain_data_from_registry( + login_server=login_server, + path=_get_manifest_path(repository_name), + username=username, + password=password, + result_index='manifests', + orderby=None) + + # Get a list of digests that have at least 20% similarity with the inputted image name + digests = [item['digest'] for item in image_digest_list] + matches = get_close_matches(image, digests, n=1, cutoff=0.2) + #TO DO: Need to change this to 80% match not 20% + # if there is a match, give a suggestion on the intended image name + if matches: + raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) + raise CLIError("Invalid image: {}".format(str(e))) # if the error is not 404, raise the appropriate error from backend - else: - raise - -# Validate if specific artifact can be pulled -def _check_artifact(cmd, - registry_name, - repository_name, - image): - + raise + +# Validate if specific blob can be pulled +def _check_blob(cmd, + registry_name, + repository_name, + image): + import requests from .repository import get_access_credentials from ._utils import get_resource_group_name_by_registry_name @@ -513,11 +523,11 @@ def _check_artifact(cmd, password=None, repository=repository_name, permission='pull') - + # Get manifest # GET {url}/v2/{name}/manifests/{reference} manifest_url = 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, image) - + manifest_response = requests.get( manifest_url, headers={'Accept': 'application/vnd.oci.artifact.manifest.v1+json' @@ -527,30 +537,26 @@ def _check_artifact(cmd, ', application/vnd.docker.distribution.manifest.v2+json' ', application/vnd.docker.distribution.manifest.list.v2+json'}, auth=(username, password)) - + manifest = manifest_response.json() # Get the digest of the smallest blob for performance purposes - def get_smallest_artifact_digest(manifest): - - smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) - smallest_blob_digest = smallest_blob['digest'] - - return smallest_blob_digest + smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) + digest = smallest_blob['digest'] - digest = get_smallest_artifact_digest(manifest) + # Get blob + # request_url = 'https://' + login_server + '/v2/' + repository_name + '/blobs/' + digest + request_url = _get_blob(login_server, repository_name, digest) - # Pull blob - GET {url}/v2/{name}/blobs/{digest} - request_url = 'https://' + login_server + '/v2/' + repository_name + '/blobs/' + digest - logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) - + res = requests.get(request_url, auth=(username, password)) - - if res.status_code < 400: - print_pass("Artifact identified by image '{}' is available to pull from registry '{}'".format(image, login_server)) + if res.status_code < 400 and 'sha256' not in image: + print_pass("Blobs within the tag '{}' can be pulled from registry '{}'".format(image, login_server)) + elif res.status_code < 400: + print_pass("Blobs in image '{}' can be pulled from registry '{}'".format(image, login_server)) else: - raise CLIError("'Artifact identified by image '{}' cannot be pulled from registry '{}'".format(image, login_server)) + raise CLIError("'Blobs in image '{}' cannot be pulled from registry '{}'".format(image, login_server)) # General command def acr_check_health(cmd, # pylint: disable useless-return @@ -568,13 +574,13 @@ def acr_check_health(cmd, # pylint: disable useless-return else: _get_docker_status_and_version(ignore_errors, yes) _get_cli_version() - + _check_registry_health(cmd, registry_name, ignore_errors) # If repository and image are provided, validate image input if (image and repository_name): validate_image(cmd, registry_name, repository_name, image) - _check_artifact(cmd, registry_name, repository_name, image) + _check_blob(cmd, registry_name, repository_name, image) if vnet: _check_private_endpoint(cmd, registry_name, vnet) From b7be29d90b72b4cec28f27a15164d0857da9e715 Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Thu, 16 Nov 2023 10:28:57 -0800 Subject: [PATCH 5/8] 'adding check-health command and test' --- .../cli/command_modules/acr/check_health.py | 259 +++++++++--------- .../latest/test_acr_check_health_commands.py | 35 +++ 2 files changed, 170 insertions(+), 124 deletions(-) create mode 100644 src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 3d3ad4c8bf7..a6906c04a85 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- import re + from knack.util import CLIError from knack.log import get_logger from .custom import get_docker_command @@ -69,6 +70,52 @@ def _subprocess_communicate(command_parts, shell=False): def _get_blob(login_server, repository_name, digest): return 'https://{}/v2/{}/blobs/{}'.format(login_server, repository_name, digest) +# Checks inputted image or tag for possible matches +def _check_image_match(cmd, + registry_name, + repository_name, + login_server, + username, + password, + image): + from difflib import get_close_matches + from .manifest import _get_manifest_path + from .repository import( + acr_repository_show_tags, + _obtain_data_from_registry) + + if 'sha256' not in image: + tags = acr_repository_show_tags( + cmd, + registry_name=registry_name, + repository=repository_name, + orderby=None, + username=username, + password=password) + # Get a list of tags that have at least 80% similarity with the inputted image name + matches = get_close_matches(image, tags, n=1, cutoff=0.8) + + if matches: + raise CLIError("Tag '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) + return + + # If digest is used, get all digests + image_digest_list = _obtain_data_from_registry( + login_server=login_server, + path=_get_manifest_path(repository_name), + username=username, + password=password, + result_index='manifests', + orderby=None) + + # Get a list of digests that have at least 80% similarity with the inputted image name + digests = [item['digest'] for item in image_digest_list] + matches = get_close_matches(image, digests, n=1, cutoff=0.8) + + if matches: + raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) + return + # Checks for the environment # Checks docker command, docker daemon, docker version and docker pull def _get_docker_status_and_version(ignore_errors, yes): @@ -293,29 +340,13 @@ def _get_endpoint_and_token_status(cmd, login_server, ignore_errors): print_pass("Fetch refresh token for registry '{}'".format(login_server)) print_pass("Fetch access token for registry '{}'".format(login_server)) -def _check_registry_health(cmd, registry_name, ignore_errors): +def _check_registry_health(cmd, + registry_name, + registry, + login_server, + ignore_errors): from azure.cli.core.profiles import ResourceType - if registry_name is None: - logger.warning("Registry name must be provided to check connectivity.") - return - - registry = None - # Connectivity - try: - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) - login_server = registry.login_server.rstrip('/') - except CLIError: - from ._docker_utils import get_login_server_suffix - suffix = get_login_server_suffix(cmd.cli_ctx) - - if not suffix: - from ._errors import LOGIN_SERVER_ERROR - _handle_error(LOGIN_SERVER_ERROR.format_error_message(registry_name), ignore_errors) - return - - login_server = registry_name + suffix - status_validated = _get_registry_status(login_server, registry_name, ignore_errors) if status_validated: _get_endpoint_and_token_status(cmd, login_server, ignore_errors) @@ -341,18 +372,16 @@ def _check_registry_health(cmd, registry_name, ignore_errors): _handle_error(CMK_MANAGED_IDENTITY_ERROR.format_error_message(registry_name), ignore_errors) -def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # pylint: disable=too-many-locals, too-many-statements +def _check_private_endpoint(cmd, + registry_name, + registry, + vnet_of_private_endpoint): # pylint: disable=too-many-locals, too-many-statements import socket from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id if registry_name is None: raise CLIError("Registry name must be provided to verify DNS routings of its private endpoints") - registry = None - - # retrieve registry - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name) - if not registry.private_endpoint_connections: raise CLIError('Registry "{}" doesn\'t have private endpoints to verify DNS routings.'.format(registry_name)) @@ -418,9 +447,13 @@ def _check_private_endpoint(cmd, registry_name, vnet_of_private_endpoint): # py raise CLIError('DNS routing verification failed') # Validate --image input -def validate_image(cmd, registry_name, repository_name, image): - from difflib import get_close_matches - from ._utils import get_resource_group_name_by_registry_name +def validate_image(cmd, + registry_name, + repository_name, + login_server, + username, + password, + image): from .manifest import _get_v2_manifest_path from ._docker_utils import ( @@ -429,27 +462,6 @@ def validate_image(cmd, registry_name, repository_name, image): RegistryException ) - from .repository import ( - get_access_credentials, - acr_repository_show_tags, - _get_manifest_path, - _obtain_data_from_registry - ) - - rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, None) - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) - login_server = registry.login_server.rstrip('/') - - # Get the access credentials for the registry - login_server, username, password = get_access_credentials( - cmd, - registry_name=registry_name, - tenant_suffix=None, - username=None, - password=None, - repository=repository_name, - permission='pull') - try: request_data_from_registry( http_method='get', @@ -464,65 +476,24 @@ def validate_image(cmd, registry_name, repository_name, image): except RegistryException as e: if e.status_code == 404: - # If tag is used, get all tags - # TO DO: Make this into its own function and then call it - if 'sha256' not in image: - tags = acr_repository_show_tags( - cmd, - registry_name=registry_name, - repository=repository_name, - orderby=None, - username=username, - password=password) - # Get a list of tags that have at least 80% similarity with the inputted image name - matches = get_close_matches(image, tags, n=1, cutoff=0.8) - if matches: - raise CLIError("Tag not found: {}. Did you mean to input '{}'?".format(image, matches[0])) - raise CLIError("Invalid tag: {}".format(str(e))) - - # If digest is used, get all digests - image_digest_list = _obtain_data_from_registry( - login_server=login_server, - path=_get_manifest_path(repository_name), - username=username, - password=password, - result_index='manifests', - orderby=None) - - # Get a list of digests that have at least 20% similarity with the inputted image name - digests = [item['digest'] for item in image_digest_list] - matches = get_close_matches(image, digests, n=1, cutoff=0.2) - #TO DO: Need to change this to 80% match not 20% - # if there is a match, give a suggestion on the intended image name - if matches: - raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) - raise CLIError("Invalid image: {}".format(str(e))) - # if the error is not 404, raise the appropriate error from backend - raise - -# Validate if specific blob can be pulled -def _check_blob(cmd, - registry_name, - repository_name, + _check_image_match(cmd, + registry_name, + repository_name, + login_server, + username, + password, + image) + raise CLIError("{} Please check if image/tag was inputted correctly.".format(str(e))) + +# Validate if blob layer can be pulled +def _check_blob(repository_name, + login_server, + username, + password, image): import requests - from .repository import get_access_credentials - from ._utils import get_resource_group_name_by_registry_name - - rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, None) - registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) - login_server = registry.login_server.rstrip('/') - - # Get the access credentials for the registry - registry_name, username, password = get_access_credentials( - cmd, - registry_name=registry_name, - tenant_suffix=None, - username=None, - password=None, - repository=repository_name, - permission='pull') + from ._docker_utils import get_manifest_authorization_header, parse_error_message # Get manifest # GET {url}/v2/{name}/manifests/{reference} @@ -530,13 +501,7 @@ def _check_blob(cmd, manifest_response = requests.get( manifest_url, - headers={'Accept': 'application/vnd.oci.artifact.manifest.v1+json' - ', application/vnd.cncf.oras.artifact.manifest.v1+json' - ', application/vnd.oci.image.manifest.v1+json' - ', application/vnd.oci.image.index.v1+json' - ', application/vnd.docker.distribution.manifest.v2+json' - ', application/vnd.docker.distribution.manifest.list.v2+json'}, - auth=(username, password)) + headers=get_manifest_authorization_header(username, password)) manifest = manifest_response.json() @@ -545,18 +510,19 @@ def _check_blob(cmd, digest = smallest_blob['digest'] # Get blob - # request_url = 'https://' + login_server + '/v2/' + repository_name + '/blobs/' + digest request_url = _get_blob(login_server, repository_name, digest) - logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) res = requests.get(request_url, auth=(username, password)) + + # Return server error message; if server error not available, will return error message below + if res.status_code >= 400: + raise CLIError(parse_error_message('Could not get the requested data.', res), res.status_code) + # Check if image or tag was inputted and return appropriate message if res.status_code < 400 and 'sha256' not in image: - print_pass("Blobs within the tag '{}' can be pulled from registry '{}'".format(image, login_server)) - elif res.status_code < 400: - print_pass("Blobs in image '{}' can be pulled from registry '{}'".format(image, login_server)) + print_pass("Blobs referenced by tag '{}' can be pulled from registry '{}'".format(image, login_server)) else: - raise CLIError("'Blobs in image '{}' cannot be pulled from registry '{}'".format(image, login_server)) + print_pass("Blobs in image '{}' can be pulled from registry '{}'".format(image, login_server)) # General command def acr_check_health(cmd, # pylint: disable useless-return @@ -565,8 +531,38 @@ def acr_check_health(cmd, # pylint: disable useless-return yes=False, registry_name=None, repository_name=None, - image=None): + image=None, + resource_group_name=None): from azure.cli.core.util import in_cloud_console + from .repository import get_access_credentials + from ._utils import get_resource_group_name_by_registry_name + + rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, resource_group_name) + + registry = None + + # Connectivity + try: + registry, _ = get_registry_by_name(cmd.cli_ctx, registry_name, rg) + login_server = registry.login_server.rstrip('/') + except CLIError: + from ._docker_utils import get_login_server_suffix + suffix = get_login_server_suffix(cmd.cli_ctx) + + if not suffix: + from ._errors import LOGIN_SERVER_ERROR + _handle_error(LOGIN_SERVER_ERROR.format_error_message(registry_name), ignore_errors) + return + + # Get the access credentials for the registry + login_server, username, password = get_access_credentials( + cmd, + registry_name=registry_name, + tenant_suffix=None, + username=None, + password=None, + repository=repository_name, + permission='pull') in_cloud_console = in_cloud_console() if in_cloud_console: @@ -575,12 +571,27 @@ def acr_check_health(cmd, # pylint: disable useless-return _get_docker_status_and_version(ignore_errors, yes) _get_cli_version() - _check_registry_health(cmd, registry_name, ignore_errors) + _check_registry_health(cmd, + registry_name, + registry, + login_server, + ignore_errors) # If repository and image are provided, validate image input + # Then check if blob layer can be pulled if (image and repository_name): - validate_image(cmd, registry_name, repository_name, image) - _check_blob(cmd, registry_name, repository_name, image) + validate_image(cmd, + registry_name, + repository_name, + login_server, + username, + password, + image) + _check_blob(repository_name, + login_server, + username, + password, + image) if vnet: _check_private_endpoint(cmd, registry_name, vnet) diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py new file mode 100644 index 00000000000..a74e90d1470 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py @@ -0,0 +1,35 @@ +# -------------------------------------------------------------------------------------------- +# 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.testsdk import ScenarioTest, ResourceGroupPreparer + +class AcrCheckHealthCommandsTests(ScenarioTest): + + @ResourceGroupPreparer() + def test_acr_check_health(self, repository_name, image): + registry_name = self.create_random_name('clireg', 20) + image = 'latest' + self.kwargs.update({ + 'registry': registry_name, + 'ignore_errors': False, + 'yes': False, + 'vnet': None, + 'repository': repository_name, + 'image': image, + 'reason': 'OK' + }) + + # Test the check_health command with the --ignore-errors flag + self.cmd('acr check-health --name {registry_name} --ignore-errors ', + checks=[self.check('name', '{registry_name}'), + self.check('ignoreErrors', False), + self.check('vnet', None)]) + + # Test the check_health command to check if blobs can be pulled from the registry + self.cmd('acr check-health --name {registry_name} --repository {repository_name} --image {image}', + checks=[self.check('name', '{registry_name}'), + self.check('repository', '{repository_name}'), + self.check('image', '{image}'), + self.check('reason', 'OK')]) \ No newline at end of file From 2fdc6cd6dc6104086a21d678cbb831167943b4eb Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Tue, 28 Nov 2023 14:30:31 -0800 Subject: [PATCH 6/8] add check blob function in check-health and test --- .../recordings/test_acr_check_health.yaml | 1833 +++++++++++++++++ .../latest/test_acr_check_health_commands.py | 44 +- 2 files changed, 1858 insertions(+), 19 deletions(-) create mode 100644 src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_check_health.yaml diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_check_health.yaml b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_check_health.yaml new file mode 100644 index 00000000000..e3027ada2cc --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_check_health.yaml @@ -0,0 +1,1833 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + ParameterSetName: + - --name --sku --resource-group + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-resource/23.1.0b2 Python/3.11.5 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2022-09-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001","name":"clitest.rg000001","type":"Microsoft.Resources/resourceGroups","location":"westus","tags":{"product":"azurecli","cause":"automation","test":"test_acr_check_health","date":"2023-11-28T21:39:50Z","module":"acr"},"properties":{"provisioningState":"Succeeded"}}' + headers: + cache-control: + - no-cache + content-length: + - '356' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:39:54 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 5C15CE22AB5B448FB95CB607CAC24291 Ref B: CO6AA3150219025 Ref C: 2023-11-28T21:39:55Z' + status: + code: 200 + message: OK +- request: + body: '{"location": "westus", "sku": {"name": "Premium"}, "properties": {"adminUserEnabled": + false, "anonymousPullEnabled": false}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + Content-Length: + - '124' + Content-Type: + - application/json + ParameterSetName: + - --name --sku --resource-group + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Creating","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-a9be9dc0-8e36-11ee-bfe4-546cebebf32e?api-version=2022-02-01-preview&t=638368044023679882&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=C6kjuBLoowCpOiRbPkzL-Zucc3LcElHa8vuvIyfH01nG7A4hyKUwnV_Juq_A8RqGPyWslO79M46RKOJw0f3RqojPjJX7mIhreO8IhPnTG9sYdwffkkqS29DH6yMHFXB8M14VJx0Y7FfO6mCpwNuYnbwEgo1OJ88yzCqU3RX7jN9Fkwq4YFtJRD6mX11AVcqW9zoUmJwJOwR30Q8ju7SXV79UqTulP27WuOAk71zOHcO3t5EG2T0bfIJsdJu4jPq5LZt20ZBY7shJ6I88PyUkyUAasuMWJzx9aWuAPh356xmctxZECyk7dDjgxSkX6jihnSoUSaasY6LUu552VUGcwg&h=sR3MzUcNkKmUL53rVIOxIHLI2KnzgVaK-a3Sp-u508Q + cache-control: + - no-cache + content-length: + - '1421' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:01 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-writes: + - '1199' + x-msedge-ref: + - 'Ref A: F86B9B1890644705920524C6409A94BE Ref B: CO6AA3150218029 Ref C: 2023-11-28T21:39:55Z' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + ParameterSetName: + - --name --sku --resource-group + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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-a9be9dc0-8e36-11ee-bfe4-546cebebf32e?api-version=2022-02-01-preview&t=638368044023679882&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=C6kjuBLoowCpOiRbPkzL-Zucc3LcElHa8vuvIyfH01nG7A4hyKUwnV_Juq_A8RqGPyWslO79M46RKOJw0f3RqojPjJX7mIhreO8IhPnTG9sYdwffkkqS29DH6yMHFXB8M14VJx0Y7FfO6mCpwNuYnbwEgo1OJ88yzCqU3RX7jN9Fkwq4YFtJRD6mX11AVcqW9zoUmJwJOwR30Q8ju7SXV79UqTulP27WuOAk71zOHcO3t5EG2T0bfIJsdJu4jPq5LZt20ZBY7shJ6I88PyUkyUAasuMWJzx9aWuAPh356xmctxZECyk7dDjgxSkX6jihnSoUSaasY6LUu552VUGcwg&h=sR3MzUcNkKmUL53rVIOxIHLI2KnzgVaK-a3Sp-u508Q + response: + body: + string: '{"status":"Succeeded"}' + headers: + api-supported-versions: + - 2022-02-01-preview + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/operationStatuses/registries-a9be9dc0-8e36-11ee-bfe4-546cebebf32e?api-version=2022-02-01-preview&t=638368044026096861&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=cyQSVj5nWEoethV4OW4Tqwvv_3ipDFvhuap-kcSbLQB3yzpZKl_xQH9ExhDWRfWJ1ytMb8gv2H6-2bCxeKOOnT-or83Fby_r_0WDOvzWV3fsK8ddwSyQ0zft-G6yfeSzEq9OSpFJmBhvAXHiekNbMhdAcLgw8ULhGKTvbsJOlRgJvW4S9ao6Kd4UFoTRim3xnMZeprAFe_kxG3GG9HlRYN2eiY68k_G7X0cZKfcafpebC0REsn1Uvq-IAAGj3jWSL6YJMht8-UPj9MHpRJrcefLma5AWxKcZSWJ4gbLxiFQzuexYQdYKZcxGChPuA6u3rb_piqqIWXW_kvm1GbPwaQ&h=nIcVB2h9dZybv_ZkZJIONSQuSVA-B1wSrNZlXGXTlLA + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 31F7CD6FDF4F4155A8846ADF1BA4DE6C Ref B: CO6AA3150218029 Ref C: 2023-11-28T21:40:02Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + ParameterSetName: + - --name --sku --resource-group + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 7AB83114F81E434AA92C32529CC11329 Ref B: CO6AA3150218029 Ref C: 2023-11-28T21:40:02Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr import + Connection: + - keep-alive + ParameterSetName: + - -n -r --source + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-resource/23.1.0b2 Python/3.11.5 (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/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakRegistry","name":"sakopakRegistry","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus","tags":{"testTag":"123"},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-18T19:59:31.8324214Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-10-13T18:44:59.5274264Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakregisty","name":"sakopakregisty","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-19T21:04:00.2056918Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-09-19T21:04:00.2056918Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvq6m4yu27skf56tn3qn5zqsmknyedmk2dqmmyukvzidq2mtk6wbyfsjhoqhjct7gf/providers/Microsoft.ContainerRegistry/registries/cliregbgxyyjuhgaez5z","name":"cliregbgxyyjuhgaez5z","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:03:27.5829894Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:03:27.5829894Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvdksdzc5mkzjp6bxbwvo5elyo2cctwcxuvruvg7g7shrsiamk3zwqr4eignkbbk24/providers/Microsoft.ContainerRegistry/registries/testregl3k76cgqtfdedhjzki","name":"testregl3k76cgqtfdedhjzki","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:04:04.8052779Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:04:04.8052779Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg6a2vsibk7qf6eusmrwhwb5ywyrz6yx3zavvqkrgtfktrviaiflxqqbnowr6hdabob/providers/Microsoft.ContainerRegistry/registries/cliregmmimc4khy4a7m7","name":"cliregmmimc4khy4a7m7","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:38:39.1064323Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:38:39.1064323Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '3449' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 3008077F79A949BFAAEC5AB71729B66A Ref B: CO6AA3150219025 Ref C: 2023-11-28T21:40:03Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr import + Connection: + - keep-alive + ParameterSetName: + - -n -r --source + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:03 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 4A26535BE5CD4BF3B73343AFFA45F479 Ref B: CO6AA3150220027 Ref C: 2023-11-28T21:40:03Z' + status: + code: 200 + message: OK +- request: + body: '{"source": {"resourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/resourcegroupdiffsub/providers/Microsoft.ContainerRegistry/registries/sourceregistrydiffsub", + "sourceImage": "microsoft:azure-cli"}, "targetTags": ["microsoft:azure-cli"], + "mode": "NoForce"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr import + Connection: + - keep-alive + Content-Length: + - '284' + Content-Type: + - application/json + ParameterSetName: + - -n -r --source + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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/importImage?api-version=2022-02-01-preview + response: + body: + string: '' + headers: + api-supported-versions: + - 2017-10-01, 2019-05-01, 2019-12-01-preview, 2020-11-01-preview, 2021-06-01-preview, + 2021-08-01-preview, 2021-09-01, 2021-12-01-preview, 2022-02-01-preview, 2022-12-01, + 2023-01-01-preview, 2023-06-01-preview, 2023-07-01, 2023-08-01-preview, 2023-11-01-preview, + 2024-11-01-preview + cache-control: + - no-cache + content-length: + - '0' + date: + - Tue, 28 Nov 2023 21:40:03 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/WESTUS/operationResults/registries-aea50403-8e36-11ee-bcd8-546cebebf32e?api-version=2022-02-01-preview&t=638368044044330148&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=JxGGQC4BpVSHhnUz-Qg4dteMYALOwHywm_5d-Uz0f38fF12p8GSR6C9jNg2MySg0Llaq0fptLAlkq6RrPIjvzjHI9bm-P4LE98s9XkGRJudwSNN8nZTv2R4wOKX3Xm7lmEEAM0wlGSLlSIzwpzXVDFFyf6mOjz_fOa9J9H0chnZ49vM8iMoAe454KAOdj3IQnVl-c6m22VWw_VtUD7oSavSftf-Z7zfF63Z9qVLm-46NRodtW5PjXLGfAAHxk4dX9VccX8JJAKDZNUXE8nxFrv6foWYIWgL62GbGWYRDNNM9lglu9ov5Xn5BVolDOTe7UM6h241zRGLQ-dNdQ4VenA&h=Xh3Wpl4fqsG7epm9JIgK5g_7HY06bdA3DP9XUzSnCFg + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-writes: + - '1199' + x-msedge-ref: + - 'Ref A: 88482B5A472949919C21047D8B25EEBD Ref B: CO6AA3150217047 Ref C: 2023-11-28T21:40:04Z' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr import + Connection: + - keep-alive + ParameterSetName: + - -n -r --source + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/WESTUS/operationResults/registries-aea50403-8e36-11ee-bcd8-546cebebf32e?api-version=2022-02-01-preview&t=638368044044330148&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=JxGGQC4BpVSHhnUz-Qg4dteMYALOwHywm_5d-Uz0f38fF12p8GSR6C9jNg2MySg0Llaq0fptLAlkq6RrPIjvzjHI9bm-P4LE98s9XkGRJudwSNN8nZTv2R4wOKX3Xm7lmEEAM0wlGSLlSIzwpzXVDFFyf6mOjz_fOa9J9H0chnZ49vM8iMoAe454KAOdj3IQnVl-c6m22VWw_VtUD7oSavSftf-Z7zfF63Z9qVLm-46NRodtW5PjXLGfAAHxk4dX9VccX8JJAKDZNUXE8nxFrv6foWYIWgL62GbGWYRDNNM9lglu9ov5Xn5BVolDOTe7UM6h241zRGLQ-dNdQ4VenA&h=Xh3Wpl4fqsG7epm9JIgK5g_7HY06bdA3DP9XUzSnCFg + response: + body: + string: '{"status":"Accepted"}' + headers: + cache-control: + - no-cache + content-length: + - '21' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:03 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/WESTUS/operationResults/registries-aea50403-8e36-11ee-bcd8-546cebebf32e?api-version=2022-02-01-preview&t=638368044045413487&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=b4Qf5epSJxiFSxpqzzrWUlcfYS9oNxL3nucEwi21jr8pFDDZooefyphLo_YJaOWI0-w1qnzVykJoROLfcru3kDmlohQaOwwAzxTjksD_G8IKmFn9nmx9wdJdml3ZVxtf04ixnS0zzvgotkhID5Rp5GwUHhGrScdMX7xxTong7NBRSyZI6lyjDQYGXdTYR4xNWTYMtpG2fBdlmG5vT8tzO1AC3dEXgi7Q8xVwFr9abQTeGjjrxVxzFzd9kRG8cDd04EYDSxKJT1eSIqEfVIYtvQCkkYrfjArbVjwvE2gE1k5q4YjefxRDEU5xHFMKZ70VBpCXN6bdUT30aRaRBDz8LA&h=WDvVowHm7XhGd8A7NG7xWRl0LEDZAaYDwsblj8hkF8o + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 95DAAEFEBF584027AF86241830E872F4 Ref B: CO6AA3150217047 Ref C: 2023-11-28T21:40:04Z' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr import + Connection: + - keep-alive + ParameterSetName: + - -n -r --source + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/WESTUS/operationResults/registries-aea50403-8e36-11ee-bcd8-546cebebf32e?api-version=2022-02-01-preview&t=638368044045413487&c=MIIHHjCCBgagAwIBAgITfwI8ooo2761TEgO3SgAEAjyiijANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDIwHhcNMjMxMTAxMTc1NTI2WhcNMjQxMDI2MTc1NTI2WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0WQLjgbZj70uXwL_AnKvEas1GVvOB7Og4giEY7H0L78RFiY2-CzzgMKyZV8H3ACZxqQoBMWsq9XAf4iUNAer7s23VPyWkoVdr2uTc8SCvur4qja77OTMKiRVU277ViRu_Mb-fJvQKeRO3Q8A4Sg1A63a2VQ_WlyOCHPBj-gUF0zU4SYnlqSYGcNmuhCjtHpVvF_N3CGz0JlGTo3ia0wmks2y95IHeD0lcr0AgP73_eafbKafZn4Z56GdC3lngKdhyEiQi_kPyxaydv1PfV2xX9OLKvB19e9jLB43QA9r5k5DsAhqtv6eqwHBdW07S9MCMu8kwoYUpX1TTGapizc6ECAwEAAaOCBAswggQHMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHaBggrBgEFBQcBAQSCAcwwggHIMGYGCCsGAQUFBzAChlpodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MFYGCCsGAQUFBzAChkpodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAxLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDAyKDQpLmNydDBWBggrBgEFBQcwAoZKaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMS5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwMig0KS5jcnQwVgYIKwYBBQUHMAKGSmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDEuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3J0MB0GA1UdDgQWBBTwk8yVBP3k-Qa8LdSw6mv--mLIvDAOBgNVHQ8BAf8EBAMCBaAwggE1BgNVHR8EggEsMIIBKDCCASSgggEgoIIBHIZCaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JshjRodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDIoNCkuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBSuecJrXSWIEwb2BwnDl3x7l48dVTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAKR8h2puMUi3SGdIfblcEylOBfcaCRtDDIvC64QKLae7vOAe1f8SpXEFfYeIl5xydb8lEUYApxL701SQSy-NPuBuuQ0CIMKjZ-xCj9VbjQIykosQBVJvxp5I0TplyumFiehQP3zZuc1PZ2hg05aq3CKSbJGKFlow_8P9RN66yeKWGE7SWV9NZThEL8VfEXjl_ITgWb-L1SmnFKTdOVNVDQoRjjX-JqVobqh0O4K0dsPapDoAdqjIECodvocGyWtCEwIk-j8yyBxqX_JzzumMzxUMrxCjaosaJVOvoJB7vh6WuiYfHondyzaGqjm9Bjpqj46bQXojx6xALlzNX5x_j_g&s=b4Qf5epSJxiFSxpqzzrWUlcfYS9oNxL3nucEwi21jr8pFDDZooefyphLo_YJaOWI0-w1qnzVykJoROLfcru3kDmlohQaOwwAzxTjksD_G8IKmFn9nmx9wdJdml3ZVxtf04ixnS0zzvgotkhID5Rp5GwUHhGrScdMX7xxTong7NBRSyZI6lyjDQYGXdTYR4xNWTYMtpG2fBdlmG5vT8tzO1AC3dEXgi7Q8xVwFr9abQTeGjjrxVxzFzd9kRG8cDd04EYDSxKJT1eSIqEfVIYtvQCkkYrfjArbVjwvE2gE1k5q4YjefxRDEU5xHFMKZ70VBpCXN6bdUT30aRaRBDz8LA&h=WDvVowHm7XhGd8A7NG7xWRl0LEDZAaYDwsblj8hkF8o + response: + body: + string: '{"status":"Succeeded"}' + headers: + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:14 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 393A4C41AE254DA7B9081EC2AB832162 Ref B: CO6AA3150217047 Ref C: 2023-11-28T21:40:14Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-resource/23.1.0b2 Python/3.11.5 (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/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakRegistry","name":"sakopakRegistry","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus","tags":{"testTag":"123"},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-18T19:59:31.8324214Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-10-13T18:44:59.5274264Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakregisty","name":"sakopakregisty","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-19T21:04:00.2056918Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-09-19T21:04:00.2056918Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvq6m4yu27skf56tn3qn5zqsmknyedmk2dqmmyukvzidq2mtk6wbyfsjhoqhjct7gf/providers/Microsoft.ContainerRegistry/registries/cliregbgxyyjuhgaez5z","name":"cliregbgxyyjuhgaez5z","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:03:27.5829894Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:03:27.5829894Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvdksdzc5mkzjp6bxbwvo5elyo2cctwcxuvruvg7g7shrsiamk3zwqr4eignkbbk24/providers/Microsoft.ContainerRegistry/registries/testregl3k76cgqtfdedhjzki","name":"testregl3k76cgqtfdedhjzki","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:04:04.8052779Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:04:04.8052779Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg6a2vsibk7qf6eusmrwhwb5ywyrz6yx3zavvqkrgtfktrviaiflxqqbnowr6hdabob/providers/Microsoft.ContainerRegistry/registries/cliregmmimc4khy4a7m7","name":"cliregmmimc4khy4a7m7","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:38:39.1064323Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:38:39.1064323Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '3449' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:14 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 892A20A0A736459B8D4E1BEEA548B489 Ref B: CO6AA3150219019 Ref C: 2023-11-28T21:40:15Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:15 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: A98E33AD40914C7B90D0DBAE5DD05931 Ref B: CO6AA3150217021 Ref C: 2023-11-28T21:40:15Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-resource/23.1.0b2 Python/3.11.5 (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/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakRegistry","name":"sakopakRegistry","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus","tags":{"testTag":"123"},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-18T19:59:31.8324214Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-10-13T18:44:59.5274264Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakregisty","name":"sakopakregisty","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-19T21:04:00.2056918Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-09-19T21:04:00.2056918Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvq6m4yu27skf56tn3qn5zqsmknyedmk2dqmmyukvzidq2mtk6wbyfsjhoqhjct7gf/providers/Microsoft.ContainerRegistry/registries/cliregbgxyyjuhgaez5z","name":"cliregbgxyyjuhgaez5z","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:03:27.5829894Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:03:27.5829894Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvdksdzc5mkzjp6bxbwvo5elyo2cctwcxuvruvg7g7shrsiamk3zwqr4eignkbbk24/providers/Microsoft.ContainerRegistry/registries/testregl3k76cgqtfdedhjzki","name":"testregl3k76cgqtfdedhjzki","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:04:04.8052779Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:04:04.8052779Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg6a2vsibk7qf6eusmrwhwb5ywyrz6yx3zavvqkrgtfktrviaiflxqqbnowr6hdabob/providers/Microsoft.ContainerRegistry/registries/cliregmmimc4khy4a7m7","name":"cliregmmimc4khy4a7m7","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:38:39.1064323Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:38:39.1064323Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '3449' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:15 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: FD9F3E6EBF8740898B19DE1A3F0E3859 Ref B: CO6AA3150219027 Ref C: 2023-11-28T21:40:16Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:16 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: F8F4B17DFD804F2EA1D084A213A1CBA3 Ref B: CO6AA3150220025 Ref C: 2023-11-28T21:40:16Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + 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, 28 Nov 2023 21:40:17 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:18 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 84E1A0C0BC0746A389B1BFA456E90A4B Ref B: CO6AA3150218023 Ref C: 2023-11-28T21:40:17Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + 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, 28 Nov 2023 21:40:18 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: grant_type=access_token&service=clireg3tal56fhkul3xo.azurecr.io&tenant=72f988bf-86f1-41af-91ab-2d7cd011db47&access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSIsImtpZCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNzAxMjA2NzE5LCJuYmYiOjE3MDEyMDY3MTksImV4cCI6MTcwMTIxMTQ1NywiX2NsYWltX25hbWVzIjp7Imdyb3VwcyI6InNyYzEifSwiX2NsYWltX3NvdXJjZXMiOnsic3JjMSI6eyJlbmRwb2ludCI6Imh0dHBzOi8vZ3JhcGgud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3VzZXJzL2E4ZGZkZTlmLWIxYmQtNDBhNS1hOWU2LTA3NTViZDkwNWQxNy9nZXRNZW1iZXJPYmplY3RzIn19LCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFZBQUFBM2c1VWY3Qk9UeEFtMlk0RHNITTI0MkNlRXA2VGNOT1RuQVhmeUJTN0V3WEV0blhObkpXbUdvNTl0bW51b0VNb1llemRSMkEvc2l6THRuV0ZudGMrVGFSdlowd0VhL1JxdXdyRTIvOHdxV1E9IiwiYW1yIjpbInJzYSIsIm1mYSJdLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsImFwcGlkYWNyIjoiMCIsImNhcG9saWRzX2xhdGViaW5kIjpbIjI5Mzk5Y2Y5LTliNmItNDIwNS1iNWIzLTEzYTEzNGU5YjIzMyJdLCJmYW1pbHlfbmFtZSI6IlBhayIsImdpdmVuX25hbWUiOiJTYWtvIiwiaWR0eXAiOiJ1c2VyIiwiaXBhZGRyIjoiMjAwMTo0ODk4OjgwZTg6OToxN2U6OTBiYToyN2UxOmQ4MTIiLCJuYW1lIjoiU2FrbyBQYWsiLCJvaWQiOiJhOGRmZGU5Zi1iMWJkLTQwYTUtYTllNi0wNzU1YmQ5MDVkMTciLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtMjEyNzUyMTE4NC0xNjA0MDEyOTIwLTE4ODc5Mjc1MjctNjg4OTc0NDEiLCJwdWlkIjoiMTAwMzIwMDJCNkVFRTg0NCIsInJoIjoiMC5BUUVBdjRqNWN2R0dyMEdScXkxODBCSGJSMFpJZjNrQXV0ZFB1a1Bhd2ZqMk1CTWFBRU0uIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwic3ViIjoiUGoxc0hOY0NZbEZ4RXdMNUpvZ3Z0NTRleXQyeklIN2hrZG1BbEUwaWp5VSIsInRpZCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInVuaXF1ZV9uYW1lIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXBuIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXRpIjoiNXpwYVl6emhrVS1lYVpMTnhRZlpBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il0sInhtc19jYWUiOiIxIiwieG1zX2NjIjpbIkNQMSJdLCJ4bXNfZmlsdGVyX2luZGV4IjpbIjI2Il0sInhtc19yZCI6IjAuNDJMbFlCUmlsQUlBIiwieG1zX3NzbSI6IjEiLCJ4bXNfdGNkdCI6MTI4OTI0MTU0N30.P3wdkDnaw8Ij7Z4kIDax43aQywhHoCUJ-kiJ5CXb3olm8_lCGK5GRMXfAutOiGxLge9hE1wheAF9h432C0QawOxoD4-cY4U6B8XQ7gDahdeKQ-UsJkT7NQF9c6zs5b0B86ecX22oL6jQtPGUlhYR3GJ1gMzSE-QLj681KmzmSmnRBL8YcNpj_D5N263hf0Elt_ERXH-7TUDZwBRw-W1POEuB1KODhGsJWtAdhAKfsvk55EFVNyHUm6VwqJQ0F4rw3DgXrKCIh8KqijSw1YPLXFSOtVl34lQaxFUepL9zp0tIjFtI07orMVPGf5pRcL3DyGPd4oJPSWi3i9kRFb4g8A + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2420' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/exchange + response: + body: + string: '{"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI2YTE2MDA0Mi1hYzVkLTQxY2UtODI0NS1kMzgyMDBkMzgyMTMiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MTgsImV4cCI6MTcwMTIxODQxOCwiaWF0IjoxNzAxMjA2NzE4LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.it-L3M1AW3aei3qIT-983D-RZT5ezAL9PUrGhconk-QxAgGXbn7CwEktpFvShcC6Ph2xvKMjWx0ZCW_0Mkmu-i4TMXsVEBU7Us6s_pqZQuv5WcBKNfhWBT2P-4nIkIs16NnooiGk3w_yGV1lcsZ6SizlqgISHFYGRZ0PLUoYB8oiRAUuamopKZCEOvlS8k2cbvt1tURo1pIzslRFVb_u5P2CxZ2LoyG-ez0xNvMT2l1QiVKd-9UW0TLYXe5J0VWZgvyc-Gtn56wtHRtwKd_RxrjtMDIQ3XiDM6gJAGNZRHFg_hmSsL33goLzNg_J8Vr03j6mXs1L0HdpG5mSgP1ysw"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:18 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.316667' + status: + code: 200 + message: OK +- request: + body: grant_type=refresh_token&service=clireg3tal56fhkul3xo.azurecr.io&scope=registry%3Apull%3A%2A&refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI2YTE2MDA0Mi1hYzVkLTQxY2UtODI0NS1kMzgyMDBkMzgyMTMiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MTgsImV4cCI6MTcwMTIxODQxOCwiaWF0IjoxNzAxMjA2NzE4LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.it-L3M1AW3aei3qIT-983D-RZT5ezAL9PUrGhconk-QxAgGXbn7CwEktpFvShcC6Ph2xvKMjWx0ZCW_0Mkmu-i4TMXsVEBU7Us6s_pqZQuv5WcBKNfhWBT2P-4nIkIs16NnooiGk3w_yGV1lcsZ6SizlqgISHFYGRZ0PLUoYB8oiRAUuamopKZCEOvlS8k2cbvt1tURo1pIzslRFVb_u5P2CxZ2LoyG-ez0xNvMT2l1QiVKd-9UW0TLYXe5J0VWZgvyc-Gtn56wtHRtwKd_RxrjtMDIQ3XiDM6gJAGNZRHFg_hmSsL33goLzNg_J8Vr03j6mXs1L0HdpG5mSgP1ysw + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '1292' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI0NWRlZmY5NC1mN2QxLTRlNzUtOWE2Yy1lN2FkN2JlYjEwYjYiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MTksImV4cCI6MTcwMTIxMTIxOSwiaWF0IjoxNzAxMjA2NzE5LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiYWNjZXNzIjpbXSwicm9sZXMiOltdLCJncmFudF90eXBlIjoiYWNjZXNzX3Rva2VuIiwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYifQ.BGrCJ-IYm4CMXROsdS072AK2T3Jb99wmm4dXQQ60UEjnXdG1f-uXZIUp7uVk4TSxEXil2OzOUgFnLkmEarDAhSmj53mvPjyS1X0P8S-nlTaDOHVKHjGRcEs56K5ttVv1r4AlJ9cU-AwO4jWB3oBGEROXLOU4e4Mw5Q24k7fo15goI2CNjTcj6cxCfQ0R0dDCxLky4F8wqHtB9LUxT1p3m7B1EettwSzc98Oh3q4n4q6Tt4rH7meROkmrmS6IZfuk9AYIda193gi8LBZTdazci2DKB_Z_0BA7Hf2ySdSMsuUWPKIDCnch5gBUN0CTLzO9pDZXv1BNqGQfaJ23D2Z1TQ"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:19 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.316667' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + 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, 28 Nov 2023 21:40:20 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.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.31.0 + 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, 28 Nov 2023 21:40:21 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: grant_type=access_token&service=clireg3tal56fhkul3xo.azurecr.io&tenant=72f988bf-86f1-41af-91ab-2d7cd011db47&access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSIsImtpZCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNzAxMjA2NzE5LCJuYmYiOjE3MDEyMDY3MTksImV4cCI6MTcwMTIxMTQ1NywiX2NsYWltX25hbWVzIjp7Imdyb3VwcyI6InNyYzEifSwiX2NsYWltX3NvdXJjZXMiOnsic3JjMSI6eyJlbmRwb2ludCI6Imh0dHBzOi8vZ3JhcGgud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3VzZXJzL2E4ZGZkZTlmLWIxYmQtNDBhNS1hOWU2LTA3NTViZDkwNWQxNy9nZXRNZW1iZXJPYmplY3RzIn19LCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFZBQUFBM2c1VWY3Qk9UeEFtMlk0RHNITTI0MkNlRXA2VGNOT1RuQVhmeUJTN0V3WEV0blhObkpXbUdvNTl0bW51b0VNb1llemRSMkEvc2l6THRuV0ZudGMrVGFSdlowd0VhL1JxdXdyRTIvOHdxV1E9IiwiYW1yIjpbInJzYSIsIm1mYSJdLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsImFwcGlkYWNyIjoiMCIsImNhcG9saWRzX2xhdGViaW5kIjpbIjI5Mzk5Y2Y5LTliNmItNDIwNS1iNWIzLTEzYTEzNGU5YjIzMyJdLCJmYW1pbHlfbmFtZSI6IlBhayIsImdpdmVuX25hbWUiOiJTYWtvIiwiaWR0eXAiOiJ1c2VyIiwiaXBhZGRyIjoiMjAwMTo0ODk4OjgwZTg6OToxN2U6OTBiYToyN2UxOmQ4MTIiLCJuYW1lIjoiU2FrbyBQYWsiLCJvaWQiOiJhOGRmZGU5Zi1iMWJkLTQwYTUtYTllNi0wNzU1YmQ5MDVkMTciLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtMjEyNzUyMTE4NC0xNjA0MDEyOTIwLTE4ODc5Mjc1MjctNjg4OTc0NDEiLCJwdWlkIjoiMTAwMzIwMDJCNkVFRTg0NCIsInJoIjoiMC5BUUVBdjRqNWN2R0dyMEdScXkxODBCSGJSMFpJZjNrQXV0ZFB1a1Bhd2ZqMk1CTWFBRU0uIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwic3ViIjoiUGoxc0hOY0NZbEZ4RXdMNUpvZ3Z0NTRleXQyeklIN2hrZG1BbEUwaWp5VSIsInRpZCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInVuaXF1ZV9uYW1lIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXBuIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXRpIjoiNXpwYVl6emhrVS1lYVpMTnhRZlpBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il0sInhtc19jYWUiOiIxIiwieG1zX2NjIjpbIkNQMSJdLCJ4bXNfZmlsdGVyX2luZGV4IjpbIjI2Il0sInhtc19yZCI6IjAuNDJMbFlCUmlsQUlBIiwieG1zX3NzbSI6IjEiLCJ4bXNfdGNkdCI6MTI4OTI0MTU0N30.P3wdkDnaw8Ij7Z4kIDax43aQywhHoCUJ-kiJ5CXb3olm8_lCGK5GRMXfAutOiGxLge9hE1wheAF9h432C0QawOxoD4-cY4U6B8XQ7gDahdeKQ-UsJkT7NQF9c6zs5b0B86ecX22oL6jQtPGUlhYR3GJ1gMzSE-QLj681KmzmSmnRBL8YcNpj_D5N263hf0Elt_ERXH-7TUDZwBRw-W1POEuB1KODhGsJWtAdhAKfsvk55EFVNyHUm6VwqJQ0F4rw3DgXrKCIh8KqijSw1YPLXFSOtVl34lQaxFUepL9zp0tIjFtI07orMVPGf5pRcL3DyGPd4oJPSWi3i9kRFb4g8A + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2420' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/exchange + response: + body: + string: '{"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI3ZTc3ZDg0YS00NmQyLTQ2NzItYjljZS03YTdlNjc0ZmZiNmUiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjEsImV4cCI6MTcwMTIxODQyMSwiaWF0IjoxNzAxMjA2NzIxLCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.jIp8cCB0dtbaAACw5o7nN3hHlK_nstkg2diuepWt6launn6SHxRS1TCd2uRszLm4ALnefHzqEJOyBO9shByPVxOvWVMkzo0Rt7JQNTDFZEMD5YcFvAMb-dxLXvbLJGvXEkbOxI9-fMRWzOvvEPAWoZKtMlX5uq94VwR9_KwP7w9563lDIFe-VX53fl0j3ys5R4UrGOQFIiHFuk6mrPZrPQNJYU-sm2BHIHgW5G8L0lyvC9jcolzrOLVoGJdc7sy9YtyvJWbcXxT66ikS_sPbEbczN495C2SM80385F_441cIOtDOhtXJaHnuFrQo9V2jyWD9Sf6q1Gg9SSayBC8lUg"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:21 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.316667' + status: + code: 200 + message: OK +- request: + body: grant_type=refresh_token&service=clireg3tal56fhkul3xo.azurecr.io&scope=registry%3ANone%3A%2A&refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI3ZTc3ZDg0YS00NmQyLTQ2NzItYjljZS03YTdlNjc0ZmZiNmUiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjEsImV4cCI6MTcwMTIxODQyMSwiaWF0IjoxNzAxMjA2NzIxLCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.jIp8cCB0dtbaAACw5o7nN3hHlK_nstkg2diuepWt6launn6SHxRS1TCd2uRszLm4ALnefHzqEJOyBO9shByPVxOvWVMkzo0Rt7JQNTDFZEMD5YcFvAMb-dxLXvbLJGvXEkbOxI9-fMRWzOvvEPAWoZKtMlX5uq94VwR9_KwP7w9563lDIFe-VX53fl0j3ys5R4UrGOQFIiHFuk6mrPZrPQNJYU-sm2BHIHgW5G8L0lyvC9jcolzrOLVoGJdc7sy9YtyvJWbcXxT66ikS_sPbEbczN495C2SM80385F_441cIOtDOhtXJaHnuFrQo9V2jyWD9Sf6q1Gg9SSayBC8lUg + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '1292' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI0NzJhOWE3Mi0yYjhkLTQ3YjEtYjAzMC1mZmNjNDE5YzJjMWYiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjIsImV4cCI6MTcwMTIxMTIyMiwiaWF0IjoxNzAxMjA2NzIyLCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiYWNjZXNzIjpbXSwicm9sZXMiOltdLCJncmFudF90eXBlIjoiYWNjZXNzX3Rva2VuIiwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYifQ.Lx-kyV66KYdbNqxJC5dFWoTsz5Yrm0poFnweVQL8Y_o_K_eDHuM7eOTBLdRboDPBgBJ1mWvyAzIi377IlSgbCIdvRyu1UT0H_Uadp4eMSUWbVcRhrpnB2EzOqSyqlM3g1WM0dWXU04aqjr6W0IE_j1I6x2IGjVLcXhmCNET0Pr3zFJzg4BLNdc53CDiUn_TyZoDGxw_H88dIkCFekCASkDt3uC8fv4SLJLZT74Gji3WBDDNvFXH9bpvTRXN8EQEVbzY9o2mv10kEMam7aWviLQ2Zv8hdnEXNVlWkR-B3hdk_AiGfxbQVo7PLoBYMio_zkHs2WafFTxwFtdhylj9DLw"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:22 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.3' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --repository --image --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-resource/23.1.0b2 Python/3.11.5 (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/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakRegistry","name":"sakopakRegistry","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus","tags":{"testTag":"123"},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-18T19:59:31.8324214Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-10-13T18:44:59.5274264Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakregisty","name":"sakopakregisty","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-19T21:04:00.2056918Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-09-19T21:04:00.2056918Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvq6m4yu27skf56tn3qn5zqsmknyedmk2dqmmyukvzidq2mtk6wbyfsjhoqhjct7gf/providers/Microsoft.ContainerRegistry/registries/cliregbgxyyjuhgaez5z","name":"cliregbgxyyjuhgaez5z","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:03:27.5829894Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:03:27.5829894Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvdksdzc5mkzjp6bxbwvo5elyo2cctwcxuvruvg7g7shrsiamk3zwqr4eignkbbk24/providers/Microsoft.ContainerRegistry/registries/testregl3k76cgqtfdedhjzki","name":"testregl3k76cgqtfdedhjzki","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:04:04.8052779Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:04:04.8052779Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '2843' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:22 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 3FDA48A00A594BDABA55887EF5D84BFC Ref B: CO6AA3150217025 Ref C: 2023-11-28T21:40:22Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --repository --image --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:21 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: D1F4506CBBB24688993475B2D8AD9E13 Ref B: CO6AA3150217033 Ref C: 2023-11-28T21:40:22Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --repository --image --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-resource/23.1.0b2 Python/3.11.5 (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/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakRegistry","name":"sakopakRegistry","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"eastus","tags":{"testTag":"123"},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-18T19:59:31.8324214Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-10-13T18:44:59.5274264Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sakopak-rg/providers/Microsoft.ContainerRegistry/registries/sakopakregisty","name":"sakopakregisty","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"eastus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-09-19T21:04:00.2056918Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-09-19T21:04:00.2056918Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvq6m4yu27skf56tn3qn5zqsmknyedmk2dqmmyukvzidq2mtk6wbyfsjhoqhjct7gf/providers/Microsoft.ContainerRegistry/registries/cliregbgxyyjuhgaez5z","name":"cliregbgxyyjuhgaez5z","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Standard","tier":"Standard"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:03:27.5829894Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:03:27.5829894Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rgvdksdzc5mkzjp6bxbwvo5elyo2cctwcxuvruvg7g7shrsiamk3zwqr4eignkbbk24/providers/Microsoft.ContainerRegistry/registries/testregl3k76cgqtfdedhjzki","name":"testregl3k76cgqtfdedhjzki","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-17T19:04:04.8052779Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-17T19:04:04.8052779Z"}},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","type":"Microsoft.ContainerRegistry/registries","sku":{"name":"Premium","tier":"Premium"},"location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495Z","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495Z"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '2843' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:22 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 1A0FA765BBFC4AFCA8B6CA336630B505 Ref B: CO6AA3150219049 Ref C: 2023-11-28T21:40:23Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --repository --image --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:23 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: 6F674D8498D942D3B2BB689AA8028C37 Ref B: CO6AA3150220027 Ref C: 2023-11-28T21:40:23Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + 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, 28 Nov 2023 21:40:23 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr check-health + Connection: + - keep-alive + ParameterSetName: + - --name --repository --image --yes --ignore-errors + User-Agent: + - AZURECLI/2.54.0 azsdk-python-azure-mgmt-containerregistry/10.1.0 Python/3.11.5 + (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=2022-02-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"westus","tags":{},"systemData":{"createdBy":"sakopak@microsoft.com","createdByType":"User","createdAt":"2023-11-28T21:39:55.7899495+00:00","lastModifiedBy":"sakopak@microsoft.com","lastModifiedByType":"User","lastModifiedAt":"2023-11-28T21:39:55.7899495+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2023-11-28T21:39:55.7899495Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790293+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2023-11-28T21:40:02.1790722+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"dataEndpointHostNames":[],"privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","zoneRedundancy":"Disabled","anonymousPullEnabled":false}}' + headers: + api-supported-versions: + - 2022-02-01-preview + cache-control: + - no-cache + content-length: + - '1422' + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:23 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-msedge-ref: + - 'Ref A: F798D1C1CADE4E8FAC289F1D174DF966 Ref B: CO6AA3150218019 Ref C: 2023-11-28T21:40:24Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + 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, 28 Nov 2023 21:40:24 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: grant_type=access_token&service=clireg3tal56fhkul3xo.azurecr.io&tenant=72f988bf-86f1-41af-91ab-2d7cd011db47&access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSIsImtpZCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNzAxMjA2NzE5LCJuYmYiOjE3MDEyMDY3MTksImV4cCI6MTcwMTIxMTQ1NywiX2NsYWltX25hbWVzIjp7Imdyb3VwcyI6InNyYzEifSwiX2NsYWltX3NvdXJjZXMiOnsic3JjMSI6eyJlbmRwb2ludCI6Imh0dHBzOi8vZ3JhcGgud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3VzZXJzL2E4ZGZkZTlmLWIxYmQtNDBhNS1hOWU2LTA3NTViZDkwNWQxNy9nZXRNZW1iZXJPYmplY3RzIn19LCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFZBQUFBM2c1VWY3Qk9UeEFtMlk0RHNITTI0MkNlRXA2VGNOT1RuQVhmeUJTN0V3WEV0blhObkpXbUdvNTl0bW51b0VNb1llemRSMkEvc2l6THRuV0ZudGMrVGFSdlowd0VhL1JxdXdyRTIvOHdxV1E9IiwiYW1yIjpbInJzYSIsIm1mYSJdLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsImFwcGlkYWNyIjoiMCIsImNhcG9saWRzX2xhdGViaW5kIjpbIjI5Mzk5Y2Y5LTliNmItNDIwNS1iNWIzLTEzYTEzNGU5YjIzMyJdLCJmYW1pbHlfbmFtZSI6IlBhayIsImdpdmVuX25hbWUiOiJTYWtvIiwiaWR0eXAiOiJ1c2VyIiwiaXBhZGRyIjoiMjAwMTo0ODk4OjgwZTg6OToxN2U6OTBiYToyN2UxOmQ4MTIiLCJuYW1lIjoiU2FrbyBQYWsiLCJvaWQiOiJhOGRmZGU5Zi1iMWJkLTQwYTUtYTllNi0wNzU1YmQ5MDVkMTciLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtMjEyNzUyMTE4NC0xNjA0MDEyOTIwLTE4ODc5Mjc1MjctNjg4OTc0NDEiLCJwdWlkIjoiMTAwMzIwMDJCNkVFRTg0NCIsInJoIjoiMC5BUUVBdjRqNWN2R0dyMEdScXkxODBCSGJSMFpJZjNrQXV0ZFB1a1Bhd2ZqMk1CTWFBRU0uIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwic3ViIjoiUGoxc0hOY0NZbEZ4RXdMNUpvZ3Z0NTRleXQyeklIN2hrZG1BbEUwaWp5VSIsInRpZCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInVuaXF1ZV9uYW1lIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXBuIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXRpIjoiNXpwYVl6emhrVS1lYVpMTnhRZlpBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il0sInhtc19jYWUiOiIxIiwieG1zX2NjIjpbIkNQMSJdLCJ4bXNfZmlsdGVyX2luZGV4IjpbIjI2Il0sInhtc19yZCI6IjAuNDJMbFlCUmlsQUlBIiwieG1zX3NzbSI6IjEiLCJ4bXNfdGNkdCI6MTI4OTI0MTU0N30.P3wdkDnaw8Ij7Z4kIDax43aQywhHoCUJ-kiJ5CXb3olm8_lCGK5GRMXfAutOiGxLge9hE1wheAF9h432C0QawOxoD4-cY4U6B8XQ7gDahdeKQ-UsJkT7NQF9c6zs5b0B86ecX22oL6jQtPGUlhYR3GJ1gMzSE-QLj681KmzmSmnRBL8YcNpj_D5N263hf0Elt_ERXH-7TUDZwBRw-W1POEuB1KODhGsJWtAdhAKfsvk55EFVNyHUm6VwqJQ0F4rw3DgXrKCIh8KqijSw1YPLXFSOtVl34lQaxFUepL9zp0tIjFtI07orMVPGf5pRcL3DyGPd4oJPSWi3i9kRFb4g8A + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2420' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/exchange + response: + body: + string: '{"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI0NWM1NzZmNy02NTY2LTQ1MTMtOWZmMS1hNmQwOWIzZGNiNjQiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjUsImV4cCI6MTcwMTIxODQyNSwiaWF0IjoxNzAxMjA2NzI1LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.HNlkJI1FBDgcxQ1Sml15q1KA4i4Knd_PRgNMz2SvOWXWTgcxkslYl4QX0Fj-1WP2EgtrBk4n2oizvz7s75nLIsDxO1256bs3rkzCTbm4V3RhNZMZL2_ufBXLqtEVyPWxgQMl6eK08EIv1xiPbYHMMoAMeLYp_pJRLcY5guICMemqiH3Hz7cl1NpRPBTbwrmHmdVDQ4VG-lJRHo9nbBT3yRlzwqD2eEzW1YWNCv2KyWy5usmk-FIpk5HX2BE1lGqL247MTbRiZgk-kwH5zqA4Tfd4wQWVNc4B_DYhvZbkpHo0JIsea4d2kJJwySLjLhJoX1DdzkYeRVu7DADt3H3FyA"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:25 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.316667' + status: + code: 200 + message: OK +- request: + body: grant_type=refresh_token&service=clireg3tal56fhkul3xo.azurecr.io&scope=repository%3Amicrosoft%3Apull&refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiI0NWM1NzZmNy02NTY2LTQ1MTMtOWZmMS1hNmQwOWIzZGNiNjQiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjUsImV4cCI6MTcwMTIxODQyNSwiaWF0IjoxNzAxMjA2NzI1LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.HNlkJI1FBDgcxQ1Sml15q1KA4i4Knd_PRgNMz2SvOWXWTgcxkslYl4QX0Fj-1WP2EgtrBk4n2oizvz7s75nLIsDxO1256bs3rkzCTbm4V3RhNZMZL2_ufBXLqtEVyPWxgQMl6eK08EIv1xiPbYHMMoAMeLYp_pJRLcY5guICMemqiH3Hz7cl1NpRPBTbwrmHmdVDQ4VG-lJRHo9nbBT3yRlzwqD2eEzW1YWNCv2KyWy5usmk-FIpk5HX2BE1lGqL247MTbRiZgk-kwH5zqA4Tfd4wQWVNc4B_DYhvZbkpHo0JIsea4d2kJJwySLjLhJoX1DdzkYeRVu7DADt3H3FyA + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '1300' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiJiNjEyN2Y0Ny03ZTllLTRjNzMtYTgwMC1lZDFjOTM4MGQ1MzciLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjUsImV4cCI6MTcwMTIxMTIyNSwiaWF0IjoxNzAxMjA2NzI1LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiYWNjZXNzIjpbeyJUeXBlIjoicmVwb3NpdG9yeSIsIk5hbWUiOiJtaWNyb3NvZnQiLCJBY3Rpb25zIjpbInB1bGwiXX1dLCJyb2xlcyI6W10sImdyYW50X3R5cGUiOiJhY2Nlc3NfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiJ9.FgWwJxRWl0N-GNEF4DdWBCY8q6viG3kk3ITsH96_NJKakX7zO_aM-Mi3L_OIUtWXBBdk6Gajn1lovItDgBhBtnHfXWDHYZ3bXKWPoH9NP1kHQT2N8OJ85UagA11J1bnCkoJGfXA7-aNiBi-gZ63JVq8mnTwKlGBIqyBse8yfzEFb-cbaYBsQ8o-8ZtpHHhuM-Mhoqq4E7-h5tGqdTxP6gVcyVgK9W7jrvfsJEDq1hnETq6wsdmAZlPt0OfbLwmWPDjfaRYiWPMKuphJmruDYEU3luqpY8HtFfUxeR30LYpFyrrCJUcORwH4DaMx_kN0oUg16EDNXiPp7H4Aw7DwPVA"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:25 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.283333' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + 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, 28 Nov 2023 21:40:26 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.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.31.0 + 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, 28 Nov 2023 21:40:27 GMT + docker-distribution-api-version: + - registry/2.0 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + www-authenticate: + - Bearer realm="https://clireg3tal56fhkul3xo.azurecr.io/oauth2/token",service="clireg3tal56fhkul3xo.azurecr.io" + x-content-type-options: + - nosniff + status: + code: 401 + message: Unauthorized +- request: + body: grant_type=access_token&service=clireg3tal56fhkul3xo.azurecr.io&tenant=72f988bf-86f1-41af-91ab-2d7cd011db47&access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSIsImtpZCI6IlQxU3QtZExUdnlXUmd4Ql82NzZ1OGtyWFMtSSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNzAxMjA2NzE5LCJuYmYiOjE3MDEyMDY3MTksImV4cCI6MTcwMTIxMTQ1NywiX2NsYWltX25hbWVzIjp7Imdyb3VwcyI6InNyYzEifSwiX2NsYWltX3NvdXJjZXMiOnsic3JjMSI6eyJlbmRwb2ludCI6Imh0dHBzOi8vZ3JhcGgud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3VzZXJzL2E4ZGZkZTlmLWIxYmQtNDBhNS1hOWU2LTA3NTViZDkwNWQxNy9nZXRNZW1iZXJPYmplY3RzIn19LCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFZBQUFBM2c1VWY3Qk9UeEFtMlk0RHNITTI0MkNlRXA2VGNOT1RuQVhmeUJTN0V3WEV0blhObkpXbUdvNTl0bW51b0VNb1llemRSMkEvc2l6THRuV0ZudGMrVGFSdlowd0VhL1JxdXdyRTIvOHdxV1E9IiwiYW1yIjpbInJzYSIsIm1mYSJdLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsImFwcGlkYWNyIjoiMCIsImNhcG9saWRzX2xhdGViaW5kIjpbIjI5Mzk5Y2Y5LTliNmItNDIwNS1iNWIzLTEzYTEzNGU5YjIzMyJdLCJmYW1pbHlfbmFtZSI6IlBhayIsImdpdmVuX25hbWUiOiJTYWtvIiwiaWR0eXAiOiJ1c2VyIiwiaXBhZGRyIjoiMjAwMTo0ODk4OjgwZTg6OToxN2U6OTBiYToyN2UxOmQ4MTIiLCJuYW1lIjoiU2FrbyBQYWsiLCJvaWQiOiJhOGRmZGU5Zi1iMWJkLTQwYTUtYTllNi0wNzU1YmQ5MDVkMTciLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtMjEyNzUyMTE4NC0xNjA0MDEyOTIwLTE4ODc5Mjc1MjctNjg4OTc0NDEiLCJwdWlkIjoiMTAwMzIwMDJCNkVFRTg0NCIsInJoIjoiMC5BUUVBdjRqNWN2R0dyMEdScXkxODBCSGJSMFpJZjNrQXV0ZFB1a1Bhd2ZqMk1CTWFBRU0uIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwic3ViIjoiUGoxc0hOY0NZbEZ4RXdMNUpvZ3Z0NTRleXQyeklIN2hrZG1BbEUwaWp5VSIsInRpZCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInVuaXF1ZV9uYW1lIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXBuIjoic2Frb3Bha0BtaWNyb3NvZnQuY29tIiwidXRpIjoiNXpwYVl6emhrVS1lYVpMTnhRZlpBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il0sInhtc19jYWUiOiIxIiwieG1zX2NjIjpbIkNQMSJdLCJ4bXNfZmlsdGVyX2luZGV4IjpbIjI2Il0sInhtc19yZCI6IjAuNDJMbFlCUmlsQUlBIiwieG1zX3NzbSI6IjEiLCJ4bXNfdGNkdCI6MTI4OTI0MTU0N30.P3wdkDnaw8Ij7Z4kIDax43aQywhHoCUJ-kiJ5CXb3olm8_lCGK5GRMXfAutOiGxLge9hE1wheAF9h432C0QawOxoD4-cY4U6B8XQ7gDahdeKQ-UsJkT7NQF9c6zs5b0B86ecX22oL6jQtPGUlhYR3GJ1gMzSE-QLj681KmzmSmnRBL8YcNpj_D5N263hf0Elt_ERXH-7TUDZwBRw-W1POEuB1KODhGsJWtAdhAKfsvk55EFVNyHUm6VwqJQ0F4rw3DgXrKCIh8KqijSw1YPLXFSOtVl34lQaxFUepL9zp0tIjFtI07orMVPGf5pRcL3DyGPd4oJPSWi3i9kRFb4g8A + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2420' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/exchange + response: + body: + string: '{"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiIwZjQxNGY5NC0wYzZiLTQ1ZDItYTgxMi1mNTMxMjQ1ZTU2MzUiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjcsImV4cCI6MTcwMTIxODQyNywiaWF0IjoxNzAxMjA2NzI3LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.ZD4cMW-TBNprV13wY2qMjA1vki41_kxQoS9C8NtNKOwuaGMnLMHSXZcr2m2QhsdGID3CbKuq1QcKLJRT4LQhGpLyBu0weupxGE3eolCJujHNjMZRnshQhP6MwuPDObU2ZIWz6gcAyiOAGK4v8gGZcNV3B1uN5uaozj--a2ad-l1WJ4demvZGpPNxkjgkDTc95Koh9R20RMmlUCDniSrPjp39XropVkfnWw4a-TqOaqCN7FPob4oCCu0uUtg8NZHLXdqKa8-J3BoAOo96gFUM_FbezY3shiBKKoAu-WdnVbLRgaxBZAP9nietFdaENJNINZEx3XzaQ8GumCD7j_f18A"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:27 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.316667' + status: + code: 200 + message: OK +- request: + body: grant_type=refresh_token&service=clireg3tal56fhkul3xo.azurecr.io&scope=registry%3ANone%3A%2A&refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiIwZjQxNGY5NC0wYzZiLTQ1ZDItYTgxMi1mNTMxMjQ1ZTU2MzUiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjcsImV4cCI6MTcwMTIxODQyNywiaWF0IjoxNzAxMjA2NzI3LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiZ3JhbnRfdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsInRlbmFudCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInBlcm1pc3Npb25zIjp7IkFjdGlvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIiwibWV0YWRhdGEvcmVhZCIsIm1ldGFkYXRhL3dyaXRlIiwiZGVsZXRlZC9yZWFkIiwiZGVsZXRlZC9yZXN0b3JlL2FjdGlvbiJdLCJOb3RBY3Rpb25zIjpudWxsfSwicm9sZXMiOltdfQ.ZD4cMW-TBNprV13wY2qMjA1vki41_kxQoS9C8NtNKOwuaGMnLMHSXZcr2m2QhsdGID3CbKuq1QcKLJRT4LQhGpLyBu0weupxGE3eolCJujHNjMZRnshQhP6MwuPDObU2ZIWz6gcAyiOAGK4v8gGZcNV3B1uN5uaozj--a2ad-l1WJ4demvZGpPNxkjgkDTc95Koh9R20RMmlUCDniSrPjp39XropVkfnWw4a-TqOaqCN7FPob4oCCu0uUtg8NZHLXdqKa8-J3BoAOo96gFUM_FbezY3shiBKKoAu-WdnVbLRgaxBZAP9nietFdaENJNINZEx3XzaQ8GumCD7j_f18A + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '1292' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://clireg000002.azurecr.io/oauth2/token + response: + body: + string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlpCVlk6QlhBTjpURkZVOjNIWkw6TjQ2NTpKRlczOkpXN0w6TFlBVzpQNVNNOlJCUUc6S0szSDpZR1VEIn0.eyJqdGkiOiIwMTYzZjIxMy0wMTBiLTQxM2YtYTk1My01MTRlZTNhMmRiMjkiLCJzdWIiOiJzYWtvcGFrQG1pY3Jvc29mdC5jb20iLCJuYmYiOjE3MDEyMDY3MjgsImV4cCI6MTcwMTIxMTIyOCwiaWF0IjoxNzAxMjA2NzI4LCJpc3MiOiJBenVyZSBDb250YWluZXIgUmVnaXN0cnkiLCJhdWQiOiJjbGlyZWczdGFsNTZmaGt1bDN4by5henVyZWNyLmlvIiwidmVyc2lvbiI6IjEuMCIsInJpZCI6Ijc5MWQ5MGNjNTdjYTRkMDc5YWFlODI2MGJmNDkzZjIwIiwiYWNjZXNzIjpbXSwicm9sZXMiOltdLCJncmFudF90eXBlIjoiYWNjZXNzX3Rva2VuIiwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYifQ.CUOmvoQ3t07tfe12LpT6GprKwGE4GEpOmjNd4IbwU5GjMWc2k5JhwvenyA_cGBtknPWNZ96In12oFwpUSlb8tQXojaIj0Hp67_nFcjeGhvLJR-8ptXbBIqM2sIPSfLCpFooJEdyurxXBzPFs-Bs_ObuApj04rBGHT-E92ISr2GoKcbifYPABwUeT0yfNP0RTC5paZ2Mh9cAi3CqR2DvcSVvEozUXAJT8d2HVX2nuLClHrQ7qWcr2AgszjCE-L2U-959hJqMRCJouhvJuI-bDIKHlByNN13kW0mh2E6RAb1m-sNYk1qhsmf0gM5pyE72bt18XuP-sL5aBAoTjUjStKA"}' + headers: + connection: + - keep-alive + content-type: + - application/json; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:28 GMT + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + x-ms-ratelimit-remaining-calls-per-second: + - '333.316667' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*, application/vnd.oci.artifact.manifest.v1+json, application/vnd.cncf.oras.artifact.manifest.v1+json, + application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, + application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + method: GET + uri: https://clireg000002.azurecr.io/v2/microsoft/manifests/azure-cli?azure-cli + response: + body: + string: "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n + \ \"config\": {\n \"mediaType\": \"application/vnd.docker.container.image.v1+json\",\n + \ \"size\": 11406,\n \"digest\": \"sha256:3f2cb2e6d7eba3300ad0a91473cabe64182e73ea699f62ca3a9317db83e8c8ce\"\n + \ },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 2065537,\n \"digest\": \"sha256:ff3a5c916c92643ff77519ffa742d3ec61b7f591b6b7504599d95a4a41134e28\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 308014,\n \"digest\": \"sha256:471170bb1257626389ed5fd16962cdec310ab3af264ffef445df2773e7420b92\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 26087976,\n \"digest\": \"sha256:d487cc70216ed78f8cbb6fde35207cc9a3617934d6e8d62c1579944f24314e69\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 228,\n \"digest\": \"sha256:9358b3ca3321fc07694e760e1bf656bd77e8faea44df9cc36b6e4a8d50c1a249\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 1993236,\n \"digest\": \"sha256:d4d73eb5841d45aaad22e16135e31b8123fb4856a0f41613d0e26578072c0613\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 55392530,\n \"digest\": \"sha256:5c17e3e2850c5046b47a343db0bd55a40257204ad1c500ff4f9d408bf6082ef2\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 4595257,\n \"digest\": \"sha256:b20703671a927ea52cd430a9c6f6f26f5ec2a29d6b55e897e38df500d50e6cf3\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 98,\n \"digest\": \"sha256:90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 30151881,\n \"digest\": \"sha256:38ab474f751eb7e9dd4344fbb28ce15f2ad1d47caa379e8bb9154bac3da65a3c\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 28813412,\n \"digest\": \"sha256:9f50c4477c0bdd02acb6d1c43fe40ecf4fa2023cdb16bdb158adb11c37cac4e5\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 832,\n \"digest\": \"sha256:6b6db60ae441b5cc9887fdc91e3bd2fc92d52aa791dd22651e0544499b1285bf\"\n + \ }\n ]\n}" + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '2629' + content-type: + - application/vnd.docker.distribution.manifest.v2+json + date: + - Tue, 28 Nov 2023 21:40:28 GMT + docker-content-digest: + - sha256:622731d3e3a16b11a1f318b1c5018d0c44996b4c096b864fe2eac5b8beab535a + docker-distribution-api-version: + - registry/2.0 + etag: + - '"sha256:622731d3e3a16b11a1f318b1c5018d0c44996b4c096b864fe2eac5b8beab535a"' + server: + - openresty + 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/vnd.oci.artifact.manifest.v1+json, application/vnd.cncf.oras.artifact.manifest.v1+json, + application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, + application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + method: GET + uri: https://clireg000002.azurecr.io/v2/microsoft/manifests/azure-cli + response: + body: + string: "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n + \ \"config\": {\n \"mediaType\": \"application/vnd.docker.container.image.v1+json\",\n + \ \"size\": 11406,\n \"digest\": \"sha256:3f2cb2e6d7eba3300ad0a91473cabe64182e73ea699f62ca3a9317db83e8c8ce\"\n + \ },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 2065537,\n \"digest\": \"sha256:ff3a5c916c92643ff77519ffa742d3ec61b7f591b6b7504599d95a4a41134e28\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 308014,\n \"digest\": \"sha256:471170bb1257626389ed5fd16962cdec310ab3af264ffef445df2773e7420b92\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 26087976,\n \"digest\": \"sha256:d487cc70216ed78f8cbb6fde35207cc9a3617934d6e8d62c1579944f24314e69\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 228,\n \"digest\": \"sha256:9358b3ca3321fc07694e760e1bf656bd77e8faea44df9cc36b6e4a8d50c1a249\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 1993236,\n \"digest\": \"sha256:d4d73eb5841d45aaad22e16135e31b8123fb4856a0f41613d0e26578072c0613\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 55392530,\n \"digest\": \"sha256:5c17e3e2850c5046b47a343db0bd55a40257204ad1c500ff4f9d408bf6082ef2\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 4595257,\n \"digest\": \"sha256:b20703671a927ea52cd430a9c6f6f26f5ec2a29d6b55e897e38df500d50e6cf3\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 98,\n \"digest\": \"sha256:90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 30151881,\n \"digest\": \"sha256:38ab474f751eb7e9dd4344fbb28ce15f2ad1d47caa379e8bb9154bac3da65a3c\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 28813412,\n \"digest\": \"sha256:9f50c4477c0bdd02acb6d1c43fe40ecf4fa2023cdb16bdb158adb11c37cac4e5\"\n + \ },\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n + \ \"size\": 832,\n \"digest\": \"sha256:6b6db60ae441b5cc9887fdc91e3bd2fc92d52aa791dd22651e0544499b1285bf\"\n + \ }\n ]\n}" + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '2629' + content-type: + - application/vnd.docker.distribution.manifest.v2+json + date: + - Tue, 28 Nov 2023 21:40:28 GMT + docker-content-digest: + - sha256:622731d3e3a16b11a1f318b1c5018d0c44996b4c096b864fe2eac5b8beab535a + docker-distribution-api-version: + - registry/2.0 + etag: + - '"sha256:622731d3e3a16b11a1f318b1c5018d0c44996b4c096b864fe2eac5b8beab535a"' + server: + - openresty + 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.31.0 + method: GET + uri: https://clireg000002.azurecr.io/v2/microsoft/blobs/sha256:90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405 + response: + body: + string: 'Temporary + Redirect. + + + ' + headers: + access-control-expose-headers: + - Docker-Content-Digest + - WWW-Authenticate + - Link + - X-Ms-Correlation-Request-Id + connection: + - keep-alive + content-length: + - '405' + content-type: + - text/html; charset=utf-8 + date: + - Tue, 28 Nov 2023 21:40:29 GMT + docker-content-digest: + - sha256:90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405 + docker-distribution-api-version: + - registry/2.0 + location: + - https://wusmanaged198.blob.core.windows.net/791d90cc57ca4d079aae8260bf493f20-omvpctoui1//docker/registry/v2/blobs/sha256/90/90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405/data?se=2023-11-28T22%3A00%3A29Z&sig=DDsXBFJ8dnJBnNfzfb62E0PRcSJuHNJbJ2V9pnKMsAY%3D&sp=r&spr=https&sr=b&sv=2018-03-28®id=791d90cc57ca4d079aae8260bf493f20 + server: + - openresty + strict-transport-security: + - max-age=31536000; includeSubDomains + - max-age=31536000; includeSubDomains + x-content-type-options: + - nosniff + status: + code: 307 + message: Temporary Redirect +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + method: GET + uri: https://wusmanaged198.blob.core.windows.net/791d90cc57ca4d079aae8260bf493f20-omvpctoui1/docker/registry/v2/blobs/sha256/90/90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405/data?se=2023-11-28T22%3A00%3A29Z&sig=DDsXBFJ8dnJBnNfzfb62E0PRcSJuHNJbJ2V9pnKMsAY%3D&sp=r&spr=https&sr=b&sv=2018-03-28®id=791d90cc57ca4d079aae8260bf493f20 + response: + body: + string: !!binary | + H4sIAAAAAAAA/0qsKi1K1U3OydRnoBkwMDAxMDc1ZTCAAHQazDY0NjE2MDEyNTA2ZzAwNDQ0MWFQ + MKWdkxCgtLgksYjBwIBSc9A9NwpGwSgYBYMcAAIAAP//a+kCxwAGAAA= + headers: + accept-ranges: + - bytes + content-length: + - '98' + content-type: + - application/octet-stream + date: + - Tue, 28 Nov 2023 21:40:29 GMT + etag: + - '"0x8DBF05A95FF4E0A"' + last-modified: + - Tue, 28 Nov 2023 21:40:05 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-blob-committed-block-count: + - '1' + x-ms-blob-type: + - AppendBlob + x-ms-copy-completion-time: + - Tue, 28 Nov 2023 21:40:05 GMT + x-ms-copy-id: + - 87f1152d-715c-46b1-8685-fc3d5da6fa94 + x-ms-copy-progress: + - 98/98 + x-ms-copy-source: + - https://wusmanaged198.blob.core.windows.net/791d90cc57ca4d079aae8260bf493f20-omvpctoui1//docker/registry/v2/blobs/sha256/90/90f2ddb124f78cd676e7dd7151cec19345f88a4e418d123bdfda77aa3ece2405/data/pending?sv=2018-03-28&sr=b&se=2023-12-05T21%3A40%3A05Z&sp=r&api-version=2018-03-28 + x-ms-copy-status: + - success + x-ms-creation-time: + - Tue, 28 Nov 2023 21:40:05 GMT + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked + x-ms-server-encrypted: + - 'true' + x-ms-version: + - '2018-03-28' + status: + code: 200 + message: OK +version: 1 diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py index a74e90d1470..1e9bbed565e 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_check_health_commands.py @@ -8,28 +8,34 @@ class AcrCheckHealthCommandsTests(ScenarioTest): @ResourceGroupPreparer() - def test_acr_check_health(self, repository_name, image): - registry_name = self.create_random_name('clireg', 20) - image = 'latest' + def test_acr_check_health(self): + repository = 'microsoft' + tag = 'azure-cli' + self.kwargs.update({ - 'registry': registry_name, + 'registry': self.create_random_name('clireg', 20), + 'sku': 'Premium', + 'resource-group': 'rg', 'ignore_errors': False, 'yes': False, 'vnet': None, - 'repository': repository_name, - 'image': image, - 'reason': 'OK' + 'repository': repository, + 'tag': tag, + 'image': '{}:{}'.format(repository, tag), + 'reason': 'OK', + 'source_reg_id': '/subscriptions/dfb63c8c-7c89-4ef8-af13-75c1d873c895/resourcegroups/resourcegroupdiffsub/providers/Microsoft.ContainerRegistry/registries/sourceregistrydiffsub', }) - - # Test the check_health command with the --ignore-errors flag - self.cmd('acr check-health --name {registry_name} --ignore-errors ', - checks=[self.check('name', '{registry_name}'), - self.check('ignoreErrors', False), - self.check('vnet', None)]) - # Test the check_health command to check if blobs can be pulled from the registry - self.cmd('acr check-health --name {registry_name} --repository {repository_name} --image {image}', - checks=[self.check('name', '{registry_name}'), - self.check('repository', '{repository_name}'), - self.check('image', '{image}'), - self.check('reason', 'OK')]) \ No newline at end of file + # Create the registry + result = self.cmd('acr create --name {registry} --sku {sku} --resource-group {rg}').get_output_in_json() + self.kwargs['registry'] = result['name'] + + # Import image to registry. + self.cmd('acr import -n {registry} -r {source_reg_id} --source {image}') + + # Check the health of the registry + self.cmd('acr check-health --name {registry} --yes --ignore-errors') + + # Test if imported image can be pulled from the registry + result = self.cmd('acr check-health --name {registry} --repository {repository} --image {tag} --yes --ignore-errors') + self.assertTrue(result) \ No newline at end of file From 8e23abf0c6fa314ad5a003560287b758ff39a3c5 Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Thu, 7 Dec 2023 14:56:21 -0800 Subject: [PATCH 7/8] 'resolved comments' --- .../azure/cli/command_modules/acr/_help.py | 7 +- .../azure/cli/command_modules/acr/_params.py | 5 +- .../cli/command_modules/acr/check_health.py | 224 ++++++++---------- 3 files changed, 102 insertions(+), 134 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index e4b73b75dcf..0ef896e0f0a 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -49,12 +49,9 @@ - name: Gets health state of the environment, without stopping on first error. text: > az acr check-health --ignore-errors - - name: Verify that blobs within a given image 'sha256:abc123' can be downloaded from the repository. + - name: Verify that blobs within a given image ('name:tag' or 'name@digest') can be downloaded from the repository. text: > - az acr check-health -n MyRegistry -r MyRepository --image sha256:abc123 - - name: Verify that blobs within a given tag 'latest' can be downloaded from the repository. - text: > - az acr check-health -n MyRegistry -r MyRepository -t latest + az acr check-health -n MyRegistry -t sample/hello-world@sha256:123 """ helps['acr check-name'] = """ diff --git a/src/azure-cli/azure/cli/command_modules/acr/_params.py b/src/azure-cli/azure/cli/command_modules/acr/_params.py index af8f2b93da0..c726c558dd8 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_params.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_params.py @@ -434,10 +434,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements c.argument('ignore_errors', options_list=['--ignore-errors'], help='Provide all health checks, even if errors are found', action='store_true', required=False) c.argument('vnet', options_list=['--vnet'], help="Virtual network ID so to run this command inside a VNET to verify the DNS routing to private endpoints", required=False) - c.argument('registry_name', options_list=['--name', '-n'], help="The name of the registry.") - c.argument('repository_name', options_list=['--repository', '-r'], help="The target repository namespace such as 'ubuntu'.") - c.argument('image', options_list=['--image','-t'], - help="The image digest of the manifest such as '--image sha256@abc123', or the tag such as '-t latest'") + c.argument('image', arg_type=image_by_tag_or_digest_type, required=False) with self.argument_context('acr scope-map') as c: c.argument('registry_name', options_list=['--registry', '-r']) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 29368c1eaba..3168d9dab67 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -71,41 +71,55 @@ def _subprocess_communicate(command_parts, shell=False): ) return output, warning, stderr, succeeded - -# Retrieve blob identified by digest - GET {url}/v2/{name}/blobs/{digest} +# Get blob identified by digest - GET {url}/v2/{name}/blobs/{digest} def _get_blob(login_server, repository_name, digest): return 'https://{}/v2/{}/blobs/{}'.format(login_server, repository_name, digest) -# Checks inputted image or tag for possible matches -def _check_image_match(cmd, - registry_name, - repository_name, +# Validate if image layer can be pulled +def _validate_image_layers(repository_name, + digest, + login_server, + username, + password): + + import requests + from ._docker_utils import get_manifest_authorization_header, parse_error_message + + # Get manifest + # GET {url}/v2/{name}/manifests/{reference} + manifest_url = 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, digest) + + manifest_response = requests.get( + manifest_url, + headers=get_manifest_authorization_header(username, password)) + + manifest = manifest_response.json() + + # Get the digest of the smallest blob for performance purposes + smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) + digest = smallest_blob['digest'] + + # Get blob + request_url = _get_blob(login_server, repository_name, digest) + logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) + + res = requests.get(request_url, auth=(username, password)) + + # Return server error message; if server error not available, will return custom error message below + if res.status_code >= 400: + raise CLIError(parse_error_message('Could not get the requested data.', res), res.status_code) + print_pass("Blobs in image '{}' can be pulled from registry '{}'".format(digest, login_server)) + +# Checks inputted image for possible matches +def _check_image_match(repository_name, + digest, login_server, username, - password, - image): + password): from difflib import get_close_matches from .manifest import _get_manifest_path - from .repository import( - acr_repository_show_tags, - _obtain_data_from_registry) + from .repository import _obtain_data_from_registry - if 'sha256' not in image: - tags = acr_repository_show_tags( - cmd, - registry_name=registry_name, - repository=repository_name, - orderby=None, - username=username, - password=password) - # Get a list of tags that have at least 80% similarity with the inputted image name - matches = get_close_matches(image, tags, n=1, cutoff=0.8) - - if matches: - raise CLIError("Tag '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) - return - - # If digest is used, get all digests image_digest_list = _obtain_data_from_registry( login_server=login_server, path=_get_manifest_path(repository_name), @@ -116,11 +130,10 @@ def _check_image_match(cmd, # Get a list of digests that have at least 80% similarity with the inputted image name digests = [item['digest'] for item in image_digest_list] - matches = get_close_matches(image, digests, n=1, cutoff=0.8) + matches = get_close_matches(digest, digests, n=1, cutoff=0.8) if matches: - raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(image, matches[0])) - return + raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(digest, matches[0])) # Checks for the environment # Checks docker command, docker daemon, docker version and docker pull @@ -343,13 +356,12 @@ def _get_endpoint_and_token_status(cmd, login_server, ignore_errors): print_pass("Fetch access token for registry '{}'".format(login_server)) def _check_registry_health(cmd, - registry_name, registry, login_server, ignore_errors): from azure.cli.core.profiles import ResourceType - status_validated = _get_registry_status(login_server, registry_name, ignore_errors) + status_validated = _get_registry_status(login_server, registry.name, ignore_errors) if status_validated: _get_endpoint_and_token_status(cmd, login_server, ignore_errors) @@ -371,21 +383,20 @@ def _check_registry_health(cmd, pass if not valid_identity: from ._errors import CMK_MANAGED_IDENTITY_ERROR - _handle_error(CMK_MANAGED_IDENTITY_ERROR.format_error_message(registry_name), ignore_errors) + _handle_error(CMK_MANAGED_IDENTITY_ERROR.format_error_message(registry.name), ignore_errors) def _check_private_endpoint(cmd, - registry_name, registry, vnet_of_private_endpoint): # pylint: disable=too-many-locals, too-many-statements import socket from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id - if registry_name is None: + if registry.name is None: raise CLIError("Registry name must be provided to verify DNS routings of its private endpoints") if not registry.private_endpoint_connections: - raise CLIError('Registry "{}" doesn\'t have private endpoints to verify DNS routings.'.format(registry_name)) + raise CLIError('Registry "{}" doesn\'t have private endpoints to verify DNS routings.'.format(registry.name)) if is_valid_resource_id(vnet_of_private_endpoint): res = parse_resource_id(vnet_of_private_endpoint) @@ -423,21 +434,21 @@ def _check_private_endpoint(cmd, if dns_config["privateLinkConnectionProperties"]["fqdns"][0] in dns_mappings: err = ('Registry "{}" has more than one private endpoint in the vnet of "{}".' ' DNS routing will be unreliable') - raise CLIError(err.format(registry_name, vnet_of_private_endpoint)) + raise CLIError(err.format(registry.name, vnet_of_private_endpoint)) dns_mappings[dns_config["privateLinkConnectionProperties"]["fqdns"][0]] = dns_config["privateIPAddress"] dns_ok = True if not dns_mappings: err = ('Registry "{}" doesn\'t have private endpoints in the vnet of "{}".' ' Please make sure you provided correct vnet') - raise CLIError(err.format(registry_name, vnet_of_private_endpoint)) + raise CLIError(err.format(registry.name, vnet_of_private_endpoint)) for fqdn in dns_mappings: try: result = socket.gethostbyname(fqdn) if result != dns_mappings[fqdn]: err = 'DNS routing to registry "%s" through private IP is incorrect. Expect: %s, Actual: %s' - logger.warning(err, registry_name, dns_mappings[fqdn], result) + logger.warning(err, registry.name, dns_mappings[fqdn], result) dns_ok = False except Exception as e: # pylint: disable=broad-except logger.warning('Error resolving DNS for %s. Ex: %s', fqdn, e) @@ -449,13 +460,12 @@ def _check_private_endpoint(cmd, raise CLIError('DNS routing verification failed') # Validate --image input -def validate_image(cmd, - registry_name, - repository_name, - login_server, - username, - password, - image): +# Validate if image layer can be pulled +def _validate_image_name(repository_name, + digest, + login_server, + username, + password): from .manifest import _get_v2_manifest_path from ._docker_utils import ( @@ -468,75 +478,41 @@ def validate_image(cmd, request_data_from_registry( http_method='get', login_server=login_server, - path=_get_v2_manifest_path(repository_name, image), + path=_get_v2_manifest_path(repository_name, digest), username=username, password=password, json_payload=None, file_payload=None, manifest_headers=get_manifest_authorization_header(username, password), - params=image) + params=digest) except RegistryException as e: if e.status_code == 404: - _check_image_match(cmd, - registry_name, - repository_name, + _check_image_match(repository_name, + digest, login_server, username, - password, - image) - raise CLIError("{} Please check if image/tag was inputted correctly.".format(str(e))) - -# Validate if blob layer can be pulled -def _check_blob(repository_name, - login_server, - username, - password, - image): - - import requests - from ._docker_utils import get_manifest_authorization_header, parse_error_message + password) + raise CLIError("{} Please check if image was inputted correctly.".format(str(e))) - # Get manifest - # GET {url}/v2/{name}/manifests/{reference} - manifest_url = 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, image) - - manifest_response = requests.get( - manifest_url, - headers=get_manifest_authorization_header(username, password)) - - manifest = manifest_response.json() - - # Get the digest of the smallest blob for performance purposes - smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) - digest = smallest_blob['digest'] - - # Get blob - request_url = _get_blob(login_server, repository_name, digest) - logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) - - res = requests.get(request_url, auth=(username, password)) - - # Return server error message; if server error not available, will return error message below - if res.status_code >= 400: - raise CLIError(parse_error_message('Could not get the requested data.', res), res.status_code) - # Check if image or tag was inputted and return appropriate message - if res.status_code < 400 and 'sha256' not in image: - print_pass("Blobs referenced by tag '{}' can be pulled from registry '{}'".format(image, login_server)) - else: - print_pass("Blobs in image '{}' can be pulled from registry '{}'".format(image, login_server)) + _validate_image_layers(repository_name, + digest, + login_server, + username, + password) # General command def acr_check_health(cmd, # pylint: disable useless-return - vnet=None, - ignore_errors=False, - yes=False, registry_name=None, - repository_name=None, image=None, - resource_group_name=None): + vnet=None, + yes=False, + ignore_errors=False, + resource_group_name=None, + username=None, + password=None): from azure.cli.core.util import in_cloud_console - from .repository import get_access_credentials + from .repository import get_access_credentials, get_image_digest from ._utils import get_resource_group_name_by_registry_name rg = get_resource_group_name_by_registry_name(cmd.cli_ctx, registry_name, resource_group_name) @@ -549,23 +525,14 @@ def acr_check_health(cmd, # pylint: disable useless-return login_server = registry.login_server.rstrip('/') except CLIError: from ._docker_utils import get_login_server_suffix + # Checking the Azure Container Registry login server suffix in the current cloud suffix = get_login_server_suffix(cmd.cli_ctx) - + # If not found, return error if not suffix: from ._errors import LOGIN_SERVER_ERROR _handle_error(LOGIN_SERVER_ERROR.format_error_message(registry_name), ignore_errors) return - # Get the access credentials for the registry - login_server, username, password = get_access_credentials( - cmd, - registry_name=registry_name, - tenant_suffix=None, - username=None, - password=None, - repository=repository_name, - permission='pull') - in_cloud_console = in_cloud_console() if in_cloud_console: logger.warning("Environment checks are not supported in Azure Cloud Shell.") @@ -574,26 +541,33 @@ def acr_check_health(cmd, # pylint: disable useless-return _get_cli_version() _check_registry_health(cmd, - registry_name, registry, login_server, ignore_errors) - # If repository and image are provided, validate image input - # Then check if blob layer can be pulled - if (image and repository_name): - validate_image(cmd, - registry_name, - repository_name, - login_server, - username, - password, - image) - _check_blob(repository_name, - login_server, - username, - password, - image) + # If --image is inputted, validate image + if image: + # Get repository name and digest + try: + repository_name, digest = get_image_digest(cmd, registry_name, image, username, password) + except CLIError as e: + raise CLIError("Could not find image '{}'. {}".format(image, e)) + + # Get the access credentials for the registry + login_server, username, password = get_access_credentials( + cmd, + registry_name=registry_name, + tenant_suffix=None, + username=None, + password=None, + repository=repository_name, + permission='pull') + + _validate_image_name(repository_name, + digest, + login_server, + username, + password) if vnet: _check_private_endpoint(cmd, registry_name, vnet) From 8bbf0b734e0e923ba59f0f7ebfcbd30a494b5e52 Mon Sep 17 00:00:00 2001 From: Sako Pak Date: Wed, 13 Dec 2023 16:00:26 -0800 Subject: [PATCH 8/8] 'add condition for docker manifest lists' --- .../azure/cli/command_modules/acr/_help.py | 4 +- .../cli/command_modules/acr/check_health.py | 42 ++++++++++++++++--- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index 0ef896e0f0a..f2daaffd1e0 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -49,9 +49,9 @@ - name: Gets health state of the environment, without stopping on first error. text: > az acr check-health --ignore-errors - - name: Verify that blobs within a given image ('name:tag' or 'name@digest') can be downloaded from the repository. + - name: Verify that blobs within a given image, identified as 'name:tag' or 'name@digest', can be downloaded from the repository. text: > - az acr check-health -n MyRegistry -t sample/hello-world@sha256:123 + az acr check-health -n MyRegistry -t hello-world@sha256:123 """ helps['acr check-name'] = """ diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 3168d9dab67..bcb374d0c98 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -95,17 +95,41 @@ def _validate_image_layers(repository_name, manifest = manifest_response.json() - # Get the digest of the smallest blob for performance purposes - smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) - digest = smallest_blob['digest'] + # Pull the smallest blob layer in the image to test if the image can be pulled + # First, check if the manifest is a Docker Manifest List + if manifest['mediaType'] == 'application/vnd.docker.distribution.manifest.list.v2+json': + smallest_blobs = [] + + # Iterate over each manifest in the list + for manifest_item in manifest['manifests']: + # Get the manifest for the image + image_manifest_response = requests.get( + 'https://{}/v2/{}/manifests/{}'.format(login_server, repository_name, manifest_item['digest']), + headers=get_manifest_authorization_header(username, password)) + + image_manifest = image_manifest_response.json() + + # Find the smallest blob in the image manifest + smallest_blob = min(image_manifest['layers'], key=lambda layer: layer['size']) + smallest_blobs.append(smallest_blob) + + # Find the smallest blob across all image manifests + smallest_blob = min(smallest_blobs, key=lambda blob: blob['size']) + + else: + # If manifest is not a Docker Manifest List, find the smallest blob in the given single manifest + smallest_blob = min(manifest['layers'], key=lambda layer: layer['size']) + + smallest_digest = smallest_blob['digest'] # Get blob - request_url = _get_blob(login_server, repository_name, digest) + request_url = _get_blob(login_server, repository_name, smallest_digest) logger.debug(add_timestamp("Sending a HTTP GET request to {}".format(request_url))) res = requests.get(request_url, auth=(username, password)) - # Return server error message; if server error not available, will return custom error message below + # If blob layer cannot be pulled, return server error message; + # If server error not available, will return custom error message if res.status_code >= 400: raise CLIError(parse_error_message('Could not get the requested data.', res), res.status_code) print_pass("Blobs in image '{}' can be pulled from registry '{}'".format(digest, login_server)) @@ -132,6 +156,7 @@ def _check_image_match(repository_name, digests = [item['digest'] for item in image_digest_list] matches = get_close_matches(digest, digests, n=1, cutoff=0.8) + # Give a suggestion to the user if a match is found if matches: raise CLIError("Image '{}' not found. Did you mean to input '{}'?".format(digest, matches[0])) @@ -473,7 +498,7 @@ def _validate_image_name(repository_name, get_manifest_authorization_header, RegistryException ) - + # First check if image exists in repository before validating image layers try: request_data_from_registry( http_method='get', @@ -486,15 +511,20 @@ def _validate_image_name(repository_name, manifest_headers=get_manifest_authorization_header(username, password), params=digest) + # If image does not exist, check for possible matches + # This helps deliver a more useful error message in case of a typo or other user error except RegistryException as e: if e.status_code == 404: + # If at least 80% similarity with the inputted image name is found, return a suggested image name to user _check_image_match(repository_name, digest, login_server, username, password) + # otherwise, return the error message raise CLIError("{} Please check if image was inputted correctly.".format(str(e))) + # If image exists, then validate image layers and check if blob can be pulled _validate_image_layers(repository_name, digest, login_server,