33"""
44Load module library into database via the API
55"""
6+ import base64
67import json
78import re
89from base64 import b64encode
1213
1314import requests
1415import typer
15- from requests .auth import HTTPBasicAuth
1616from rich import print
1717
1818
1919class SyncLibrary :
20- DOCKER_PREFIX = "automation-module-"
20+ DOCKER_REGISTRY = "ghcr.io"
21+ DOCKER_NAMESPACE = "sekoia-io"
22+ DOCKER_PREFIX = "automation-module"
2123
2224 def __init__ (
2325 self ,
2426 playbook_url : str ,
2527 api_key : str ,
2628 modules_path : Path ,
27- registry_pat : str | None = None ,
28- registry_user : str | None = None ,
2929 module : str = "" ,
3030 registry_check : bool = False ,
31+ registry : str | None = None ,
32+ namespace : str | None = None ,
33+ registry_pat : str | None = None ,
3134 ):
32- self .registry_pat = registry_pat
33- self .registry_user = registry_user
3435 self .playbook_url = playbook_url
3536 self .api_key = api_key
3637 self .headers = {
@@ -39,7 +40,12 @@ def __init__(
3940 }
4041 self .modules_path = modules_path
4142 self .module = module
43+
4244 self .registry_check = registry_check
45+ self .registry = registry or self .DOCKER_REGISTRY
46+ self .namespace = namespace or self .DOCKER_NAMESPACE
47+ # In case of a public image any base64 encoded token works
48+ self .registry_pat = registry_pat or "none"
4349
4450 def pprint (
4551 self , created : list , updated : list , up_to_date : list , errors : list , nb_tabs : int
@@ -263,60 +269,37 @@ def get_module_logo(self, module_path: Path) -> str | None:
263269 with path_to_use .open ("rb" ) as f :
264270 return f"{ prefix } { b64encode (f .read ()).decode ('utf-8' )} "
265271
266- def check_image_on_registry (
267- self , docker_image : str , docker_image_version : str
268- ) -> bool :
272+ def check_image_on_registry (self , docker_image : str , version : str ) -> bool :
269273 """Checks if a Docker image exists on a registry
270274
271275 If no registry is specified in the Module's manifest, we use a default value
272276 If the docker image name in the Module's manifest begins with a registry,
273277 this custom registry is used for the verification instead
274278 An image is considered to contain the registry path if it contains at least 2 /
275279 They delimit the path and the pathinfo fields
276- e.g. my_registry.com/v2 /my_docker_image
280+ e.g. my_registry.com/sekoia-io /my_docker_image
277281
278282 Args:
279283 docker_image (str): Docker image name as specified in the manifest
280- docker_image_version (str): Docker image version
284+ version (str): Docker image version
281285
282286 Returns:
283287 bool: True if the image exists on the registry or if we don't have access
284288 to a registry
285289 False otherwise
286290 """
287- assert self .registry_user and self .registry_pat
288- auth = HTTPBasicAuth (self .registry_user , self .registry_pat )
289-
290291 if match := re .match (r"(.*?)/(.*)/(.*)" , docker_image ):
291- registry_path = match [1 ]
292- registry_pathinfo = match [2 ]
292+ registry = match [1 ]
293+ namespace = match [2 ]
293294 image_name = match [3 ]
294295 else :
295- registry_path = "ghcr.io"
296- registry_pathinfo = "v2/sekoialab"
296+ registry = self . registry
297+ namespace = self . namespace
297298 image_name = docker_image
298299
300+ token = base64 .b64encode (self .registry_pat .encode ()).decode ()
299301 response = requests .get (
300- f"https://{ registry_path } /token" ,
301- params = {
302- "service" : registry_path ,
303- "scope" : "repository:<repo>:pull" ,
304- "client_id" : "symphony-docker-image" ,
305- },
306- auth = auth ,
307- )
308- if not response .ok :
309- print (
310- f"[bold red][!] Authentication against the docker registry "
311- f"failed with status { response .status_code } "
312- )
313- raise typer .Exit (code = 1 )
314-
315- token = response .json ()["token" ]
316-
317- response = requests .get (
318- f"https://{ registry_path } /{ registry_pathinfo } /{ image_name } /manifests/\
319- { docker_image_version } " ,
302+ f"https://{ registry } /v2/{ namespace } /{ image_name } /manifests/{ version } " ,
320303 headers = {
321304 "Authorization" : f"Bearer { token } " ,
322305 "Accept" : "application/vnd.docker.distribution.manifest.v2+json" ,
@@ -404,12 +387,6 @@ def execute(self):
404387 Otherwise, it will attempt to load all modules present in the library path
405388 specified
406389 """
407- if self .registry_check and not (self .registry_pat and self .registry_user ):
408- print (
409- "[bold red][!] Credentials must be provided to check image in registry"
410- )
411- raise typer .Exit (code = 1 )
412-
413390 if not self .module :
414391 library_path = self .modules_path .absolute ()
415392 print ("Library path: " , library_path )
@@ -425,5 +402,5 @@ def _get_module_docker_name(self, manifest: dict) -> str:
425402 if docker := manifest .get ("docker" ):
426403 return docker
427404 if slug := manifest .get ("slug" ):
428- return f"{ self .DOCKER_PREFIX } { slug } "
405+ return f"{ self .registry } / { self . namespace } / { self . DOCKER_PREFIX } - { slug } "
429406 raise ValueError ("Impossible to generate image name" )
0 commit comments