From 706e798076ca94049757c281a4ae148eadd6dbb3 Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Wed, 11 May 2022 09:05:58 -0700 Subject: [PATCH 1/7] fix lstrip bug --- src/azure-cli/azure/cli/command_modules/acr/manifest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/manifest.py b/src/azure-cli/azure/cli/command_modules/acr/manifest.py index c37c26353eb..827f0bec872 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/manifest.py +++ b/src/azure-cli/azure/cli/command_modules/acr/manifest.py @@ -118,7 +118,8 @@ def _obtain_referrers_from_registry(login_server, def _parse_fqdn(cmd, fqdn, is_manifest=True): try: - fqdn = fqdn.lstrip('https://') + if fqdn.startswith('https://'): + fqdn = fqdn[len('https://'):] reg_addr = fqdn.split('/', 1)[0] registry_name = reg_addr.split('.', 1)[0] reg_suffix = '.' + reg_addr.split('.', 1)[1] From f5de197ebcaed94767c9dc3b0ca62cf24fd5a51b Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Wed, 11 May 2022 09:08:16 -0700 Subject: [PATCH 2/7] fix next link bug --- src/azure-cli/azure/cli/command_modules/acr/repository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/repository.py b/src/azure-cli/azure/cli/command_modules/acr/repository.py index bb9777fd15b..2e8817707c5 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/repository.py +++ b/src/azure-cli/azure/cli/command_modules/acr/repository.py @@ -113,7 +113,7 @@ def _obtain_data_from_registry(login_server, # we should follow the next path indicated in the link header next_link_path = next_link[(next_link.index('<') + 1):next_link.index('>')] tokens = next_link_path.split('?', 2) - params = {y[0]: unquote(y[1]) for y in (x.split('=', 2) for x in tokens[1].split('&'))} + params = {y[0]: unquote(y[1]) for y in (x.split('=', 1) for x in tokens[1].split('&'))} execute_next_http_call = True return result_list From 49101a5017731a0dda55d6c884011be4c6dfb807 Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Wed, 11 May 2022 10:02:46 -0700 Subject: [PATCH 3/7] fix user/pass bug --- src/azure-cli/azure/cli/command_modules/acr/manifest.py | 6 +++--- src/azure-cli/azure/cli/command_modules/acr/repository.py | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/manifest.py b/src/azure-cli/azure/cli/command_modules/acr/manifest.py index 827f0bec872..e3a6a78fb88 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/manifest.py +++ b/src/azure-cli/azure/cli/command_modules/acr/manifest.py @@ -255,7 +255,7 @@ def acr_manifest_list_referrers(cmd, if not manifest: image = repository + ':' + tag - repository, tag, manifest = get_image_digest(cmd, registry_name, image) + repository, tag, manifest = get_image_digest(cmd, registry_name, image, tenant_suffix, username, password) login_server, username, password = get_access_credentials( cmd=cmd, @@ -307,7 +307,7 @@ def acr_manifest_show(cmd, if not manifest: image = repository + ':' + tag - repository, tag, manifest = get_image_digest(cmd, registry_name, image) + repository, tag, manifest = get_image_digest(cmd, registry_name, image, tenant_suffix, username, password) login_server, username, password = get_access_credentials( cmd=cmd, @@ -433,7 +433,7 @@ def acr_manifest_delete(cmd, if not manifest: image = repository + ':' + tag - repository, tag, manifest = get_image_digest(cmd, registry_name, image) + repository, tag, manifest = get_image_digest(cmd, registry_name, image, tenant_suffix, username, password) login_server, username, password = get_access_credentials( cmd=cmd, diff --git a/src/azure-cli/azure/cli/command_modules/acr/repository.py b/src/azure-cli/azure/cli/command_modules/acr/repository.py index 2e8817707c5..7e0de41132a 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/repository.py +++ b/src/azure-cli/azure/cli/command_modules/acr/repository.py @@ -489,7 +489,7 @@ def _delete_manifest_confirmation(login_server, return manifest -def get_image_digest(cmd, registry_name, image): +def get_image_digest(cmd, registry_name, image, tenant_suffix=None, username=None, password=None): repository, tag, manifest = _parse_image_name(image, allow_digest=True) if manifest: @@ -499,6 +499,9 @@ def get_image_digest(cmd, registry_name, image): login_server, username, password = get_access_credentials( cmd=cmd, registry_name=registry_name, + tenant_suffix=tenant_suffix, + username=username, + password=password, repository=repository, permission=RepoAccessTokenPermission.METADATA_READ.value) From e840255f6b0a6d50ed42cc1dbef4336cc2441c06 Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Mon, 16 May 2022 14:09:15 -0700 Subject: [PATCH 4/7] update tests --- .../azure/cli/command_modules/acr/repository.py | 2 +- .../acr/tests/latest/test_acr_commands_mock.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/repository.py b/src/azure-cli/azure/cli/command_modules/acr/repository.py index 7e0de41132a..a745cafbab2 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/repository.py +++ b/src/azure-cli/azure/cli/command_modules/acr/repository.py @@ -112,7 +112,7 @@ def _obtain_data_from_registry(login_server, # like `Link: ; rel="next"` # we should follow the next path indicated in the link header next_link_path = next_link[(next_link.index('<') + 1):next_link.index('>')] - tokens = next_link_path.split('?', 2) + tokens = next_link_path.split('?', 1) params = {y[0]: unquote(y[1]) for y in (x.split('=', 1) for x in tokens[1].split('&'))} execute_next_http_call = True diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py index 68c06c3ad16..77a9114ae3d 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py @@ -458,6 +458,17 @@ def test_manifest_show(self, mock_requests_get, mock_get_manifest_digest, mock_g timeout=300, verify=mock.ANY) + # Test https strip + acr_manifest_show(cmd, + manifest_id=['https://testregistry.azurecr.io/testrepository:testtag']) + mock_requests_get.assert_called_with( + method='get', + url='https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', + headers=get_manifest_authorization_header('username', 'password'), + params=None, + json=None, + timeout=300, + verify=mock.ANY) @mock.patch('azure.cli.command_modules.acr.manifest.get_access_credentials', autospec=True) @mock.patch('azure.cli.command_modules.acr.repository.get_access_credentials', autospec=True) From 3baf5c7a143ed1fbe54f32fe464a16400080778c Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Fri, 1 Jul 2022 09:33:21 -0700 Subject: [PATCH 5/7] changes for rc1 --- .../azure/cli/command_modules/acr/manifest.py | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/manifest.py b/src/azure-cli/azure/cli/command_modules/acr/manifest.py index e3a6a78fb88..80f39d88130 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/manifest.py +++ b/src/azure-cli/azure/cli/command_modules/acr/manifest.py @@ -39,7 +39,7 @@ 'time_desc': 'timedesc' } DEFAULT_PAGINATION = 100 - +REF_KEY = "referrers" BAD_ARGS_ERROR_REPO = "You must provide either a fully qualified repository specifier such as"\ " 'MyRegistry.azurecr.io/hello-world' as a positional parameter or"\ " provide '-r MyRegistry -n hello-world' argument values." @@ -51,10 +51,8 @@ def _get_v2_manifest_path(repository, manifest): return '/v2/{}/manifests/{}'.format(repository, manifest) - -def _get_referrers_path(repository, manifest): - return '/oras/artifacts/v1/{}/manifests/{}/referrers'.format(repository, manifest) - +def _get_referrers_path(repository): + return '/v2/{}/_oras/artifacts/referrers'.format(repository) def _obtain_manifest_from_registry(login_server, path, @@ -78,12 +76,14 @@ def _obtain_referrers_from_registry(login_server, path, username, password, + digest, artifact_type=None): - result_list = {'references': []} + result_list = {REF_KEY: []} execute_next_http_call = True params = { + 'digest': digest, 'artifactType': artifact_type } @@ -100,7 +100,7 @@ def _obtain_referrers_from_registry(login_server, params=params) if result: - result_list['references'].extend(result['references']) + result_list[REF_KEY].extend(result[REF_KEY]) if next_link: # The registry is telling us there's more items in the list, @@ -268,22 +268,23 @@ def acr_manifest_list_referrers(cmd, raw_result = _obtain_referrers_from_registry( login_server=login_server, - path=_get_referrers_path(repository, manifest), + path=_get_referrers_path(repository), username=username, password=password, - artifact_type=artifact_type) + artifact_type=artifact_type, + digest=manifest) - ref_key = "references" if recursive: - for referrers_obj in raw_result[ref_key]: + for referrers_obj in raw_result[REF_KEY]: internal_referrers_obj = _obtain_referrers_from_registry( login_server=login_server, - path=_get_referrers_path(repository, referrers_obj["digest"]), + path=_get_referrers_path(repository), username=username, - password=password) + password=password, + digest=referrers_obj["digest"]) - for ref in internal_referrers_obj[ref_key]: - raw_result[ref_key].append(ref) + for ref in internal_referrers_obj[REF_KEY]: + raw_result[REF_KEY].append(ref) return raw_result From a8154f5ee4df1e966ef6de8f8b7436292f8614f0 Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Tue, 5 Jul 2022 20:01:05 -0700 Subject: [PATCH 6/7] more changes --- .../cli/command_modules/acr/_constants.py | 2 ++ .../azure/cli/command_modules/acr/_format.py | 6 +++-- .../azure/cli/command_modules/acr/manifest.py | 6 ++++- .../tests/latest/test_acr_commands_mock.py | 22 ++++++++++++++----- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/_constants.py b/src/azure-cli/azure/cli/command_modules/acr/_constants.py index 7f6d69c033c..c1ce1a7a065 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_constants.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_constants.py @@ -30,6 +30,8 @@ ALLOWED_TASK_FILE_TYPES = ('.yaml', '.yml', '.toml', '.json', '.sh', '.bash', '.zsh', '.ps1', '.ps', '.cmd', '.bat', '.ts', '.js', '.php', '.py', '.rb', '.lua') +REF_KEY = "referrers" + def get_classic_sku(cmd): SkuName = cmd.get_models('SkuName') diff --git a/src/azure-cli/azure/cli/command_modules/acr/_format.py b/src/azure-cli/azure/cli/command_modules/acr/_format.py index 0552cecca9e..3ecea58fb06 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_format.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_format.py @@ -6,7 +6,9 @@ from collections import OrderedDict from datetime import datetime from knack.log import get_logger - +from ._constants import ( + REF_KEY +) logger = get_logger(__name__) @@ -132,7 +134,7 @@ def connected_registry_list_output_format(result): def list_referrers_output_format(result): manifests = [] - for manifest in result['references']: + for manifest in result[REF_KEY]: manifests.append(OrderedDict([ ('Digest', _get_value(manifest, 'digest')), ('ArtifactType', _get_value(manifest, 'artifactType')), diff --git a/src/azure-cli/azure/cli/command_modules/acr/manifest.py b/src/azure-cli/azure/cli/command_modules/acr/manifest.py index 80f39d88130..23eb4333fd6 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/manifest.py +++ b/src/azure-cli/azure/cli/command_modules/acr/manifest.py @@ -32,6 +32,9 @@ BAD_REPO_FQDN ) +from ._constants import ( + REF_KEY +) logger = get_logger(__name__) ORDERBY_PARAMS = { @@ -39,7 +42,6 @@ 'time_desc': 'timedesc' } DEFAULT_PAGINATION = 100 -REF_KEY = "referrers" BAD_ARGS_ERROR_REPO = "You must provide either a fully qualified repository specifier such as"\ " 'MyRegistry.azurecr.io/hello-world' as a positional parameter or"\ " provide '-r MyRegistry -n hello-world' argument values." @@ -51,9 +53,11 @@ def _get_v2_manifest_path(repository, manifest): return '/v2/{}/manifests/{}'.format(repository, manifest) + def _get_referrers_path(repository): return '/v2/{}/_oras/artifacts/referrers'.format(repository) + def _obtain_manifest_from_registry(login_server, path, username, diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py index 77a9114ae3d..0d1f43f4870 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py @@ -551,9 +551,13 @@ def test_manifest_list_referrers(self, mock_requests_get, mock_get_manifest_dige manifest_spec='testrepository:testtag') mock_requests_get.assert_called_with( method='get', - url='https://testregistry.azurecr.io/oras/artifacts/v1/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7/referrers', + url='https://testregistry.azurecr.io/v2/testrepository/_oras/artifacts/referrers', headers=get_authorization_header('username', 'password'), - params={'artifactType': None}, + params= + { + 'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', + 'artifactType': None + }, json=None, timeout=300, verify=mock.ANY) @@ -564,9 +568,13 @@ def test_manifest_list_referrers(self, mock_requests_get, mock_get_manifest_dige manifest_spec='testrepository@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7') mock_requests_get.assert_called_with( method='get', - url='https://testregistry.azurecr.io/oras/artifacts/v1/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7/referrers', + url='https://testregistry.azurecr.io/v2/testrepository/_oras/artifacts/referrers', headers=get_authorization_header('username', 'password'), - params={'artifactType': None}, + params= + { + 'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', + 'artifactType': None + }, json=None, timeout=300, verify=mock.ANY) @@ -577,9 +585,11 @@ def test_manifest_list_referrers(self, mock_requests_get, mock_get_manifest_dige artifact_type='sbom/example') mock_requests_get.assert_called_with( method='get', - url='https://testregistry.azurecr.io/oras/artifacts/v1/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7/referrers', + url='https://testregistry.azurecr.io/v2/testrepository/_oras/artifacts/referrers', headers=get_authorization_header('username', 'password'), - params={'artifactType': 'sbom/example'}, + params={ + 'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', + 'artifactType': 'sbom/example'}, json=None, timeout=300, verify=mock.ANY) From d2a7cb773aee6b2a534ab884d86a7cf1905ae230 Mon Sep 17 00:00:00 2001 From: Matt Benedix Date: Wed, 6 Jul 2022 10:38:10 -0700 Subject: [PATCH 7/7] formatting --- .../acr/tests/latest/test_acr_commands_mock.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py index 0d1f43f4870..ceb641fd6f5 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands_mock.py @@ -553,8 +553,7 @@ def test_manifest_list_referrers(self, mock_requests_get, mock_get_manifest_dige method='get', url='https://testregistry.azurecr.io/v2/testrepository/_oras/artifacts/referrers', headers=get_authorization_header('username', 'password'), - params= - { + params={ 'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', 'artifactType': None }, @@ -570,8 +569,7 @@ def test_manifest_list_referrers(self, mock_requests_get, mock_get_manifest_dige method='get', url='https://testregistry.azurecr.io/v2/testrepository/_oras/artifacts/referrers', headers=get_authorization_header('username', 'password'), - params= - { + params={ 'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', 'artifactType': None }, @@ -589,7 +587,8 @@ def test_manifest_list_referrers(self, mock_requests_get, mock_get_manifest_dige headers=get_authorization_header('username', 'password'), params={ 'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7', - 'artifactType': 'sbom/example'}, + 'artifactType': 'sbom/example' + }, json=None, timeout=300, verify=mock.ANY)