3
3
"""
4
4
Load module library into database via the API
5
5
"""
6
+ import base64
6
7
import json
7
8
import re
8
9
from base64 import b64encode
12
13
13
14
import requests
14
15
import typer
15
- from requests .auth import HTTPBasicAuth
16
16
from rich import print
17
17
18
18
19
19
class SyncLibrary :
20
- DOCKER_PREFIX = "automation-module-"
20
+ DOCKER_REGISTRY = "ghcr.io"
21
+ DOCKER_NAMESPACE = "sekoia-io"
22
+ DOCKER_PREFIX = "automation-module"
21
23
22
24
def __init__ (
23
25
self ,
24
26
playbook_url : str ,
25
27
api_key : str ,
26
28
modules_path : Path ,
27
- registry_pat : str | None = None ,
28
- registry_user : str | None = None ,
29
29
module : str = "" ,
30
30
registry_check : bool = False ,
31
+ registry : str | None = None ,
32
+ namespace : str | None = None ,
33
+ registry_pat : str | None = None ,
31
34
):
32
- self .registry_pat = registry_pat
33
- self .registry_user = registry_user
34
35
self .playbook_url = playbook_url
35
36
self .api_key = api_key
36
37
self .headers = {
@@ -39,7 +40,12 @@ def __init__(
39
40
}
40
41
self .modules_path = modules_path
41
42
self .module = module
43
+
42
44
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"
43
49
44
50
def pprint (
45
51
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:
263
269
with path_to_use .open ("rb" ) as f :
264
270
return f"{ prefix } { b64encode (f .read ()).decode ('utf-8' )} "
265
271
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 :
269
273
"""Checks if a Docker image exists on a registry
270
274
271
275
If no registry is specified in the Module's manifest, we use a default value
272
276
If the docker image name in the Module's manifest begins with a registry,
273
277
this custom registry is used for the verification instead
274
278
An image is considered to contain the registry path if it contains at least 2 /
275
279
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
277
281
278
282
Args:
279
283
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
281
285
282
286
Returns:
283
287
bool: True if the image exists on the registry or if we don't have access
284
288
to a registry
285
289
False otherwise
286
290
"""
287
- assert self .registry_user and self .registry_pat
288
- auth = HTTPBasicAuth (self .registry_user , self .registry_pat )
289
-
290
291
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 ]
293
294
image_name = match [3 ]
294
295
else :
295
- registry_path = "ghcr.io"
296
- registry_pathinfo = "v2/sekoialab"
296
+ registry = self . registry
297
+ namespace = self . namespace
297
298
image_name = docker_image
298
299
300
+ token = base64 .b64encode (self .registry_pat .encode ()).decode ()
299
301
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 } " ,
320
303
headers = {
321
304
"Authorization" : f"Bearer { token } " ,
322
305
"Accept" : "application/vnd.docker.distribution.manifest.v2+json" ,
@@ -404,12 +387,6 @@ def execute(self):
404
387
Otherwise, it will attempt to load all modules present in the library path
405
388
specified
406
389
"""
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
-
413
390
if not self .module :
414
391
library_path = self .modules_path .absolute ()
415
392
print ("Library path: " , library_path )
@@ -425,5 +402,5 @@ def _get_module_docker_name(self, manifest: dict) -> str:
425
402
if docker := manifest .get ("docker" ):
426
403
return docker
427
404
if slug := manifest .get ("slug" ):
428
- return f"{ self .DOCKER_PREFIX } { slug } "
405
+ return f"{ self .registry } / { self . namespace } / { self . DOCKER_PREFIX } - { slug } "
429
406
raise ValueError ("Impossible to generate image name" )
0 commit comments