11from functools import cached_property
2- from typing import Any
2+ from typing import Any , Self
33
4- from pydantic import Field , SecretStr , field_validator
4+ from pydantic import (
5+ AnyHttpUrl ,
6+ Field ,
7+ SecretStr ,
8+ TypeAdapter ,
9+ field_validator ,
10+ model_validator ,
11+ )
512from pydantic_settings import SettingsConfigDict
613
714from .base import BaseCustomSettings
@@ -12,31 +19,49 @@ class RegistrySettings(BaseCustomSettings):
1219 REGISTRY_PATH : str | None = Field (
1320 default = None ,
1421 # This is useful in case of a local registry, where the registry url (path) is relative to the host docker engine"
15- description = "development mode only, in case a local registry is used" ,
22+ description = "development mode only, in case a local registry is used - "
23+ "this is the hostname to the docker registry as seen from the host running the containers (e.g. 127.0.0.1:5000)" ,
1624 )
1725 # NOTE: name is missleading, http or https protocol are not included
18- REGISTRY_URL : str = Field (default = "" , description = "address to the docker registry" )
26+ REGISTRY_URL : str = Field (
27+ ...,
28+ description = "hostname of docker registry (without protocol but with port if available)" ,
29+ min_length = 1 ,
30+ )
1931
2032 REGISTRY_USER : str = Field (
2133 ..., description = "username to access the docker registry"
2234 )
2335 REGISTRY_PW : SecretStr = Field (
2436 ..., description = "password to access the docker registry"
2537 )
26- REGISTRY_SSL : bool = Field (..., description = "access to registry through ssl" )
38+ REGISTRY_SSL : bool = Field (
39+ ..., description = "True if docker registry is using HTTPS protocol"
40+ )
2741
2842 @field_validator ("REGISTRY_PATH" , mode = "before" )
2943 @classmethod
3044 def _escape_none_string (cls , v ) -> Any | None :
3145 return None if v == "None" else v
3246
47+ @model_validator (mode = "after" )
48+ def check_registry_authentication (self : Self ) -> Self :
49+ if self .REGISTRY_AUTH and any (
50+ not v for v in (self .REGISTRY_USER , self .REGISTRY_PW )
51+ ):
52+ msg = "If REGISTRY_AUTH is True, both REGISTRY_USER and REGISTRY_PW must be provided"
53+ raise ValueError (msg )
54+ return self
55+
3356 @cached_property
3457 def resolved_registry_url (self ) -> str :
3558 return self .REGISTRY_PATH or self .REGISTRY_URL
3659
3760 @cached_property
38- def api_url (self ) -> str :
39- return f"{ self .REGISTRY_URL } /v2"
61+ def api_url (self ) -> AnyHttpUrl :
62+ return TypeAdapter (AnyHttpUrl ).validate_python (
63+ f"http{ 's' if self .REGISTRY_SSL else '' } ://{ self .REGISTRY_URL } /v2"
64+ )
4065
4166 model_config = SettingsConfigDict (
4267 json_schema_extra = {
0 commit comments