def test_repository_show_tags(self, mock_requests_get, mock_get_access_credentials, mock_get_registry_by_name):
        cmd = self._setup_cmd()

        encoded_tags = json.dumps({'tags': ['testtag1', 'testtag2']}).encode()
        encoded_tags_detail = json.dumps({'tags': [
            {
                'digest': 'sha256:b972dda797ef258a7ea5738eb2109778c2bac6a99d1033e6c9f9bdb4fbd196e7',
                'name': 'testtag1'
            },
            {
                'digest': 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
                'name': 'testtag2'
            }]}).encode()

        response = mock.MagicMock()
        response.headers = {}
        response.status_code = 200

        # Show tags using Basic auth on a classic registry
        mock_get_registry_by_name.return_value = Registry(location='westus', sku=Sku(name='Classic')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', 'username', 'password'
        response.content = encoded_tags
        mock_requests_get.return_value = response

        acr_repository_show_tags(cmd, 'testregistry', 'testrepository')
        mock_requests_get.assert_called_with(
            method='get',
            url='https://testregistry.azurecr.io/v2/testrepository/tags/list',
            headers=get_authorization_header('username', 'password'),
            params={
                'n': 100,
                'orderby': None
            },
            json=None,
            verify=mock.ANY)

        # Show tags using Bearer auth on a managed registry
        mock_get_registry_by_name.return_value = Registry(location='westus', sku=Sku(name='Standard')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', EMPTY_GUID, 'password'
        response.content = encoded_tags_detail
        mock_requests_get.return_value = response

        acr_repository_show_tags(cmd, 'testregistry', 'testrepository', top=10, orderby='time_desc', detail=True)
        mock_requests_get.assert_called_with(
            method='get',
            url='https://testregistry.azurecr.io/acr/v1/testrepository/_tags',
            headers=get_authorization_header(EMPTY_GUID, 'password'),
            params={
                'n': 10,
                'orderby': 'timedesc'
            },
            json=None,
            verify=mock.ANY)
    def test_repository_list(self, mock_requests_get,
                             mock_get_access_credentials,
                             mock_get_registry_by_name):
        cmd = mock.MagicMock()
        cmd.cli_ctx = DummyCli()
        encoded_repositories = json.dumps({
            'repositories': ['testrepo1', 'testrepo2']
        }).encode()

        response = mock.MagicMock()
        response.headers = {}
        response.status_code = 200
        response.content = encoded_repositories
        mock_requests_get.return_value = response

        # List repositories using Basic auth on a classic registry
        mock_get_registry_by_name.return_value = Registry(
            location='westus', sku=Sku(name='Classic')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', 'username', 'password'
        acr_repository_list(cmd, 'testregistry')
        mock_requests_get.assert_called_with(
            method='get',
            url='https://testregistry.azurecr.io/v2/_catalog',
            headers=get_authorization_header('username', 'password'),
            params={
                'n': 100,
                'orderby': None
            },
            json=None,
            data=None,
            verify=mock.ANY)

        # List repositories using Bearer auth on a managed registry
        mock_get_registry_by_name.return_value = Registry(
            location='westus', sku=Sku(name='Standard')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', EMPTY_GUID, 'password'
        acr_repository_list(cmd, 'testregistry', top=10)
        mock_requests_get.assert_called_with(
            method='get',
            url='https://testregistry.azurecr.io/acr/v1/_catalog',
            headers=get_authorization_header(EMPTY_GUID, 'password'),
            params={
                'n': 10,
                'orderby': None
            },
            json=None,
            data=None,
            verify=mock.ANY)
    def test_repository_show(self, mock_requests_get,
                             mock_get_access_credentials,
                             mock_get_registry_by_name):
        cmd = mock.MagicMock()
        cmd.cli_ctx = DummyCli()
        encoded_manifests = json.dumps({
            'registry': 'testregistry.azurecr.io',
            'imageName': 'testrepository'
        }).encode()

        response = mock.MagicMock()
        response.headers = {}
        response.status_code = 200
        response.content = encoded_manifests
        mock_requests_get.return_value = response

        mock_get_registry_by_name.return_value = Registry(
            location='westus', sku=Sku(name='Standard')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', 'username', 'password'

        # Show attributes for a repository
        acr_repository_show(cmd,
                            registry_name='testregistry',
                            repository='testrepository')
        mock_requests_get.assert_called_with(
            method='get',
            url='https://testregistry.azurecr.io/acr/v1/testrepository',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Show attributes for an image by tag
        acr_repository_show(cmd,
                            registry_name='testregistry',
                            image='testrepository:testtag')
        mock_requests_get.assert_called_with(
            method='get',
            url=
            'https://testregistry.azurecr.io/acr/v1/testrepository/_tags/testtag',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Show attributes for an image by manifest digest
        acr_repository_show(
            cmd,
            registry_name='testregistry',
            image=
            'testrepository@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7'
        )
        mock_requests_get.assert_called_with(
            method='get',
            url=
            'https://testregistry.azurecr.io/acr/v1/testrepository/_manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)
    def _core_token_scenarios(self, mock_get_raw_token, mock_requests_get,
                              mock_requests_post, mock_get_registry_by_name,
                              registry_exists, registry_name, login_server,
                              tenant_suffix):
        cmd = self._setup_cmd()

        if registry_exists:
            registry = Registry(location='westus', sku=Sku(name='Standard'))
            registry.login_server = login_server
            mock_get_registry_by_name.return_value = registry, None
        else:
            # Mock the registry could not be found
            mock_get_registry_by_name.side_effect = ResourceNotFound(
                'The resource could not be found.')

        self._setup_mock_token_requests(mock_get_raw_token, mock_requests_get,
                                        mock_requests_post, login_server)

        # Test get refresh token
        get_login_credentials(cmd, registry_name, tenant_suffix=tenant_suffix)
        self._validate_refresh_token_request(mock_requests_get,
                                             mock_requests_post, login_server)

        # Test get access token for container image repository
        get_access_credentials(
            cmd,
            registry_name,
            tenant_suffix=tenant_suffix,
            repository=TEST_REPOSITORY,
            permission=RepoAccessTokenPermission.METADATA_READ.value)
        self._validate_access_token_request(
            mock_requests_get, mock_requests_post, login_server,
            'repository:{}:{}'.format(
                TEST_REPOSITORY,
                RepoAccessTokenPermission.METADATA_READ.value))

        # Test get access token for artifact image repository
        get_access_credentials(cmd,
                               registry_name,
                               tenant_suffix=tenant_suffix,
                               artifact_repository=TEST_REPOSITORY,
                               permission=HelmAccessTokenPermission.PULL.value)
        self._validate_access_token_request(
            mock_requests_get, mock_requests_post, login_server,
            'artifact-repository:{}:{}'.format(
                TEST_REPOSITORY, HelmAccessTokenPermission.PULL.value))
Beispiel #5
0
def acr_create(cmd,
               client,
               registry_name,
               resource_group_name,
               sku,
               location=None,
               storage_account_name=None,
               admin_enabled=False,
               deployment_name=None):
    if sku in MANAGED_REGISTRY_SKU and storage_account_name:
        raise CLIError(
            "Please specify '--sku {}' without providing an existing storage account "
            "to create a managed registry, or specify '--sku Classic --storage-account-name {}' "
            "to create a Classic registry using storage account `{}`.".format(
                sku, storage_account_name, storage_account_name))

    if sku in CLASSIC_REGISTRY_SKU:
        result = client.check_name_availability(registry_name)
        if not result.name_available:
            raise CLIError(result.message)

        logger.warning(
            "Due to the planned deprecation of the Classic registry SKU, we recommend using "
            "Basic, Standard, or Premium for all new registries. See https://aka.ms/acr/skus for details."
        )
        if storage_account_name is None:
            storage_account_name = random_storage_account_name(
                cmd.cli_ctx, registry_name)
            logger.warning(
                "A new storage account '%s' will be created in resource group '%s'.",
                storage_account_name, resource_group_name)
            LongRunningOperation(cmd.cli_ctx)(arm_deploy_template_new_storage(
                cmd.cli_ctx, resource_group_name, registry_name, location, sku,
                storage_account_name, admin_enabled, deployment_name))
        else:
            LongRunningOperation(
                cmd.cli_ctx)(arm_deploy_template_existing_storage(
                    cmd.cli_ctx, resource_group_name, registry_name, location,
                    sku, storage_account_name, admin_enabled, deployment_name))
        return client.get(resource_group_name, registry_name)
    else:
        if storage_account_name:
            logger.warning(
                "The registry '%s' in '%s' SKU is a managed registry. The specified storage account will be ignored.",
                registry_name, sku)
        registry = Registry(location=location,
                            sku=Sku(name=sku),
                            admin_user_enabled=admin_enabled)
        return client.create(resource_group_name, registry_name, registry)
    def _core_token_scenarios(self, mock_get_raw_token, mock_requests_get, mock_requests_post, mock_get_registry_by_name, registry_exists, registry_name, login_server, tenant_suffix):
        cmd = self._setup_cmd()

        if registry_exists:
            registry = Registry(location='westus', sku=Sku(name='Standard'))
            registry.login_server = login_server
            mock_get_registry_by_name.return_value = registry, None
        else:
            # Mock the registry could not be found
            mock_get_registry_by_name.side_effect = ResourceNotFound('The resource could not be found.')

        self._setup_mock_token_requests(mock_get_raw_token, mock_requests_get, mock_requests_post, login_server)

        # Test get refresh token
        get_login_credentials(cmd, registry_name, tenant_suffix=tenant_suffix)
        self._validate_refresh_token_request(mock_requests_get, mock_requests_post, login_server)

        # Test get access token for container image repository
        get_access_credentials(cmd, registry_name, tenant_suffix=tenant_suffix, repository=TEST_REPOSITORY, permission='pull')
        self._validate_access_token_request(mock_requests_get, mock_requests_post, login_server, 'repository:{}:pull'.format(TEST_REPOSITORY))

        # Test get access token for artifact image repository
        get_access_credentials(cmd, registry_name, tenant_suffix=tenant_suffix, artifact_repository=TEST_REPOSITORY, permission='pull')
        self._validate_access_token_request(mock_requests_get, mock_requests_post, login_server, 'artifact-repository:{}:pull'.format(TEST_REPOSITORY))
    def test_get_docker_credentials(self, mock_requests_get,
                                    mock_requests_post,
                                    mock_get_registry_by_name,
                                    mock_get_raw_token):
        cmd = mock.MagicMock()
        cmd.cli_ctx = DummyCli()

        registry = Registry(location='westus', sku=Sku(name='Standard'))
        registry.login_server = 'testregistry.azurecr.io'
        mock_get_registry_by_name.return_value = registry, None

        # Set up challenge response
        challenge_response = mock.MagicMock()
        challenge_response.headers = {
            'WWW-Authenticate':
            'Bearer realm="https://testregistry.azurecr.io/oauth2/token",service="testregistry.azurecr.io"'
        }
        challenge_response.status_code = 401
        mock_requests_get.return_value = challenge_response

        # Set up refresh/access token response
        refresh_token_response = mock.MagicMock()
        refresh_token_response.headers = {}
        refresh_token_response.status_code = 200
        refresh_token_response.content = json.dumps({
            'refresh_token':
            'testrefreshtoken',
            'access_token':
            'testaccesstoken'
        }).encode()
        mock_requests_post.return_value = refresh_token_response

        # Set up AAD token with only access token
        mock_get_raw_token.return_value = (
            'Bearer', 'aadaccesstoken', {}), 'testsubscription', 'testtenant'
        get_login_credentials(cmd.cli_ctx, 'testregistry')
        mock_requests_get.assert_called_with(
            'https://testregistry.azurecr.io/v2/', verify=mock.ANY)
        mock_requests_post.assert_called_with(
            'https://testregistry.azurecr.io/oauth2/exchange',
            urlencode({
                'grant_type': 'access_token',
                'service': 'testregistry.azurecr.io',
                'tenant': 'testtenant',
                'access_token': 'aadaccesstoken'
            }),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            verify=mock.ANY)

        # Test get access token for container image repository
        get_access_credentials(cmd.cli_ctx,
                               'testregistry',
                               repository='testrepository',
                               permission='*')
        mock_requests_post.assert_called_with(
            'https://testregistry.azurecr.io/oauth2/token',
            urlencode({
                'grant_type': 'refresh_token',
                'service': 'testregistry.azurecr.io',
                'scope': 'repository:testrepository:*',
                'refresh_token': 'testrefreshtoken'
            }),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            verify=mock.ANY)

        # Test get access token for artifact image repository
        get_access_credentials(cmd.cli_ctx,
                               'testregistry',
                               artifact_repository='testrepository',
                               permission='*')
        mock_requests_post.assert_called_with(
            'https://testregistry.azurecr.io/oauth2/token',
            urlencode({
                'grant_type': 'refresh_token',
                'service': 'testregistry.azurecr.io',
                'scope': 'artifact-repository:testrepository:*',
                'refresh_token': 'testrefreshtoken'
            }),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            verify=mock.ANY)
    def test_repository_delete(self, mock_requests_get, mock_requests_delete,
                               mock_get_access_credentials,
                               mock_get_registry_by_name):
        cmd = mock.MagicMock()
        cmd.cli_ctx = DummyCli()

        get_response = mock.MagicMock()
        get_response.headers = {
            'Docker-Content-Digest':
            'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7'
        }
        get_response.status_code = 200
        mock_requests_get.return_value = get_response

        delete_response = mock.MagicMock()
        delete_response.headers = {}
        delete_response.status_code = 200
        mock_requests_delete.return_value = delete_response

        mock_get_registry_by_name.return_value = Registry(
            location='westus', sku=Sku(name='Standard')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', 'username', 'password'

        # Delete repository
        acr_repository_delete(cmd,
                              registry_name='testregistry',
                              repository='testrepository',
                              yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/_acr/testrepository/repository',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete image by tag
        acr_repository_delete(cmd,
                              registry_name='testregistry',
                              image='testrepository:testtag',
                              yes=True)
        expected_get_headers = get_authorization_header('username', 'password')
        expected_get_headers.update(MANIFEST_V2_HEADER)
        mock_requests_get.assert_called_with(
            url=
            'https://testregistry.azurecr.io/v2/testrepository/manifests/testtag',
            headers=expected_get_headers,
            verify=mock.ANY)
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete image by manifest digest
        acr_repository_delete(
            cmd,
            registry_name='testregistry',
            image=
            'testrepository@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Untag image
        acr_repository_untag(cmd,
                             registry_name='testregistry',
                             image='testrepository:testtag')
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/_acr/testrepository/tags/testtag',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete tag (deprecating)
        acr_repository_delete(cmd,
                              'testregistry',
                              'testrepository',
                              tag='testtag',
                              yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/_acr/testrepository/tags/testtag',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete manifest with tag (deprecating)
        acr_repository_delete(cmd,
                              'testregistry',
                              'testrepository',
                              tag='testtag',
                              manifest='',
                              yes=True)
        expected_get_headers = get_authorization_header('username', 'password')
        expected_get_headers.update(MANIFEST_V2_HEADER)
        mock_requests_get.assert_called_with(
            url=
            'https://testregistry.azurecr.io/v2/testrepository/manifests/testtag',
            headers=expected_get_headers,
            verify=mock.ANY)
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete manifest with digest (deprecating)
        acr_repository_delete(
            cmd,
            'testregistry',
            'testrepository',
            manifest=
            'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url=
            'https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)
    def test_get_docker_credentials(self, mock_requests_get, mock_requests_post, mock_get_registry_by_name, mock_get_raw_token):
        cmd = mock.MagicMock()
        cmd.cli_ctx = DummyCli()

        registry = Registry(location='westus', sku=Sku(name='Standard'))
        registry.login_server = 'testregistry.azurecr.io'
        mock_get_registry_by_name.return_value = registry, None

        # Set up challenge response
        challenge_response = mock.MagicMock()
        challenge_response.headers = {
            'WWW-Authenticate': 'Bearer realm="https://testregistry.azurecr.io/oauth2/token",service="testregistry.azurecr.io"'
        }
        challenge_response.status_code = 401
        mock_requests_get.return_value = challenge_response

        # Set up refresh/access token response
        refresh_token_response = mock.MagicMock()
        refresh_token_response.headers = {}
        refresh_token_response.status_code = 200
        refresh_token_response.content = json.dumps({
            'refresh_token': 'testrefreshtoken',
            'access_token': 'testaccesstoken'}).encode()
        mock_requests_post.return_value = refresh_token_response

        # Set up AAD token with only access token
        mock_get_raw_token.return_value = ('Bearer', 'aadaccesstoken', {}), 'testsubscription', 'testtenant'
        get_login_credentials(cmd.cli_ctx, 'testregistry')
        mock_requests_get.assert_called_with('https://testregistry.azurecr.io/v2/', verify=mock.ANY)
        mock_requests_post.assert_called_with(
            'https://testregistry.azurecr.io/oauth2/exchange',
            urlencode({
                'grant_type': 'access_token',
                'service': 'testregistry.azurecr.io',
                'tenant': 'testtenant',
                'access_token': 'aadaccesstoken'
            }),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            verify=mock.ANY)

        # Test get access token for container image repository
        get_access_credentials(cmd.cli_ctx, 'testregistry', repository='testrepository', permission='*')
        mock_requests_post.assert_called_with(
            'https://testregistry.azurecr.io/oauth2/token',
            urlencode({
                'grant_type': 'refresh_token',
                'service': 'testregistry.azurecr.io',
                'scope': 'repository:testrepository:*',
                'refresh_token': 'testrefreshtoken'
            }),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            verify=mock.ANY)

        # Test get access token for artifact image repository
        get_access_credentials(cmd.cli_ctx, 'testregistry', artifact_repository='testrepository', permission='*')
        mock_requests_post.assert_called_with(
            'https://testregistry.azurecr.io/oauth2/token',
            urlencode({
                'grant_type': 'refresh_token',
                'service': 'testregistry.azurecr.io',
                'scope': 'artifact-repository:testrepository:*',
                'refresh_token': 'testrefreshtoken'
            }),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            verify=mock.ANY)
    def test_repository_delete(self, mock_requests_delete, mock_get_manifest_digest, mock_get_access_credentials, mock_get_registry_by_name):
        cmd = self._setup_cmd()

        delete_response = mock.MagicMock()
        delete_response.headers = {}
        delete_response.status_code = 200
        mock_requests_delete.return_value = delete_response

        mock_get_registry_by_name.return_value = Registry(location='westus', sku=Sku(name='Standard')), 'testrg'
        mock_get_access_credentials.return_value = 'testregistry.azurecr.io', 'username', 'password'
        mock_get_manifest_digest.return_value = 'sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7'

        # Delete repository
        acr_repository_delete(cmd,
                              registry_name='testregistry',
                              repository='testrepository',
                              yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url='https://testregistry.azurecr.io/acr/v1/testrepository',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete image by tag
        acr_repository_delete(cmd,
                              registry_name='testregistry',
                              image='testrepository:testtag',
                              yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url='https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Delete image by manifest digest
        acr_repository_delete(cmd,
                              registry_name='testregistry',
                              image='testrepository@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
                              yes=True)
        mock_requests_delete.assert_called_with(
            method='delete',
            url='https://testregistry.azurecr.io/v2/testrepository/manifests/sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)

        # Untag image
        acr_repository_untag(cmd,
                             registry_name='testregistry',
                             image='testrepository:testtag')
        mock_requests_delete.assert_called_with(
            method='delete',
            url='https://testregistry.azurecr.io/acr/v1/testrepository/_tags/testtag',
            headers=get_authorization_header('username', 'password'),
            params=None,
            json=None,
            verify=mock.ANY)