mirror of
https://github.com/d9pouces/id_configurator.git
synced 2026-11-09 01:47:21 +01:00
feat: enhance Docker image tagging and add publication functionality
Signed-off-by: d9pouces <github@19pouces.net>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
import typer
|
||||
|
||||
from id_tools.config import SourceConfig
|
||||
|
||||
app = typer.Typer(
|
||||
help="Publish the documentation and release announcements to external destinations."
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@app.command(name="sign-docker", help="Signe l'image Docker sur le registre")
|
||||
def sign_docker_image(
|
||||
registry: str = typer.Option(
|
||||
"interdiode", help="Registre cible pour l'image Docker"
|
||||
),
|
||||
docker_login: str = typer.Option(
|
||||
"", envvar="DOCKER_HUB_LOGIN", help="Nom d'utilisateur Docker"
|
||||
),
|
||||
docker_token: str = typer.Option(
|
||||
"", envvar="DOCKER_HUB_TOKEN", help="Jeton d'accès Docker"
|
||||
),
|
||||
cosign_password: str = typer.Option(
|
||||
"", envvar="COSIGN_PASSWORD", help="Mot de passe de la clé privée Cosign"
|
||||
),
|
||||
cosign_private_key: str = typer.Option(
|
||||
"", envvar="COSIGN_PRIVATE_KEY", help="Contenu de la clé privée Cosign"
|
||||
),
|
||||
):
|
||||
config = SourceConfig()
|
||||
version = config.get_project_version()
|
||||
image = config.get_project_name()
|
||||
v_tag = f"{image}:{version}"
|
||||
l_tag = f"{image}:latest"
|
||||
destinations = [f"{registry}/{v_tag}", f"{registry}/{l_tag}"]
|
||||
if docker_login and docker_token:
|
||||
cmd = ["docker", "login", "-u", docker_login, "--password-stdin"]
|
||||
subprocess.run(
|
||||
cmd, input=docker_token, text=True, check=True, cwd=config.source_dir
|
||||
)
|
||||
digest_references = {
|
||||
get_reference_from_tag(destination) for destination in destinations
|
||||
}
|
||||
if cosign_password and cosign_private_key:
|
||||
with (
|
||||
tempfile.NamedTemporaryFile(mode="w", suffix=".key", delete=True) as key_fd,
|
||||
tempfile.TemporaryDirectory() as tmp_dir,
|
||||
):
|
||||
key_fd.write(cosign_private_key)
|
||||
key_fd.flush()
|
||||
cosign_env = {**os.environ, "COSIGN_PASSWORD": cosign_password}
|
||||
trivy_report = os.path.join(tmp_dir, "trivy_report.json")
|
||||
for digest_reference in digest_references:
|
||||
# noinspection SpellCheckingInspection
|
||||
cmd = [
|
||||
"trivy",
|
||||
"image",
|
||||
"--format",
|
||||
"json",
|
||||
"--output",
|
||||
trivy_report,
|
||||
digest_reference,
|
||||
]
|
||||
subprocess.run(cmd, text=True, check=True, cwd=config.source_dir)
|
||||
cmd = [
|
||||
"cosign",
|
||||
"attest",
|
||||
"--key",
|
||||
key_fd.name,
|
||||
"--type",
|
||||
"vuln",
|
||||
"--predicate",
|
||||
trivy_report,
|
||||
digest_reference,
|
||||
]
|
||||
subprocess.run(cmd, text=True, check=True, cwd=config.source_dir)
|
||||
cmd = [
|
||||
"cosign",
|
||||
"sign",
|
||||
"--yes",
|
||||
"--recursive",
|
||||
"--key",
|
||||
key_fd.name,
|
||||
digest_reference,
|
||||
]
|
||||
subprocess.check_call(cmd, env=cosign_env)
|
||||
cmd = [
|
||||
"cosign",
|
||||
"verify-attestation",
|
||||
"--key",
|
||||
config.cosign_key_url,
|
||||
"--type",
|
||||
"vuln",
|
||||
digest_reference,
|
||||
]
|
||||
subprocess.check_call(cmd, env=cosign_env)
|
||||
cmd = [
|
||||
"cosign",
|
||||
"verify",
|
||||
"--key",
|
||||
config.cosign_key_url,
|
||||
digest_reference,
|
||||
]
|
||||
subprocess.check_call(cmd, env=cosign_env)
|
||||
typer.echo(f"✓ Image signée : {registry}/{v_tag} et {registry}/{l_tag}")
|
||||
|
||||
|
||||
def get_reference_from_tag(destination: str) -> str:
|
||||
# noinspection SpellCheckingInspection
|
||||
cmd = [
|
||||
"docker",
|
||||
"buildx",
|
||||
"imagetools",
|
||||
"inspect",
|
||||
destination,
|
||||
"--format",
|
||||
"{{json .Manifest}}",
|
||||
]
|
||||
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
||||
manifest = json.loads(result.stdout)
|
||||
image_name = destination.rsplit(":", 1)[0]
|
||||
reference = f"{image_name}@{manifest['digest']}"
|
||||
return reference
|
||||
Reference in New Issue
Block a user