From a2bac7dabdb512316a68cf95a82b9374c0935d9b Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Wed, 22 Mar 2017 14:30:33 -0400 Subject: [PATCH] endpoints.v1: only work on docker repositories --- data/interfaces/v1.py | 5 +++-- data/model/repository.py | 5 +++++ endpoints/v1/index.py | 10 ++++++++++ endpoints/v1/registry.py | 35 +++++++++++++++++++++++++++++++++++ endpoints/v1/tag.py | 20 ++++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/data/interfaces/v1.py b/data/interfaces/v1.py index cfcbd25ca..c6ba7502e 100644 --- a/data/interfaces/v1.py +++ b/data/interfaces/v1.py @@ -10,7 +10,7 @@ from util.morecollections import AttrDict class Repository(namedtuple('Repository', ['id', 'name', 'namespace_name', 'description', - 'is_public'])): + 'is_public', 'kind'])): """ Repository represents a namespaced collection of tags. """ @@ -396,7 +396,8 @@ def _repository_for_repo(repo): name=repo.name, namespace_name=repo.namespace_user.username, description=repo.description, - is_public=model.repository.is_repository_public(repo) + is_public=model.repository.is_repository_public(repo), + kind=model.repository.get_repo_kind_name(repo), ) diff --git a/data/model/repository.py b/data/model/repository.py index 984519f1d..765d60c9d 100644 --- a/data/model/repository.py +++ b/data/model/repository.py @@ -18,6 +18,11 @@ from util.itertoolrecipes import take logger = logging.getLogger(__name__) + +def get_repo_kind_name(repo): + return Repository.kind.get_name(repo.kind) + + def get_repository_count(): return Repository.select().count() diff --git a/endpoints/v1/index.py b/endpoints/v1/index.py index 028379554..4eef43116 100644 --- a/endpoints/v1/index.py +++ b/endpoints/v1/index.py @@ -182,6 +182,10 @@ def create_repository(namespace_name, repo_name): message='You do not have permission to modify repository %(namespace)s/%(repository)s', issue='no-repo-write-permission', namespace=namespace_name, repository=repo_name) + elif repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) + else: create_perm = CreateRepositoryPermission(namespace_name) if not create_perm.can(): @@ -223,6 +227,9 @@ def update_images(namespace_name, repo_name): if not repo: # Make sure the repo actually exists. abort(404, message='Unknown repository', issue='unknown-repo') + elif repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) # Generate a job for each notification that has been added to this repo logger.debug('Adding notifications for repository') @@ -255,6 +262,9 @@ def get_repository_images(namespace_name, repo_name): repo = model.get_repository(namespace_name, repo_name) if not repo: abort(404, message='Unknown repository', issue='unknown-repo') + elif repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) logger.debug('Building repository image response') resp = make_response(json.dumps([]), 200) diff --git a/endpoints/v1/registry.py b/endpoints/v1/registry.py index f0bcc11b8..32eef2a12 100644 --- a/endpoints/v1/registry.py +++ b/endpoints/v1/registry.py @@ -83,6 +83,11 @@ def head_image_layer(namespace, repository, image_id, headers): logger.debug('Checking repo permissions') if permission.can() or model.repository_is_public(namespace, repository): + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + logger.debug('Looking up placement locations') locations, _ = model.placement_locations_and_path_docker_v1(namespace, repository, image_id) if locations is None: @@ -116,6 +121,11 @@ def get_image_layer(namespace, repository, image_id, headers): logger.debug('Checking repo permissions') if permission.can() or model.repository_is_public(namespace, repository): + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + logger.debug('Looking up placement locations and path') locations, path = model.placement_locations_and_path_docker_v1(namespace, repository, image_id) if not locations or not path: @@ -151,6 +161,11 @@ def put_image_layer(namespace, repository, image_id): if not permission.can(): abort(403) + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + logger.debug('Retrieving image') if model.storage_exists(namespace, repository, image_id): exact_abort(409, 'Image already exists') @@ -255,6 +270,11 @@ def put_image_checksum(namespace, repository, image_id): if not permission.can(): abort(403) + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + # Docker Version < 0.10 (tarsum+sha): old_checksum = request.headers.get('X-Docker-Checksum') @@ -324,6 +344,11 @@ def get_image_json(namespace, repository, image_id, headers): if not permission.can() and not model.repository_is_public(namespace, repository): abort(403) + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + logger.debug('Looking up repo image') v1_metadata = model.docker_v1_metadata(namespace, repository, image_id) if v1_metadata is None: @@ -353,6 +378,11 @@ def get_image_ancestry(namespace, repository, image_id, headers): if not permission.can() and not model.repository_is_public(namespace, repository): abort(403) + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + ancestry_docker_ids = model.image_ancestry(namespace, repository, image_id) if ancestry_docker_ids is None: abort(404, 'Image %(image_id)s not found', issue='unknown-image', image_id=image_id) @@ -373,6 +403,11 @@ def put_image_json(namespace, repository, image_id): if not permission.can(): abort(403) + repo = model.get_repository(namespace, repository) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, image_id=image_id) + logger.debug('Parsing image JSON') try: uploaded_metadata = request.data diff --git a/endpoints/v1/tag.py b/endpoints/v1/tag.py index 917cc6a6f..de5b0eed6 100644 --- a/endpoints/v1/tag.py +++ b/endpoints/v1/tag.py @@ -27,6 +27,11 @@ def get_tags(namespace_name, repo_name): permission = ReadRepositoryPermission(namespace_name, repo_name) if permission.can() or model.repository_is_public(namespace_name, repo_name): + repo = model.get_repository(namespace_name, repo_name) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) + tags = model.list_tags(namespace_name, repo_name) tag_map = {tag.name: tag.image.docker_image_id for tag in tags} return jsonify(tag_map) @@ -42,6 +47,11 @@ def get_tag(namespace_name, repo_name, tag): permission = ReadRepositoryPermission(namespace_name, repo_name) if permission.can() or model.repository_is_public(namespace_name, repo_name): + repo = model.get_repository(namespace_name, repo_name) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) + image_id = model.find_image_id_by_tag(namespace_name, repo_name, tag) if image_id is None: abort(404) @@ -64,6 +74,11 @@ def put_tag(namespace_name, repo_name, tag): if not TAG_REGEX.match(tag): abort(400, TAG_ERROR) + repo = model.get_repository(namespace_name, repo_name) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) + image_id = json.loads(request.data) model.create_or_update_tag(namespace_name, repo_name, image_id, tag) @@ -86,6 +101,11 @@ def delete_tag(namespace_name, repo_name, tag): permission = ModifyRepositoryPermission(namespace_name, repo_name) if permission.can(): + repo = model.get_repository(namespace_name, repo_name) + if repo.kind != 'image': + msg = 'This repository is for a managing resource type other than docker images.' + abort(415, message=msg, namespace=namespace_name) + model.delete_tag(namespace_name, repo_name, tag) track_and_log('delete_tag', model.get_repository(namespace_name, repo_name), tag=tag) return make_response('Deleted', 200)