Skip to content

Commit

Permalink
Added support for container identity for cosign
Browse files Browse the repository at this point in the history
Container identity is public facing registry + repository in public
format
  • Loading branch information
midnightercz committed Jun 26, 2024
1 parent be58349 commit 2180ae8
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 4 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ pubtools-iib
kerberos
marshmallow
urllib3<2
pubtools-sign>0.0.6
pubtools-sign>0.0.7
2 changes: 1 addition & 1 deletion src/pubtools/_quay/clear_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def clear_repositories(repositories: str, settings: Dict[str, Any]) -> None:
LOG.info("Clearing repositories '{0}'".format(repositories))
quay_client = QuayClient(settings["quay_user"], settings["quay_password"])
item_processor = item_processor_for_internal_data(
quay_client, "quay.io", 5, settings["quay_org"]
quay_client, "quay.io", [""], 5, settings["quay_org"]
)
item_processor.extractor.full_extract = True

Expand Down
7 changes: 7 additions & 0 deletions src/pubtools/_quay/iib_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ def _index_image_to_sign_entries(
reference
"""
iib_repo = target_settings["quay_operator_repository"]
pub_iib_repo = target_settings["quay_operator_repository"]
dest_registries = target_settings["docker_settings"]["docker_reference_registry"]
pub_registry = dest_registries[0]
dest_registries = dest_registries if isinstance(dest_registries, list) else [dest_registries]
if internal:
dest_registries = ["quay.io"]
Expand Down Expand Up @@ -130,6 +132,7 @@ def _index_image_to_sign_entries(
to_sign_entries.append(
SignEntry(
reference=f"{registry}/{iib_repo}:{_dest_tag}",
pub_reference=f"{pub_registry}/{pub_iib_repo}",
repo=iib_repo,
digest=headers["docker-content-digest"],
arch="amd64",
Expand All @@ -145,6 +148,7 @@ def _index_image_to_sign_entries(
to_sign_entries.append(
SignEntry(
reference=reference,
pub_reference=f"{pub_registry}/{pub_iib_repo}",
repo=iib_repo,
digest=digest,
arch="amd64",
Expand Down Expand Up @@ -267,6 +271,7 @@ def task_iib_add_bundles(
item_processor = item_processor_for_internal_data(
quay_client,
target_settings["quay_host"].rstrip("/"),
target_settings["docker_settings"]["docker_reference_registry"],
target_settings.get("retry_sleep_time", 5),
quay_operator_namespace,
)
Expand Down Expand Up @@ -401,6 +406,7 @@ def task_iib_remove_operators(
item_processor = item_processor_for_internal_data(
quay_client,
target_settings["quay_host"].rstrip("/"),
target_settings["docker_settings"]["docker_reference_registry"],
target_settings.get("retry_sleep_time", 5),
quay_operator_namespace,
)
Expand Down Expand Up @@ -530,6 +536,7 @@ def task_iib_build_from_scratch(
item_processor = item_processor_for_internal_data(
quay_client,
target_settings["quay_host"].rstrip("/"),
target_settings["docker_settings"]["docker_reference_registry"],
target_settings.get("retry_sleep_time", 5),
quay_operator_namespace,
)
Expand Down
13 changes: 12 additions & 1 deletion src/pubtools/_quay/item_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ class SignEntry:
signing_key (str): Signing key.
repo (str): Repo reference in format <registry>/<repo>
reference (str): Reference in format <registry>/<repo>:<tag>
pub_reference (str): Public repo reference in format <registry>/repo
digest (str): Digest of the manifest.
arch (str): Architecture of the manifest.
"""

repo: str
reference: str
pub_reference: str
digest: str
signing_key: str
arch: str
Expand Down Expand Up @@ -393,6 +395,7 @@ class ItemProcesor:
reference_processor: Union[ReferenceProcessorExternal, ReferenceProcessorInternal]
reference_registries: List[str]
source_registry: Optional[str]
public_registry: Optional[str]

INTERNAL_DELIMITER = "----"

Expand Down Expand Up @@ -505,6 +508,7 @@ def generate_to_sign(self, item: Any, include_manifest_lists: bool = False) -> L
SignEntry(
repo=repo,
reference=reference,
pub_reference=cast(str, self.public_registry) + "/" + repo,
digest=mad.digest,
arch=mad.arch,
signing_key=item.claims_signing_key,
Expand Down Expand Up @@ -700,17 +704,23 @@ def item_processor_for_external_data(
reference_processor=ReferenceProcessorExternal(),
reference_registries=external_registries,
source_registry=None,
public_registry=external_registries[0],
)


def item_processor_for_internal_data(
quay_client: QuayClient, internal_registry: str, retry_sleep_time: int, internal_namespace: str
quay_client: QuayClient,
internal_registry: str,
external_registries: List[str],
retry_sleep_time: int,
internal_namespace: str,
) -> ItemProcesor:
"""Get instance of item processor configured to produce internal data.
Args:
quay_client (QuayClient): Quay client.
internal_registry (str): Docker registry where containers are stored
external registries (str): List of external registries used for container identity.
retry_sleep_time (int): sleep time bewteen retries for fetching data from registry.
internal_namespace (str): Namespace of internal organization in the registry.
Returns:
Expand All @@ -723,4 +733,5 @@ def item_processor_for_internal_data(
reference_processor=reference_processor,
reference_registries=["quay.io"],
source_registry=internal_registry,
public_registry=external_registries[0],
)
7 changes: 7 additions & 0 deletions src/pubtools/_quay/push_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def generate_backup_mapping(
internal_item_processor = item_processor_for_internal_data(
self.dest_quay_client,
self.target_settings["quay_host"].rstrip("/"),
self.dest_registries,
self.target_settings.get("retry_sleep_time", 5),
self.target_settings["quay_namespace"],
)
Expand Down Expand Up @@ -503,6 +504,7 @@ def fetch_missing_push_items_digests(
item_processor = item_processor_for_internal_data(
self.dest_quay_client,
self.target_settings["quay_host"].rstrip("/"),
self.dest_registries,
self.target_settings.get("retry_sleep_time", 5),
self.target_settings["quay_namespace"],
)
Expand Down Expand Up @@ -557,10 +559,13 @@ def sign_new_manifests(self, docker_push_items: List[Any]) -> List[Tuple[str, st
+ ":"
+ tag
)
registry = self.dest_registries[0]
pub_reference = f"{registry}/{repo}"
# add entries in internal format for cosign
to_sign_entries_internal.append(
SignEntry(
reference=reference,
pub_reference=pub_reference,
repo=repo,
digest=digest,
signing_key=key,
Expand All @@ -572,6 +577,7 @@ def sign_new_manifests(self, docker_push_items: List[Any]) -> List[Tuple[str, st
to_sign_entries.append(
SignEntry(
reference=reference,
pub_reference="",
repo=repo,
digest=digest,
signing_key=key,
Expand Down Expand Up @@ -666,6 +672,7 @@ def run(self) -> None:
to_sign_entries = []
item_processor = item_processor_for_internal_data(
self.src_quay_client,
self.target_settings["quay_host"].rstrip("/"),
self.dest_registries,
self.target_settings.get("retry_sleep_time", 5),
self.target_settings["quay_namespace"],
Expand Down
2 changes: 1 addition & 1 deletion src/pubtools/_quay/remove_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def remove_repositories(repositories: str, settings: Dict[str, Any]) -> None:
quay_api_client = QuayApiClient(settings["quay_api_token"])
quay_client = QuayClient(settings["quay_user"], settings["quay_password"], "quay.io")
item_processor = item_processor_for_internal_data(
quay_client, "quay.io", 5, settings["quay_org"]
quay_client, "quay.io", [""], 5, settings["quay_org"]
)
item_processor.extractor.full_extract = True
# Remove repository doesn't work with push item by default, therefore we create VirtualPushItem
Expand Down
14 changes: 14 additions & 0 deletions src/pubtools/_quay/signer_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,20 @@ class CosignSignerWrapper(SignerWrapper):
# LOG.warning("Fetch existing signatures error:" + esig[1])
# return rets

def sign_container_opt_args(
self, sign_entry: SignEntry, task_id: Optional[str] = None
) -> Dict[str, Any]:
"""Return optional arguments for signing a container.
Args:
sign_entry (SignEntry): SignEntry to sign.
task_id (str): Task ID to identify the signing task if needed.
Returns:
dict: Optional arguments for signing a container.
"""
return {"identity": sign_entry.pub_reference}

def _filter_to_remove(
self,
signatures: List[Tuple[str, str, str]],
Expand Down
10 changes: 10 additions & 0 deletions src/pubtools/_quay/tag_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ def copy_tag_sign_images(self, push_item: Any, tag: str, executor: Executor) ->
to_sign_entries_internal.append(
SignEntry(
repo=repo,
pub_reference=registries[0] + "/" + list(push_item.repos.keys())[0],
reference="quay.io/"
+ self.target_settings["quay_namespace"]
+ "/"
Expand All @@ -566,6 +567,7 @@ def copy_tag_sign_images(self, push_item: Any, tag: str, executor: Executor) ->
to_sign_entries.append(
SignEntry(
repo=repo,
pub_reference="",
reference=reference,
digest=details.digest,
signing_key=push_item.claims_signing_key,
Expand All @@ -577,6 +579,7 @@ def copy_tag_sign_images(self, push_item: Any, tag: str, executor: Executor) ->
item_processor = item_processor_for_internal_data(
self.quay_client,
self.target_settings["quay_host"].rstrip("/"),
self.dest_registries[0],
self.target_settings.get("retry_sleep_time", 5),
self.target_settings["quay_namespace"],
)
Expand Down Expand Up @@ -666,9 +669,11 @@ def merge_manifest_lists_sign_images(
to_sign_entries_internal = []

for manifest in new_manifest_list["manifests"]:
registry = dest_registries[0]
to_sign_entries_internal.append(
SignEntry(
repo=list(push_item.repos.keys())[0],
pub_reference=registry + "/" + list(push_item.repos.keys())[0],
reference="quay.io/"
+ self.target_settings["quay_namespace"]
+ "/"
Expand All @@ -687,6 +692,7 @@ def merge_manifest_lists_sign_images(
to_sign_entries.append(
SignEntry(
repo=list(push_item.repos.keys())[0],
pub_reference="",
reference=reference,
digest=manifest["digest"],
arch=manifest["platform"]["architecture"],
Expand All @@ -701,6 +707,7 @@ def merge_manifest_lists_sign_images(
item_processor = item_processor_for_internal_data(
self.quay_client,
self.target_settings["quay_host"].rstrip("/"),
self.dest_registries[0],
self.target_settings.get("retry_sleep_time", 5),
self.target_settings["quay_namespace"],
)
Expand Down Expand Up @@ -751,9 +758,11 @@ def merge_manifest_lists_sign_images(

if push_item.claims_signing_key:
# for cosign sign also manifest list
pub_reference = "https://" + registry + "/" + list(push_item.repos.keys())[0]
to_sign_entries_internal.append(
SignEntry(
repo=list(push_item.repos.keys())[0],
pub_reference=pub_reference,
reference="quay.io/"
+ self.target_settings["quay_namespace"]
+ "/"
Expand Down Expand Up @@ -818,6 +827,7 @@ def untag_image(self, push_item: Any, tag: str) -> None:
item_processor = item_processor_for_internal_data(
self.quay_client,
self.target_settings["quay_host"].rstrip("/"),
self.dest_registries[0],
self.target_settings.get("retry_sleep_time", 5),
self.target_settings["quay_namespace"],
)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_iib_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ def test_task_iib_add_bundles(
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
],
identity="some-registry1.com/operators/index-image",
),
]
)
Expand Down Expand Up @@ -473,6 +474,7 @@ def test_task_iib_add_bundles_missing_manifest_list(
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
],
identity="some-registry1.com/operators/index-image",
),
]
)
Expand Down Expand Up @@ -637,6 +639,7 @@ def test_task_iib_add_bundles_operator_ns(
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
],
identity="some-registry1.com/operators/index-image",
),
]
)
Expand Down Expand Up @@ -1154,6 +1157,7 @@ def test_task_iib_build_from_scratch(
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
],
identity="some-registry1.com/operators/index-image",
),
]
)
Expand Down Expand Up @@ -1407,6 +1411,7 @@ def test_task_iib_build_from_scratch_missing_manifest_list(
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
],
identity="some-registry1.com/operators/index-image",
),
]
)
Expand Down Expand Up @@ -1544,6 +1549,7 @@ def test_task_iib_build_from_scratch_operator_ns(
],
task_id="1",
),
# cosign
mock.call(
config_file="test-config.yml",
signing_key="some-key",
Expand All @@ -1559,6 +1565,7 @@ def test_task_iib_build_from_scratch_operator_ns(
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
"sha256:bd6eba96070efe86b64b9a212680ca6d46a2e30f0a7d8e539f657eabc45c35a6",
],
identity="some-registry1.com/operators/index-image",
),
]
)
Expand Down
Loading

0 comments on commit 2180ae8

Please sign in to comment.