Beispiel #1
0
def fetch_manifest_by_tagname(namespace_name, repo_name, manifest_ref, registry_model):
    try:
        repository_ref = registry_model.lookup_repository(
            namespace_name, repo_name, raise_on_error=True, manifest_ref=manifest_ref
        )
    except RepositoryDoesNotExist as e:
        image_pulls.labels("v2", "tag", 404).inc()
        raise NameUnknown("repository not found")

    try:
        tag = registry_model.get_repo_tag(repository_ref, manifest_ref, raise_on_error=True)
    except TagDoesNotExist as e:
        if registry_model.has_expired_tag(repository_ref, manifest_ref):
            logger.debug(
                "Found expired tag %s for repository %s/%s", manifest_ref, namespace_name, repo_name
            )
            msg = (
                "Tag %s was deleted or has expired. To pull, revive via time machine" % manifest_ref
            )
            image_pulls.labels("v2", "tag", 404).inc()
            raise TagExpired(msg)

        image_pulls.labels("v2", "tag", 404).inc()
        raise ManifestUnknown(str(e))

    manifest = registry_model.get_manifest_for_tag(tag)
    if manifest is None:
        # Something went wrong.
        image_pulls.labels("v2", "tag", 400).inc()
        raise ManifestInvalid()

    try:
        manifest_bytes, manifest_digest, manifest_media_type = _rewrite_schema_if_necessary(
            namespace_name, repo_name, manifest_ref, manifest, registry_model
        )
    except (ManifestException, ManifestDoesNotExist) as e:
        image_pulls.labels("v2", "tag", 404).inc()
        raise ManifestUnknown(str(e))

    if manifest_bytes is None:
        image_pulls.labels("v2", "tag", 404).inc()
        raise ManifestUnknown()

    track_and_log(
        "pull_repo",
        repository_ref,
        analytics_name="pull_repo_100x",
        analytics_sample=0.01,
        tag=manifest_ref,
    )
    image_pulls.labels("v2", "tag", 200).inc()

    return Response(
        manifest_bytes.as_unicode(),
        status=200,
        headers={
            "Content-Type": manifest_media_type,
            "Docker-Content-Digest": manifest_digest,
        },
    )
Beispiel #2
0
    def test_get_layer(self):
        """
        Test for basic retrieval of layers from the security scanner.
        """

        repo_ref = registry_model.lookup_repository(ADMIN_ACCESS_USER,
                                                    SIMPLE_REPO)
        repo_tag = registry_model.get_repo_tag(repo_ref, "latest")
        manifest = registry_model.get_manifest_for_tag(repo_tag)
        registry_model.populate_legacy_images_for_testing(manifest, storage)

        with fake_security_scanner() as security_scanner:
            # Ensure the layer doesn't exist yet.
            self.assertFalse(
                security_scanner.has_layer(
                    security_scanner.layer_id(manifest)))
            self.assertIsNone(self.api.get_layer_data(manifest))

            # Add the layer.
            security_scanner.add_layer(security_scanner.layer_id(manifest))

            # Retrieve the results.
            result = self.api.get_layer_data(manifest,
                                             include_vulnerabilities=True)
            self.assertIsNotNone(result)
            self.assertEquals(result["Layer"]["Name"],
                              security_scanner.layer_id(manifest))
def test_load_security_information(secscan_model):
    repository = registry_model.lookup_repository("devtable", "complex")
    for tag in registry_model.list_all_active_repository_tags(repository):
        manifest = registry_model.get_manifest_for_tag(tag)
        assert manifest
        assert (secscan_model.load_security_information(
            manifest, True).status == ScanLookupStatus.NOT_YET_INDEXED)
Beispiel #4
0
def test_load_security_information_api_returns_none(initialized_db,
                                                    set_secscan_config):
    repository_ref = registry_model.lookup_repository("devtable", "simple")
    tag = registry_model.get_repo_tag(repository_ref,
                                      "latest",
                                      include_legacy_image=True)
    manifest = registry_model.get_manifest_for_tag(tag,
                                                   backfill_if_necessary=True)

    ManifestSecurityStatus.create(
        manifest=manifest._db_id,
        repository=repository_ref._db_id,
        error_json={},
        index_status=IndexStatus.COMPLETED,
        indexer_hash="abc",
        indexer_version=IndexerVersion.V4,
        metadata_json={},
    )

    secscan = V4SecurityScanner(app, instance_keys, storage)
    secscan._secscan_api = mock.Mock()
    secscan._secscan_api.vulnerability_report.return_value = None

    assert secscan.load_security_information(
        manifest).status == ScanLookupStatus.NOT_YET_INDEXED
Beispiel #5
0
def test_load_security_information_api_request_failure(initialized_db,
                                                       set_secscan_config):
    repository_ref = registry_model.lookup_repository("devtable", "simple")
    tag = registry_model.get_repo_tag(repository_ref,
                                      "latest",
                                      include_legacy_image=True)
    manifest = registry_model.get_manifest_for_tag(tag,
                                                   backfill_if_necessary=True)

    mss = ManifestSecurityStatus.create(
        manifest=manifest._db_id,
        repository=repository_ref._db_id,
        error_json={},
        index_status=IndexStatus.COMPLETED,
        indexer_hash="abc",
        indexer_version=IndexerVersion.V4,
        metadata_json={},
    )

    secscan = V4SecurityScanner(app, instance_keys, storage)
    secscan._secscan_api = mock.Mock()
    secscan._secscan_api.vulnerability_report.side_effect = APIRequestFailure()

    assert secscan.load_security_information(
        manifest).status == ScanLookupStatus.COULD_NOT_LOAD
    assert not ManifestSecurityStatus.select().where(
        ManifestSecurityStatus.id == mss.id).exists()
def test_load_security_information_api_responses(secscan_api_response,
                                                 initialized_db):
    repository_ref = registry_model.lookup_repository("devtable", "simple")
    tag = registry_model.get_repo_tag(repository_ref,
                                      "latest",
                                      include_legacy_image=True)
    manifest = registry_model.get_manifest_for_tag(tag,
                                                   backfill_if_necessary=True,
                                                   include_legacy_image=True)
    set_secscan_status(Image.get(id=manifest.legacy_image._db_id), True, 3)

    secscan = V2SecurityScanner(app, instance_keys, storage)
    secscan._legacy_secscan_api = mock.Mock()
    secscan._legacy_secscan_api.get_layer_data.return_value = secscan_api_response

    security_information = secscan.load_security_information(
        manifest).security_information

    assert isinstance(security_information, SecurityInformation)
    assert security_information.Layer.Name == secscan_api_response[
        "Layer"].get("Name", "")
    assert security_information.Layer.ParentName == secscan_api_response[
        "Layer"].get("ParentName", "")
    assert security_information.Layer.IndexedByVersion == secscan_api_response[
        "Layer"].get("IndexedByVersion", None)
    assert len(security_information.Layer.Features) == len(
        secscan_api_response["Layer"].get("Features", []))
Beispiel #7
0
def test_get_security_info_with_pull_secret(endpoint, client):
    repository_ref = registry_model.lookup_repository("devtable", "simple")
    tag = registry_model.get_repo_tag(repository_ref,
                                      "latest",
                                      include_legacy_image=True)
    manifest = registry_model.get_manifest_for_tag(tag,
                                                   backfill_if_necessary=True)

    params = {
        "repository": "devtable/simple",
        "imageid": tag.legacy_image.docker_image_id,
        "manifestref": manifest.digest,
    }

    headers = {
        "Authorization": "Basic %s" % base64.b64encode("devtable:password"),
    }

    conduct_api_call(client,
                     endpoint,
                     "GET",
                     params,
                     None,
                     headers=headers,
                     expected_code=200)
Beispiel #8
0
def manifest_for(namespace, repository, tagname):
    repository_ref = registry_model.lookup_repository(namespace, repository)
    tag = registry_model.get_repo_tag(repository_ref,
                                      tagname,
                                      include_legacy_image=True)

    return registry_model.get_manifest_for_tag(tag, backfill_if_necessary=True)
Beispiel #9
0
def test_get_security_info_with_pull_secret(endpoint, anonymous_allowed,
                                            auth_headers, expected_code,
                                            client):
    with patch("features.ANONYMOUS_ACCESS", anonymous_allowed):
        repository_ref = registry_model.lookup_repository("devtable", "simple")
        tag = registry_model.get_repo_tag(repository_ref, "latest")
        manifest = registry_model.get_manifest_for_tag(tag)

        params = {
            "repository": "devtable/simple",
            "imageid": tag.manifest.legacy_image_root_id,
            "manifestref": manifest.digest,
        }

        headers = {}
        if auth_headers is not None:
            headers["Authorization"] = auth_headers

        conduct_api_call(client,
                         endpoint,
                         "GET",
                         params,
                         None,
                         headers=headers,
                         expected_code=expected_code)
Beispiel #10
0
def test_deprecated_route(client):
    repository_ref = registry_model.lookup_repository("devtable", "simple")
    tag = registry_model.get_repo_tag(repository_ref, "latest")
    manifest = registry_model.get_manifest_for_tag(tag)

    with client_with_identity("devtable", client) as cl:
        resp = conduct_api_call(
            cl,
            RepositoryImageSecurity,
            "get",
            {"repository": "devtable/simple", "imageid": manifest.legacy_image_root_id},
            expected_code=200,
        )

        assert resp.headers["Deprecation"] == "true"
Beispiel #11
0
def test_deprecated_route(client):
    repository_ref = registry_model.lookup_repository("devtable", "simple")
    tag = registry_model.get_repo_tag(repository_ref, "latest", include_legacy_image=True)
    manifest = registry_model.get_manifest_for_tag(tag, backfill_if_necessary=True)
    image = shared.get_legacy_image_for_manifest(manifest._db_id)

    with client_with_identity("devtable", client) as cl:
        resp = conduct_api_call(
            cl,
            RepositoryImageSecurity,
            "get",
            {"repository": "devtable/simple", "imageid": image.docker_image_id},
            expected_code=200,
        )

        assert resp.headers["Deprecation"] == "true"
Beispiel #12
0
    def verify_replication_for(namespace, repo_name, tag_name):
        repo_ref = registry_model.lookup_repository(namespace, repo_name)
        assert repo_ref

        tag = registry_model.get_repo_tag(repo_ref, tag_name)
        assert tag

        manifest = registry_model.get_manifest_for_tag(tag)
        assert manifest

        for layer in registry_model.list_manifest_layers(manifest, storage):
            if layer.blob.digest != EMPTY_LAYER_BLOB_DIGEST:
                QueueItem.select().where(
                    QueueItem.queue_name**("%" + layer.blob.uuid + "%")).get()

        return "OK"
Beispiel #13
0
    def get(self, namespace, repository, tag, parsed_args):
        """
        List the images for the specified repository tag.
        """
        repo_ref = registry_model.lookup_repository(namespace, repository)
        if repo_ref is None:
            raise NotFound()

        tag_ref = registry_model.get_repo_tag(repo_ref, tag)
        if tag_ref is None:
            raise NotFound()

        if parsed_args["owned"]:
            # NOTE: This is deprecated, so we just return empty now.
            return {"images": []}

        manifest = registry_model.get_manifest_for_tag(tag_ref)
        if manifest is None:
            raise NotFound()

        legacy_image = registry_model.get_legacy_image(
            repo_ref, manifest.legacy_image_root_id, storage
        )
        if legacy_image is None:
            raise NotFound()

        # NOTE: This is replicating our older response for this endpoint, but
        # returns empty for the metadata fields. This is to ensure back-compat
        # for callers still using the deprecated API, while not having to load
        # all the manifests from storage.
        return {
            "images": [
                {
                    "id": image_id,
                    "created": format_date(datetime.utcfromtimestamp(tag_ref.lifetime_start_ts)),
                    "comment": "",
                    "command": "",
                    "size": 0,
                    "uploading": False,
                    "sort_index": 0,
                    "ancestors": "",
                }
                for image_id in legacy_image.full_image_id_chain
            ]
        }