Пример #1
0
def test_remove_tag_signatures_non_existent_tag(
    mock_quay_client,
    mock_get_signatures,
    mock_remove_signatures,
    manifest_list_data,
):
    mock_get_repository_tags = mock.MagicMock()
    mock_get_repository_tags.return_value = {
        "name": "external-repo/other-image",
        "tags": ["1", "2", "3", "4"],
    }
    mock_quay_client.return_value.get_repository_tags = mock_get_repository_tags
    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.return_value = manifest_list_data
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    sig_remover.remove_tag_signatures(
        "quay.io/internal-namespace/external-repo----external-image:5",
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )

    mock_get_repository_tags.assert_called_once_with(
        "internal-namespace/external-repo----external-image")
    mock_get_manifest.assert_not_called()
    mock_get_signatures.assert_not_called()
    mock_remove_signatures.assert_not_called()
Пример #2
0
def test_init():
    sig_remover = signature_remover.SignatureRemover()

    assert sig_remover.quay_host == "quay.io"
    assert sig_remover.quay_user is None
    assert sig_remover.quay_password is None
    assert sig_remover._quay_client is None
Пример #3
0
def test_remove_repository_signatures_none_to_remove(
    mock_quay_client,
    mock_get_repo_digests,
    mock_get_signatures,
    mock_remove_signatures,
):
    mock_get_repo_digests.return_value = ["digest1", "digest2"]
    mock_get_signatures.return_value = [
        {
            "repository": "namespace/different-repo",
            "_id": "id3"
        },
    ]

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    sig_remover.remove_repository_signatures("namespace/repo",
                                             "internal-namespace",
                                             "pyxis-server.com",
                                             "some-principal", "some-keytab")

    mock_get_repo_digests.assert_called_once_with(
        "internal-namespace/namespace----repo")
    mock_get_signatures.assert_called_once_with(["digest1", "digest2"],
                                                "pyxis-server.com",
                                                "some-principal",
                                                "some-keytab")
    mock_remove_signatures.assert_not_called()
Пример #4
0
def test_get_index_image_signatures_server_error(mock_quay_client,
                                                 mock_get_signatures,
                                                 manifest_list_data):
    response = mock.MagicMock()
    response.status_code = 500

    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.side_effect = requests.exceptions.HTTPError(
        "server error", response=response)
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******",
        quay_password="******",
        quay_api_token="some-token")

    with pytest.raises(requests.exceptions.HTTPError, match="server error"):
        sig_remover.get_index_image_signatures(
            "quay.io/internal-namespace/index-repo----index-image:1",
            [],
            "pyxis-server.com",
            "some-principal",
            "some-keytab",
        )

    mock_get_manifest.assert_called_once_with(
        "quay.io/internal-namespace/index-repo----index-image:1",
        media_type=mock_quay_client.MANIFEST_LIST_TYPE,
    )
    mock_get_signatures.assert_not_called()
Пример #5
0
def test_remove_tag_signatures_no_signatures(
    mock_quay_client,
    mock_get_signatures,
    mock_remove_signatures,
    manifest_list_data,
):
    mock_get_repository_tags = mock.MagicMock()
    mock_get_repository_tags.return_value = {
        "name": "external-repo/other-image",
        "tags": ["1", "2", "3", "4"],
    }
    mock_quay_client.return_value.get_repository_tags = mock_get_repository_tags
    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.return_value = manifest_list_data
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    mock_get_signatures.return_value = [
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:2",
            "_id":
            "id1",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:3",
            "_id":
            "id2",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
        {
            "repository":
            "external-repo/other-image",
            "reference":
            "redhat.com/external-repo/other-image:1",
            "_id":
            "id3",
            "manifest_digest":
            "sha256:2e8f38a0a8d2a450598430fa70c7f0b53aeec991e76c3e29c63add599b4ef7ee",
        },
    ]

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    sig_remover.remove_tag_signatures(
        "quay.io/internal-namespace/external-repo----external-image:1",
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )

    mock_remove_signatures.assert_not_called()
Пример #6
0
def test_set_quay_client():
    mock_quay_client = mock.MagicMock()
    sig_remover = signature_remover.SignatureRemover()

    assert sig_remover._quay_client is None
    sig_remover.set_quay_client(mock_quay_client)
    assert sig_remover._quay_client == mock_quay_client
    assert sig_remover.quay_client == mock_quay_client
Пример #7
0
def test_get_signatures_from_pyxis(mock_run_entrypoint, mock_tempfile,
                                   mock_json_dump):
    expected_data1 = [{"some": "data"}, {"other": "data"}]
    expected_data2 = [{"some-other": "data"}]
    mock_run_entrypoint.side_effect = [
        iter(expected_data1), iter(expected_data2)
    ]

    temp_filename = "/tmp/pubtools_quay_get_signatures_ABC123"
    mock_tempfile.return_value.__enter__.return_value.name = temp_filename

    sig_remover = signature_remover.SignatureRemover()
    sig_remover.MAX_MANIFEST_DIGESTS_PER_SEARCH_REQUEST = 2
    sig_data = sig_remover.get_signatures_from_pyxis(
        ["digest1", "digest2", "digest3", "digest3"],
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )

    for i, data in enumerate(sig_data):
        assert data == (expected_data1 + expected_data2)[i]

    assert mock_run_entrypoint.call_count == 2
    assert mock_run_entrypoint.mock_calls[0] == mock.call(
        ("pubtools-pyxis", "console_scripts", "pubtools-pyxis-get-signatures"),
        "pubtools-pyxis-get-signatures",
        [
            "--pyxis-server",
            "pyxis-server.com",
            "--pyxis-ssl-crtfile",
            "some-principal",
            "--pyxis-ssl-keyfile",
            "some-keytab",
            "--manifest-digest",
            "@/tmp/pubtools_quay_get_signatures_ABC123",
        ],
        {},
    )
    assert mock_run_entrypoint.mock_calls[1] == mock.call(
        ("pubtools-pyxis", "console_scripts", "pubtools-pyxis-get-signatures"),
        "pubtools-pyxis-get-signatures",
        [
            "--pyxis-server",
            "pyxis-server.com",
            "--pyxis-ssl-crtfile",
            "some-principal",
            "--pyxis-ssl-keyfile",
            "some-keytab",
            "--manifest-digest",
            "@/tmp/pubtools_quay_get_signatures_ABC123",
        ],
        {},
    )

    assert mock_json_dump.call_count == 2
    assert mock_json_dump.mock_calls[0][1][0] == ["digest1", "digest2"]
    assert mock_json_dump.mock_calls[1][1][0] == ["digest3"]
Пример #8
0
def test_initialize_quay_client(mock_quay_client):
    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")

    assert sig_remover.quay_host == "quay.io"
    assert sig_remover.quay_user == "some-user"
    assert sig_remover.quay_password == "some-password"
    assert sig_remover._quay_client is None
    assert sig_remover.quay_client == mock_quay_client.return_value
    assert sig_remover._quay_client == mock_quay_client.return_value
Пример #9
0
def test_get_repository_digests(mock_quay_client, repo_api_data,
                                manifest_list_data, v2s2_manifest_data):
    mock_get_repository_tags = mock.MagicMock()
    mock_get_repository_tags.return_value = {
        "name": "namespace/repo",
        "tags": ["1", "2", "3", "4"]
    }
    mock_quay_client.return_value.get_repository_tags = mock_get_repository_tags
    mock_get_manifest_digest = mock.MagicMock()
    mock_get_manifest_digest.return_value = (
        "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb"
    )
    mock_quay_client.return_value.get_manifest_digest = mock_get_manifest_digest
    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.side_effect = [
        manifest_list_data,
        manifest_list_data,
        v2s2_manifest_data,
        v2s2_manifest_data,
    ]
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    digests = sig_remover.get_repository_digests("namespace/repo")

    mock_get_repository_tags.assert_called_once_with("namespace/repo")
    assert mock_get_manifest_digest.call_count == 2
    assert mock_get_manifest_digest.call_args_list[0] == mock.call(
        "quay.io/namespace/repo:3")
    assert mock_get_manifest_digest.call_args_list[1] == mock.call(
        "quay.io/namespace/repo:4")
    assert mock_get_manifest.call_count == 4
    assert mock_get_manifest.call_args_list[0] == mock.call(
        "quay.io/namespace/repo:1")
    assert mock_get_manifest.call_args_list[1] == mock.call(
        "quay.io/namespace/repo:2")
    assert mock_get_manifest.call_args_list[2] == mock.call(
        "quay.io/namespace/repo:3")
    assert mock_get_manifest.call_args_list[3] == mock.call(
        "quay.io/namespace/repo:4")

    assert digests == [
        "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        "sha256:2e8f38a0a8d2a450598430fa70c7f0b53aeec991e76c3e29c63add599b4ef7ee",
        "sha256:496fb0ff2057c79254c9dc6ba999608a98219c5c93142569a547277c679e532c",
        "sha256:b3f9218fb5839763e62e52ee6567fe331aa1f3c644f9b6f232ff23959257acf9",
        "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
    ]
Пример #10
0
def test_remove_tag_signatures_digest(
    mock_quay_client,
    mock_get_signatures,
    mock_remove_signatures,
    manifest_list_data,
):
    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    with pytest.raises(ValueError,
                       match=".*removed must be specified by tag."):
        sig_remover.remove_tag_signatures(
            "quay.io/some-namespace/some-repo@sha256:a1a1a1",
            "pyxis-server.com",
            "some-principal",
            "some-keytab",
        )

    mock_get_signatures.assert_not_called()
    mock_remove_signatures.assert_not_called()
Пример #11
0
def test_get_index_image_signatures_digest(mock_quay_client,
                                           mock_get_signatures,
                                           manifest_list_data):
    mock_get_manifest = mock.MagicMock()
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******",
        quay_password="******",
        quay_api_token="some-token")

    with pytest.raises(ValueError,
                       match="Please specify the index image via tag"):
        sig_remover.get_index_image_signatures(
            "quay.io/internal-namespace/index-repo----index-image@sha256:a1a1a1a1",
            [],
            "pyxis-server.com",
            "some-principal",
            "some-keytab",
        )

    mock_get_manifest.assert_not_called()
    mock_get_signatures.assert_not_called()
Пример #12
0
def test_remove_signatures_from_pyxis(mock_run_entrypoint, mock_temp_file):
    mock_temp_file.return_value.__enter__.return_value.name = "some-tmp-file"
    sig_remover = signature_remover.SignatureRemover()

    sig_remover.remove_signatures_from_pyxis(["id1", "id2", "id3"],
                                             "pyxis-server.com",
                                             "some-principal", "some-keytab")

    mock_run_entrypoint.assert_called_once_with(
        ("pubtools-pyxis", "console_scripts",
         "pubtools-pyxis-delete-signatures"),
        "pubtools-pyxis-delete-signatures",
        [
            "--pyxis-server",
            "pyxis-server.com",
            "--pyxis-ssl-crtfile",
            "some-principal",
            "--pyxis-ssl-keyfile",
            "some-keytab",
            "--ids",
            "@some-tmp-file",
        ],
        {},
    )
Пример #13
0
def test_get_index_image_signatures_claims(mock_quay_client,
                                           mock_get_signatures,
                                           manifest_list_data):
    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.return_value = manifest_list_data
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    mock_get_signatures.return_value = [
        {
            "repository":
            "index-repo/index-image",
            "reference":
            "redhat.com/index-repo/index-image:1",
            "_id":
            "id1",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
        {
            "repository":
            "index-repo/index-image",
            "reference":
            "redhat.com/index-repo/index-image:1",
            "_id":
            "id2",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
        {
            "repository": "index-repo/index-image",
            "reference": "redhat.com/index-repo/index-image:1",
            "_id": "id3",
            "manifest_digest": "sha256:dfgdfgdfg",
        },
        {
            "repository":
            "index-repo/index-image",
            "reference":
            "redhat.com/index-repo/index-image:2",
            "_id":
            "id4",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
        {
            "repository":
            "different-repo/index-image",
            "reference":
            "redhat.com/different-repo/index-image:1",
            "_id":
            "id5",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
        {
            "repository":
            "index-repo/index-image",
            "reference":
            "redhat.com/index-repo/index-image:1",
            "_id":
            "id6",
            "manifest_digest":
            "sha256:496fb0ff2057c79254c9dc6ba999608a98219c5c93142569a547277c679e532c",
        },
    ]

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******",
        quay_password="******",
        quay_api_token="some-token")

    claim_messages = [
        {
            "manifest_digest":
            "sha256:496fb0ff2057c79254c9dc6ba999608a98219c5c93142569a547277c679e532c",
            "repo": "index-repo/index-image",
            "docker_reference": "redhat.com/index-repo/index-image:1",
        },
        {
            "manifest_digest":
            "sha256:496fb0ff2057c79254c9dc6ba999608a98219c5c93142569a547277c679e532c",
            "repo": "index-repo/index-image",
            "docker_reference": "redhat.com/index-repo/index-image:2",
        },
    ]

    signatures = sig_remover.get_index_image_signatures(
        "quay.io/internal-namespace/index-repo----index-image:1",
        claim_messages,
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )

    mock_get_manifest.assert_called_once_with(
        "quay.io/internal-namespace/index-repo----index-image:1",
        media_type=mock_quay_client.MANIFEST_LIST_TYPE,
    )
    mock_get_signatures.assert_called_once_with(
        [
            "sha256:2e8f38a0a8d2a450598430fa70c7f0b53aeec991e76c3e29c63add599b4ef7ee",
            "sha256:b3f9218fb5839763e62e52ee6567fe331aa1f3c644f9b6f232ff23959257acf9",
            "sha256:496fb0ff2057c79254c9dc6ba999608a98219c5c93142569a547277c679e532c",
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        ],
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )
    assert signatures == [
        {
            "repository":
            "index-repo/index-image",
            "reference":
            "redhat.com/index-repo/index-image:1",
            "_id":
            "id1",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
        {
            "repository":
            "index-repo/index-image",
            "reference":
            "redhat.com/index-repo/index-image:1",
            "_id":
            "id2",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
    ]
Пример #14
0
def test_remove_tag_signatures_selected_archs(
    mock_quay_client,
    mock_get_signatures,
    mock_remove_signatures,
    repo_api_data,
    manifest_list_data,
):
    mock_get_repository_tags = mock.MagicMock()
    mock_get_repository_tags.return_value = {
        "name": "external-repo/other-image",
        "tags": ["1", "2", "3", "4"],
    }
    mock_quay_client.return_value.get_repository_tags = mock_get_repository_tags
    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.return_value = manifest_list_data
    mock_quay_client.return_value.get_manifest = mock_get_manifest

    mock_get_signatures.return_value = [
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:1",
            "_id":
            "id1",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:1",
            "_id":
            "id2",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
        {
            "repository":
            "external-repo/other-image",
            "reference":
            "redhat.com/external-repo/other-image:1",
            "_id":
            "id3",
            "manifest_digest":
            "sha256:2e8f38a0a8d2a450598430fa70c7f0b53aeec991e76c3e29c63add599b4ef7ee",
        },
    ]

    selected_archs = ["ppc64le", "arm64"]

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    sig_remover.remove_tag_signatures(
        "quay.io/internal-namespace/external-repo----external-image:1",
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
        remove_archs=selected_archs,
    )

    mock_get_repository_tags.assert_called_once_with(
        "internal-namespace/external-repo----external-image")
    mock_get_manifest.assert_called_once_with(
        "quay.io/internal-namespace/external-repo----external-image:1")
    mock_get_signatures.assert_called_once_with(
        [
            "sha256:b3f9218fb5839763e62e52ee6567fe331aa1f3c644f9b6f232ff23959257acf9",
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        ],
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )
    mock_remove_signatures.assert_called_once_with(["id1"], "pyxis-server.com",
                                                   "some-principal",
                                                   "some-keytab")
Пример #15
0
def test_remove_tag_signatures_source(
    mock_quay_client,
    mock_get_signatures,
    mock_remove_signatures,
    v2s2_manifest_data,
):
    mock_get_repository_tags = mock.MagicMock()
    mock_get_repository_tags.return_value = {
        "name": "external-repo/other-image",
        "tags": ["1", "2", "3", "4"],
    }
    mock_quay_client.return_value.get_repository_tags = mock_get_repository_tags
    mock_get_manifest = mock.MagicMock()
    mock_get_manifest.return_value = v2s2_manifest_data
    mock_quay_client.return_value.get_manifest = mock_get_manifest
    mock_get_manifest_digest = mock.MagicMock()
    mock_get_manifest_digest.return_value = (
        "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb"
    )
    mock_quay_client.return_value.get_manifest_digest = mock_get_manifest_digest

    mock_get_signatures.return_value = [
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:3",
            "_id":
            "id1",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:3",
            "_id":
            "id2",
            "manifest_digest":
            "sha256:bbef1f46572d1f33a92b53b0ba0ed5a1d09dab7ffe64be1ae3ae66e76275eabd",
        },
        {
            "repository":
            "external-repo/other-image",
            "reference":
            "redhat.com/external-repo/other-image:3",
            "_id":
            "id3",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
        {
            "repository":
            "external-repo/external-image",
            "reference":
            "redhat.com/external-repo/external-image:4",
            "_id":
            "id4",
            "manifest_digest":
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb",
        },
    ]

    sig_remover = signature_remover.SignatureRemover(
        quay_user="******", quay_password="******")
    sig_remover.remove_tag_signatures(
        "quay.io/internal-namespace/external-repo----external-image:3",
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )

    mock_get_repository_tags.assert_called_once_with(
        "internal-namespace/external-repo----external-image")
    mock_get_manifest.assert_called_once_with(
        "quay.io/internal-namespace/external-repo----external-image:3")
    mock_get_signatures.assert_called_once_with(
        [
            "sha256:146ab6fa7ba3ab4d154b09c1c5522e4966ecd071bf23d1ba3df6c8b9fc33f8cb"
        ],
        "pyxis-server.com",
        "some-principal",
        "some-keytab",
    )
    mock_remove_signatures.assert_called_once_with(["id1"], "pyxis-server.com",
                                                   "some-principal",
                                                   "some-keytab")
Пример #16
0
def test_quay_client_error():
    sig_remover = signature_remover.SignatureRemover()

    with pytest.raises(ValueError, match="No instance of QuayClient.*"):
        sig_remover.quay_client