commit
d23910fb86
@ -14,6 +14,7 @@ from .datapipeline import mock_datapipeline, mock_datapipeline_deprecated # fla
|
|||||||
from .dynamodb import mock_dynamodb, mock_dynamodb_deprecated # flake8: noqa
|
from .dynamodb import mock_dynamodb, mock_dynamodb_deprecated # flake8: noqa
|
||||||
from .dynamodb2 import mock_dynamodb2, mock_dynamodb2_deprecated # flake8: noqa
|
from .dynamodb2 import mock_dynamodb2, mock_dynamodb2_deprecated # flake8: noqa
|
||||||
from .ec2 import mock_ec2, mock_ec2_deprecated # flake8: noqa
|
from .ec2 import mock_ec2, mock_ec2_deprecated # flake8: noqa
|
||||||
|
from .ecr import mock_ecr, mock_ecr_deprecated # flake8: noqa
|
||||||
from .ecs import mock_ecs, mock_ecs_deprecated # flake8: noqa
|
from .ecs import mock_ecs, mock_ecs_deprecated # flake8: noqa
|
||||||
from .elb import mock_elb, mock_elb_deprecated # flake8: noqa
|
from .elb import mock_elb, mock_elb_deprecated # flake8: noqa
|
||||||
from .emr import mock_emr, mock_emr_deprecated # flake8: noqa
|
from .emr import mock_emr, mock_emr_deprecated # flake8: noqa
|
||||||
|
@ -10,6 +10,7 @@ from moto.datapipeline import datapipeline_backends
|
|||||||
from moto.dynamodb import dynamodb_backends
|
from moto.dynamodb import dynamodb_backends
|
||||||
from moto.dynamodb2 import dynamodb_backends2
|
from moto.dynamodb2 import dynamodb_backends2
|
||||||
from moto.ec2 import ec2_backends
|
from moto.ec2 import ec2_backends
|
||||||
|
from moto.ecr import ecr_backends
|
||||||
from moto.ecs import ecs_backends
|
from moto.ecs import ecs_backends
|
||||||
from moto.elb import elb_backends
|
from moto.elb import elb_backends
|
||||||
from moto.emr import emr_backends
|
from moto.emr import emr_backends
|
||||||
@ -39,6 +40,7 @@ BACKENDS = {
|
|||||||
'dynamodb': dynamodb_backends,
|
'dynamodb': dynamodb_backends,
|
||||||
'dynamodb2': dynamodb_backends2,
|
'dynamodb2': dynamodb_backends2,
|
||||||
'ec2': ec2_backends,
|
'ec2': ec2_backends,
|
||||||
|
'ecr': ecr_backends,
|
||||||
'ecs': ecs_backends,
|
'ecs': ecs_backends,
|
||||||
'elb': elb_backends,
|
'elb': elb_backends,
|
||||||
'events': events_backends,
|
'events': events_backends,
|
||||||
|
7
moto/ecr/__init__.py
Normal file
7
moto/ecr/__init__.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from .models import ecr_backends
|
||||||
|
from ..core.models import base_decorator, deprecated_base_decorator
|
||||||
|
|
||||||
|
ecr_backend = ecr_backends['us-east-1']
|
||||||
|
mock_ecr = base_decorator(ecr_backends)
|
||||||
|
mock_ecr_deprecated = deprecated_base_decorator(ecr_backends)
|
221
moto/ecr/models.py
Normal file
221
moto/ecr/models.py
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
# from datetime import datetime
|
||||||
|
from random import random
|
||||||
|
|
||||||
|
from moto.core import BaseBackend, BaseModel
|
||||||
|
from moto.ec2 import ec2_backends
|
||||||
|
from copy import copy
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
|
class BaseObject(BaseModel):
|
||||||
|
|
||||||
|
def camelCase(self, key):
|
||||||
|
words = []
|
||||||
|
for i, word in enumerate(key.split('_')):
|
||||||
|
if i > 0:
|
||||||
|
words.append(word.title())
|
||||||
|
else:
|
||||||
|
words.append(word)
|
||||||
|
return ''.join(words)
|
||||||
|
|
||||||
|
def gen_response_object(self):
|
||||||
|
response_object = copy(self.__dict__)
|
||||||
|
for key, value in response_object.items():
|
||||||
|
if '_' in key:
|
||||||
|
response_object[self.camelCase(key)] = value
|
||||||
|
del response_object[key]
|
||||||
|
return response_object
|
||||||
|
|
||||||
|
@property
|
||||||
|
def response_object(self):
|
||||||
|
return self.gen_response_object()
|
||||||
|
|
||||||
|
|
||||||
|
class Repository(BaseObject):
|
||||||
|
|
||||||
|
def __init__(self, repository_name):
|
||||||
|
self.arn = 'arn:aws:ecr:us-east-1:012345678910:repository/{0}'.format(
|
||||||
|
repository_name)
|
||||||
|
self.name = repository_name
|
||||||
|
# self.created = datetime.utcnow()
|
||||||
|
self.uri = '012345678910.dkr.ecr.us-east-1.amazonaws.com/{0}'.format(
|
||||||
|
repository_name
|
||||||
|
)
|
||||||
|
self.registry_id = '012345678910'
|
||||||
|
self.images = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def physical_resource_id(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def response_object(self):
|
||||||
|
response_object = self.gen_response_object()
|
||||||
|
|
||||||
|
response_object['registryId'] = self.registry_id
|
||||||
|
response_object['repositoryArn'] = self.arn
|
||||||
|
response_object['repositoryName'] = self.name
|
||||||
|
response_object['repositoryUri'] = self.uri
|
||||||
|
# response_object['createdAt'] = self.created
|
||||||
|
del response_object['arn'], response_object['name']
|
||||||
|
return response_object
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||||
|
properties = cloudformation_json['Properties']
|
||||||
|
|
||||||
|
ecr_backend = ecr_backends[region_name]
|
||||||
|
return ecr_backend.create_repository(
|
||||||
|
# RepositoryName is optional in CloudFormation, thus create a random
|
||||||
|
# name if necessary
|
||||||
|
repository_name=properties.get(
|
||||||
|
'RepositoryName', 'ecrrepository{0}'.format(int(random() * 10 ** 6))),
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):
|
||||||
|
properties = cloudformation_json['Properties']
|
||||||
|
|
||||||
|
if original_resource.name != properties['RepositoryName']:
|
||||||
|
ecr_backend = ecr_backends[region_name]
|
||||||
|
ecr_backend.delete_cluster(original_resource.arn)
|
||||||
|
return ecr_backend.create_repository(
|
||||||
|
# RepositoryName is optional in CloudFormation, thus create a
|
||||||
|
# random name if necessary
|
||||||
|
repository_name=properties.get(
|
||||||
|
'RepositoryName', 'RepositoryName{0}'.format(int(random() * 10 ** 6))),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# no-op when nothing changed between old and new resources
|
||||||
|
return original_resource
|
||||||
|
|
||||||
|
|
||||||
|
class Image(BaseObject):
|
||||||
|
|
||||||
|
def __init__(self, tag, manifest, repository, registry_id="012345678910"):
|
||||||
|
self.image_tag = tag
|
||||||
|
self.image_manifest = manifest
|
||||||
|
self.image_size_in_bytes = 50 * 1024 * 1024
|
||||||
|
self.repository = repository
|
||||||
|
self.registry_id = registry_id
|
||||||
|
self.image_digest = None
|
||||||
|
self.image_pushed_at = None
|
||||||
|
|
||||||
|
def _create_digest(self):
|
||||||
|
image_contents = 'docker_image{0}'.format(int(random() * 10 ** 6))
|
||||||
|
self.image_digest = "sha256:%s" % hashlib.sha256(image_contents.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
def get_image_digest(self):
|
||||||
|
if not self.image_digest:
|
||||||
|
self._create_digest()
|
||||||
|
return self.image_digest
|
||||||
|
|
||||||
|
@property
|
||||||
|
def response_object(self):
|
||||||
|
response_object = self.gen_response_object()
|
||||||
|
response_object['imageId'] = {}
|
||||||
|
response_object['imageId']['imageTag'] = self.image_tag
|
||||||
|
response_object['imageId']['imageDigest'] = self.get_image_digest()
|
||||||
|
response_object['imageManifest'] = self.image_manifest
|
||||||
|
response_object['repositoryName'] = self.repository
|
||||||
|
response_object['registryId'] = self.registry_id
|
||||||
|
return response_object
|
||||||
|
|
||||||
|
@property
|
||||||
|
def response_list_object(self):
|
||||||
|
response_object = self.gen_response_object()
|
||||||
|
response_object['imageTag'] = self.image_tag
|
||||||
|
response_object['imageDigest'] = "i don't know"
|
||||||
|
return response_object
|
||||||
|
|
||||||
|
@property
|
||||||
|
def response_describe_object(self):
|
||||||
|
response_object = self.gen_response_object()
|
||||||
|
response_object['imageTags'] = [self.image_tag]
|
||||||
|
response_object['imageDigest'] = self.get_image_digest()
|
||||||
|
response_object['imageManifest'] = self.image_manifest
|
||||||
|
response_object['repositoryName'] = self.repository
|
||||||
|
response_object['registryId'] = self.registry_id
|
||||||
|
response_object['imageSizeInBytes'] = self.image_size_in_bytes
|
||||||
|
response_object['imagePushedAt'] = '2017-05-09'
|
||||||
|
return response_object
|
||||||
|
|
||||||
|
|
||||||
|
class ECRBackend(BaseBackend):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.repositories = {}
|
||||||
|
|
||||||
|
def describe_repositories(self, registry_id=None, repository_names=None):
|
||||||
|
"""
|
||||||
|
maxResults and nextToken not implemented
|
||||||
|
"""
|
||||||
|
repositories = []
|
||||||
|
for repository in self.repositories.values():
|
||||||
|
# If a registry_id was supplied, ensure this repository matches
|
||||||
|
if registry_id:
|
||||||
|
if repository.registry_id != registry_id:
|
||||||
|
continue
|
||||||
|
# If a list of repository names was supplied, esure this repository
|
||||||
|
# is in that list
|
||||||
|
if repository_names:
|
||||||
|
if repository.name not in repository_names:
|
||||||
|
continue
|
||||||
|
repositories.append(repository.response_object)
|
||||||
|
return repositories
|
||||||
|
|
||||||
|
def create_repository(self, repository_name):
|
||||||
|
repository = Repository(repository_name)
|
||||||
|
self.repositories[repository_name] = repository
|
||||||
|
return repository
|
||||||
|
|
||||||
|
def delete_repository(self, respository_name, registry_id=None):
|
||||||
|
if respository_name in self.repositories:
|
||||||
|
return self.repositories.pop(respository_name)
|
||||||
|
else:
|
||||||
|
raise Exception("{0} is not a repository".format(respository_name))
|
||||||
|
|
||||||
|
def list_images(self, repository_name, registry_id=None):
|
||||||
|
"""
|
||||||
|
maxResults and filtering not implemented
|
||||||
|
"""
|
||||||
|
images = []
|
||||||
|
for repository in self.repositories.values():
|
||||||
|
if repository_name:
|
||||||
|
if repository.name != repository_name:
|
||||||
|
continue
|
||||||
|
if registry_id:
|
||||||
|
if repository.registry_id != registry_id:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for image in repository.images:
|
||||||
|
images.append(image)
|
||||||
|
return images
|
||||||
|
|
||||||
|
def describe_images(self, repository_name, registry_id=None, image_id=None):
|
||||||
|
|
||||||
|
if repository_name in self.repositories:
|
||||||
|
repository = self.repositories[repository_name]
|
||||||
|
else:
|
||||||
|
raise Exception("{0} is not a repository".format(repository_name))
|
||||||
|
|
||||||
|
response = []
|
||||||
|
for image in repository.images:
|
||||||
|
response.append(image)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def put_image(self, repository_name, image_manifest, image_tag):
|
||||||
|
if repository_name in self.repositories:
|
||||||
|
repository = self.repositories[repository_name]
|
||||||
|
else:
|
||||||
|
raise Exception("{0} is not a repository".format(repository_name))
|
||||||
|
|
||||||
|
image = Image(image_tag, image_manifest, repository_name)
|
||||||
|
repository.images.append(image)
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
ecr_backends = {}
|
||||||
|
for region, ec2_backend in ec2_backends.items():
|
||||||
|
ecr_backends[region] = ECRBackend()
|
150
moto/ecr/responses.py
Normal file
150
moto/ecr/responses.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import json
|
||||||
|
|
||||||
|
from moto.core.responses import BaseResponse
|
||||||
|
from .models import ecr_backends
|
||||||
|
|
||||||
|
|
||||||
|
class ECRResponse(BaseResponse):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ecr_backend(self):
|
||||||
|
return ecr_backends[self.region]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def request_params(self):
|
||||||
|
try:
|
||||||
|
return json.loads(self.body)
|
||||||
|
except ValueError:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def _get_param(self, param):
|
||||||
|
return self.request_params.get(param, None)
|
||||||
|
|
||||||
|
def create_repository(self):
|
||||||
|
repository_name = self._get_param('repositoryName')
|
||||||
|
if repository_name is None:
|
||||||
|
repository_name = 'default'
|
||||||
|
repository = self.ecr_backend.create_repository(repository_name)
|
||||||
|
return json.dumps({
|
||||||
|
'repository': repository.response_object
|
||||||
|
})
|
||||||
|
|
||||||
|
def describe_repositories(self):
|
||||||
|
describe_repositories_name = self._get_param('repositoryNames')
|
||||||
|
registry_id = self._get_param('registryId')
|
||||||
|
|
||||||
|
repositories = self.ecr_backend.describe_repositories(
|
||||||
|
repository_names=describe_repositories_name, registry_id=registry_id)
|
||||||
|
return json.dumps({
|
||||||
|
'repositories': repositories,
|
||||||
|
'failures': []
|
||||||
|
})
|
||||||
|
|
||||||
|
def delete_repository(self):
|
||||||
|
repository_str = self._get_param('repositoryName')
|
||||||
|
repository = self.ecr_backend.delete_repository(repository_str)
|
||||||
|
return json.dumps({
|
||||||
|
'repository': repository.response_object
|
||||||
|
})
|
||||||
|
|
||||||
|
def put_image(self):
|
||||||
|
repository_str = self._get_param('repositoryName')
|
||||||
|
image_manifest = self._get_param('imageManifest')
|
||||||
|
image_tag = self._get_param('imageTag')
|
||||||
|
image = self.ecr_backend.put_image(repository_str, image_manifest, image_tag)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
'image': image.response_object
|
||||||
|
})
|
||||||
|
|
||||||
|
def list_images(self):
|
||||||
|
repository_str = self._get_param('repositoryName')
|
||||||
|
registry_id = self._get_param('registryId')
|
||||||
|
images = self.ecr_backend.list_images(repository_str, registry_id)
|
||||||
|
return json.dumps({
|
||||||
|
'imageIds': [image.response_list_object for image in images],
|
||||||
|
})
|
||||||
|
|
||||||
|
def describe_images(self):
|
||||||
|
repository_str = self._get_param('repositoryName')
|
||||||
|
registry_id = self._get_param('registryId')
|
||||||
|
images = self.ecr_backend.describe_images(repository_str, registry_id)
|
||||||
|
return json.dumps({
|
||||||
|
'imageDetails': [image.response_describe_object for image in images],
|
||||||
|
})
|
||||||
|
|
||||||
|
def batch_check_layer_availability(self):
|
||||||
|
if self.is_not_dryrun('BatchCheckLayerAvailability'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.batch_check_layer_availability is not yet implemented')
|
||||||
|
|
||||||
|
def batch_delete_image(self):
|
||||||
|
if self.is_not_dryrun('BatchDeleteImage'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.batch_delete_image is not yet implemented')
|
||||||
|
|
||||||
|
def batch_get_image(self):
|
||||||
|
if self.is_not_dryrun('BatchGetImage'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.batch_get_image is not yet implemented')
|
||||||
|
|
||||||
|
def can_paginate(self):
|
||||||
|
if self.is_not_dryrun('CanPaginate'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.can_paginate is not yet implemented')
|
||||||
|
|
||||||
|
def complete_layer_upload(self):
|
||||||
|
if self.is_not_dryrun('CompleteLayerUpload'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.complete_layer_upload is not yet implemented')
|
||||||
|
|
||||||
|
def delete_repository_policy(self):
|
||||||
|
if self.is_not_dryrun('DeleteRepositoryPolicy'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.delete_repository_policy is not yet implemented')
|
||||||
|
|
||||||
|
def generate_presigned_url(self):
|
||||||
|
if self.is_not_dryrun('GeneratePresignedUrl'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.generate_presigned_url is not yet implemented')
|
||||||
|
|
||||||
|
def get_authorization_token(self):
|
||||||
|
if self.is_not_dryrun('GetAuthorizationToken'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.get_authorization_token is not yet implemented')
|
||||||
|
|
||||||
|
def get_download_url_for_layer(self):
|
||||||
|
if self.is_not_dryrun('GetDownloadUrlForLayer'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.get_download_url_for_layer is not yet implemented')
|
||||||
|
|
||||||
|
def get_paginator(self):
|
||||||
|
if self.is_not_dryrun('GetPaginator'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.get_paginator is not yet implemented')
|
||||||
|
|
||||||
|
def get_repository_policy(self):
|
||||||
|
if self.is_not_dryrun('GetRepositoryPolicy'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.get_repository_policy is not yet implemented')
|
||||||
|
|
||||||
|
def get_waiter(self):
|
||||||
|
if self.is_not_dryrun('GetWaiter'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.get_waiter is not yet implemented')
|
||||||
|
|
||||||
|
def initiate_layer_upload(self):
|
||||||
|
if self.is_not_dryrun('InitiateLayerUpload'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.initiate_layer_upload is not yet implemented')
|
||||||
|
|
||||||
|
def set_repository_policy(self):
|
||||||
|
if self.is_not_dryrun('SetRepositoryPolicy'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.set_repository_policy is not yet implemented')
|
||||||
|
|
||||||
|
def upload_layer_part(self):
|
||||||
|
if self.is_not_dryrun('UploadLayerPart'):
|
||||||
|
raise NotImplementedError(
|
||||||
|
'ECR.upload_layer_part is not yet implemented')
|
10
moto/ecr/urls.py
Normal file
10
moto/ecr/urls.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from .responses import ECRResponse
|
||||||
|
|
||||||
|
url_bases = [
|
||||||
|
"https?://ecr.(.+).amazonaws.com",
|
||||||
|
]
|
||||||
|
|
||||||
|
url_paths = {
|
||||||
|
'{0}/$': ECRResponse.dispatch,
|
||||||
|
}
|
315
tests/test_ecr/test_ecr_boto3.py
Normal file
315
tests/test_ecr/test_ecr_boto3.py
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
from random import random
|
||||||
|
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
|
||||||
|
from moto import mock_ecr
|
||||||
|
|
||||||
|
|
||||||
|
def _create_image_digest(contents=None):
|
||||||
|
if not contents:
|
||||||
|
contents = 'docker_image{0}'.format(int(random() * 10 ** 6))
|
||||||
|
return "sha256:%s" % hashlib.sha256(contents.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _create_image_manifest():
|
||||||
|
return {
|
||||||
|
"schemaVersion": 2,
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||||
|
"config":
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.container.image.v1+json",
|
||||||
|
"size": 7023,
|
||||||
|
"digest": _create_image_digest("config")
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"size": 32654,
|
||||||
|
"digest": _create_image_digest("layer1")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"size": 16724,
|
||||||
|
"digest": _create_image_digest("layer2")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"size": 73109,
|
||||||
|
"digest": _create_image_digest("layer3")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_create_repository():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
response = client.create_repository(
|
||||||
|
repositoryName='test_ecr_repository'
|
||||||
|
)
|
||||||
|
response['repository']['repositoryName'].should.equal('test_ecr_repository')
|
||||||
|
response['repository']['repositoryArn'].should.equal(
|
||||||
|
'arn:aws:ecr:us-east-1:012345678910:repository/test_ecr_repository')
|
||||||
|
response['repository']['registryId'].should.equal('012345678910')
|
||||||
|
response['repository']['repositoryUri'].should.equal(
|
||||||
|
'012345678910.dkr.ecr.us-east-1.amazonaws.com/test_ecr_repository')
|
||||||
|
# response['repository']['createdAt'].should.equal(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_describe_repositories():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository1'
|
||||||
|
)
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository0'
|
||||||
|
)
|
||||||
|
response = client.describe_repositories()
|
||||||
|
len(response['repositories']).should.equal(2)
|
||||||
|
|
||||||
|
respository_arns = ['arn:aws:ecr:us-east-1:012345678910:repository/test_repository1',
|
||||||
|
'arn:aws:ecr:us-east-1:012345678910:repository/test_repository0']
|
||||||
|
set([response['repositories'][0]['repositoryArn'],
|
||||||
|
response['repositories'][1]['repositoryArn']]).should.equal(set(respository_arns))
|
||||||
|
|
||||||
|
respository_uris = ['012345678910.dkr.ecr.us-east-1.amazonaws.com/test_repository1',
|
||||||
|
'012345678910.dkr.ecr.us-east-1.amazonaws.com/test_repository0']
|
||||||
|
set([response['repositories'][0]['repositoryUri'],
|
||||||
|
response['repositories'][1]['repositoryUri']]).should.equal(set(respository_uris))
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_describe_repositories_1():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository1'
|
||||||
|
)
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository0'
|
||||||
|
)
|
||||||
|
response = client.describe_repositories(registryId='012345678910')
|
||||||
|
len(response['repositories']).should.equal(2)
|
||||||
|
|
||||||
|
respository_arns = ['arn:aws:ecr:us-east-1:012345678910:repository/test_repository1',
|
||||||
|
'arn:aws:ecr:us-east-1:012345678910:repository/test_repository0']
|
||||||
|
set([response['repositories'][0]['repositoryArn'],
|
||||||
|
response['repositories'][1]['repositoryArn']]).should.equal(set(respository_arns))
|
||||||
|
|
||||||
|
respository_uris = ['012345678910.dkr.ecr.us-east-1.amazonaws.com/test_repository1',
|
||||||
|
'012345678910.dkr.ecr.us-east-1.amazonaws.com/test_repository0']
|
||||||
|
set([response['repositories'][0]['repositoryUri'],
|
||||||
|
response['repositories'][1]['repositoryUri']]).should.equal(set(respository_uris))
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_describe_repositories_2():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository1'
|
||||||
|
)
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository0'
|
||||||
|
)
|
||||||
|
response = client.describe_repositories(registryId='109876543210')
|
||||||
|
len(response['repositories']).should.equal(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_describe_repositories_3():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository1'
|
||||||
|
)
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository0'
|
||||||
|
)
|
||||||
|
response = client.describe_repositories(repositoryNames=['test_repository1'])
|
||||||
|
len(response['repositories']).should.equal(1)
|
||||||
|
respository_arn = 'arn:aws:ecr:us-east-1:012345678910:repository/test_repository1'
|
||||||
|
response['repositories'][0]['repositoryArn'].should.equal(respository_arn)
|
||||||
|
|
||||||
|
respository_uri = '012345678910.dkr.ecr.us-east-1.amazonaws.com/test_repository1'
|
||||||
|
response['repositories'][0]['repositoryUri'].should.equal(respository_uri)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_describe_repositories_4():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository1'
|
||||||
|
)
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository0'
|
||||||
|
)
|
||||||
|
response = client.describe_repositories(repositoryNames=['not_a_valid_name'])
|
||||||
|
len(response['repositories']).should.equal(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_delete_repository():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository'
|
||||||
|
)
|
||||||
|
response = client.delete_repository(repositoryName='test_repository')
|
||||||
|
response['repository']['repositoryName'].should.equal('test_repository')
|
||||||
|
response['repository']['repositoryArn'].should.equal(
|
||||||
|
'arn:aws:ecr:us-east-1:012345678910:repository/test_repository')
|
||||||
|
response['repository']['registryId'].should.equal('012345678910')
|
||||||
|
response['repository']['repositoryUri'].should.equal(
|
||||||
|
'012345678910.dkr.ecr.us-east-1.amazonaws.com/test_repository')
|
||||||
|
# response['repository']['createdAt'].should.equal(0)
|
||||||
|
|
||||||
|
response = client.describe_repositories()
|
||||||
|
len(response['repositories']).should.equal(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_put_image():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository'
|
||||||
|
)
|
||||||
|
response = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='latest'
|
||||||
|
)
|
||||||
|
|
||||||
|
response['image']['repositoryName'].should.equal('test_repository')
|
||||||
|
response['image']['imageId']['imageTag'].should.equal('latest')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_list_images():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository_1'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository_2'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository_1',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='latest'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository_1',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='v1'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository_1',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='v2'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository_2',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='oldest'
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.list_images(repositoryName='test_repository_1')
|
||||||
|
type(response['imageIds']).should.be(list)
|
||||||
|
len(response['imageIds']).should.be(3)
|
||||||
|
|
||||||
|
image_tags = ['latest', 'v1', 'v2']
|
||||||
|
set([response['imageIds'][0]['imageTag'],
|
||||||
|
response['imageIds'][1]['imageTag'],
|
||||||
|
response['imageIds'][2]['imageTag']]).should.equal(set(image_tags))
|
||||||
|
|
||||||
|
response = client.list_images(repositoryName='test_repository_2')
|
||||||
|
type(response['imageIds']).should.be(list)
|
||||||
|
len(response['imageIds']).should.be(1)
|
||||||
|
response['imageIds'][0]['imageTag'].should.equal('oldest')
|
||||||
|
|
||||||
|
response = client.list_images(repositoryName='test_repository_2', registryId='109876543210')
|
||||||
|
type(response['imageIds']).should.be(list)
|
||||||
|
len(response['imageIds']).should.be(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_describe_images():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='latest'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='v1'
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='v2'
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_images(repositoryName='test_repository')
|
||||||
|
type(response['imageDetails']).should.be(list)
|
||||||
|
len(response['imageDetails']).should.be(3)
|
||||||
|
|
||||||
|
response['imageDetails'][0]['imageDigest'].should.contain("sha")
|
||||||
|
response['imageDetails'][1]['imageDigest'].should.contain("sha")
|
||||||
|
response['imageDetails'][2]['imageDigest'].should.contain("sha")
|
||||||
|
|
||||||
|
response['imageDetails'][0]['registryId'].should.equal("012345678910")
|
||||||
|
response['imageDetails'][1]['registryId'].should.equal("012345678910")
|
||||||
|
response['imageDetails'][2]['registryId'].should.equal("012345678910")
|
||||||
|
|
||||||
|
response['imageDetails'][0]['repositoryName'].should.equal("test_repository")
|
||||||
|
response['imageDetails'][1]['repositoryName'].should.equal("test_repository")
|
||||||
|
response['imageDetails'][2]['repositoryName'].should.equal("test_repository")
|
||||||
|
|
||||||
|
len(response['imageDetails'][0]['imageTags']).should.be(1)
|
||||||
|
len(response['imageDetails'][1]['imageTags']).should.be(1)
|
||||||
|
len(response['imageDetails'][2]['imageTags']).should.be(1)
|
||||||
|
|
||||||
|
image_tags = ['latest', 'v1', 'v2']
|
||||||
|
set([response['imageDetails'][0]['imageTags'][0],
|
||||||
|
response['imageDetails'][1]['imageTags'][0],
|
||||||
|
response['imageDetails'][2]['imageTags'][0]]).should.equal(set(image_tags))
|
||||||
|
|
||||||
|
response['imageDetails'][0]['imageSizeInBytes'].should.equal(52428800)
|
||||||
|
response['imageDetails'][1]['imageSizeInBytes'].should.equal(52428800)
|
||||||
|
response['imageDetails'][2]['imageSizeInBytes'].should.equal(52428800)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_put_image():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository'
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
|
imageTag='latest'
|
||||||
|
)
|
||||||
|
|
||||||
|
response['image']['imageId']['imageTag'].should.equal('latest')
|
||||||
|
response['image']['imageId']['imageDigest'].should.contain("sha")
|
||||||
|
response['image']['repositoryName'].should.equal('test_repository')
|
||||||
|
response['image']['registryId'].should.equal('012345678910')
|
Loading…
Reference in New Issue
Block a user