orchestrator-core 4.0.4__py3-none-any.whl → 4.1.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orchestrator/__init__.py +1 -1
- orchestrator/api/api_v1/endpoints/settings.py +12 -1
- orchestrator/services/settings_env_variables.py +68 -0
- orchestrator/settings.py +11 -2
- orchestrator/utils/expose_settings.py +45 -0
- {orchestrator_core-4.0.4.dist-info → orchestrator_core-4.1.0rc1.dist-info}/METADATA +1 -1
- {orchestrator_core-4.0.4.dist-info → orchestrator_core-4.1.0rc1.dist-info}/RECORD +9 -7
- {orchestrator_core-4.0.4.dist-info → orchestrator_core-4.1.0rc1.dist-info}/WHEEL +0 -0
- {orchestrator_core-4.0.4.dist-info → orchestrator_core-4.1.0rc1.dist-info}/licenses/LICENSE +0 -0
orchestrator/__init__.py
CHANGED
|
@@ -22,11 +22,17 @@ from sqlalchemy.exc import SQLAlchemyError
|
|
|
22
22
|
from oauth2_lib.fastapi import OIDCUserModel
|
|
23
23
|
from orchestrator.api.error_handling import raise_status
|
|
24
24
|
from orchestrator.db import EngineSettingsTable
|
|
25
|
-
from orchestrator.schemas import
|
|
25
|
+
from orchestrator.schemas import (
|
|
26
|
+
EngineSettingsBaseSchema,
|
|
27
|
+
EngineSettingsSchema,
|
|
28
|
+
WorkerStatus,
|
|
29
|
+
)
|
|
26
30
|
from orchestrator.security import authenticate
|
|
27
31
|
from orchestrator.services import processes, settings
|
|
28
32
|
from orchestrator.services.settings import generate_engine_global_status
|
|
33
|
+
from orchestrator.services.settings_env_variables import get_all_exposed_settings
|
|
29
34
|
from orchestrator.settings import ExecutorType, app_settings
|
|
35
|
+
from orchestrator.utils.expose_settings import SettingsExposedSchema
|
|
30
36
|
from orchestrator.utils.json import json_dumps
|
|
31
37
|
from orchestrator.utils.redis import delete_keys_matching_pattern
|
|
32
38
|
from orchestrator.utils.redis_client import create_redis_asyncio_client
|
|
@@ -169,3 +175,8 @@ def generate_engine_status_response(
|
|
|
169
175
|
result = EngineSettingsSchema.model_validate(engine_settings)
|
|
170
176
|
result.global_status = generate_engine_global_status(engine_settings)
|
|
171
177
|
return result
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@router.get("/overview", response_model=list[SettingsExposedSchema])
|
|
181
|
+
def get_exposed_settings() -> list[SettingsExposedSchema]:
|
|
182
|
+
return get_all_exposed_settings()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Copyright 2019-2025 SURF.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from typing import Any, Dict, Type
|
|
15
|
+
|
|
16
|
+
from pydantic import SecretStr as PydanticSecretStr
|
|
17
|
+
from pydantic_core import MultiHostUrl
|
|
18
|
+
from pydantic_settings import BaseSettings
|
|
19
|
+
|
|
20
|
+
from orchestrator.utils.expose_settings import SecretStr as OrchSecretStr
|
|
21
|
+
from orchestrator.utils.expose_settings import SettingsEnvVariablesSchema, SettingsExposedSchema
|
|
22
|
+
|
|
23
|
+
EXPOSED_ENV_SETTINGS_REGISTRY: Dict[str, Type[BaseSettings]] = {}
|
|
24
|
+
MASK = "**********"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def expose_settings(settings_name: str, base_settings: Type[BaseSettings]) -> Type[BaseSettings]:
|
|
28
|
+
"""Decorator to register settings classes."""
|
|
29
|
+
EXPOSED_ENV_SETTINGS_REGISTRY[settings_name] = base_settings
|
|
30
|
+
return base_settings
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def mask_value(key: str, value: Any) -> Any:
|
|
34
|
+
key_lower = key.lower()
|
|
35
|
+
|
|
36
|
+
if "secret" in key_lower or "password" in key_lower:
|
|
37
|
+
# Mask sensitive information
|
|
38
|
+
return MASK
|
|
39
|
+
|
|
40
|
+
if isinstance(value, PydanticSecretStr):
|
|
41
|
+
# Need to convert SecretStr to str for serialization
|
|
42
|
+
return str(value)
|
|
43
|
+
|
|
44
|
+
if isinstance(value, OrchSecretStr):
|
|
45
|
+
return MASK
|
|
46
|
+
|
|
47
|
+
# PostgresDsn is just MultiHostUrl with extra metadata (annotations)
|
|
48
|
+
if isinstance(value, MultiHostUrl):
|
|
49
|
+
# Convert PostgresDsn to str for serialization
|
|
50
|
+
return MASK
|
|
51
|
+
|
|
52
|
+
return value
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_all_exposed_settings() -> list[SettingsExposedSchema]:
|
|
56
|
+
"""Return all registered settings as dicts."""
|
|
57
|
+
|
|
58
|
+
def _get_settings_env_variables(base_settings: Type[BaseSettings]) -> list[SettingsEnvVariablesSchema]:
|
|
59
|
+
"""Get environment variables from settings."""
|
|
60
|
+
return [
|
|
61
|
+
SettingsEnvVariablesSchema(env_name=key, env_value=mask_value(key, value))
|
|
62
|
+
for key, value in base_settings.model_dump().items() # type: ignore
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
SettingsExposedSchema(name=name, variables=_get_settings_env_variables(base_settings))
|
|
67
|
+
for name, base_settings in EXPOSED_ENV_SETTINGS_REGISTRY.items()
|
|
68
|
+
]
|
orchestrator/settings.py
CHANGED
|
@@ -20,6 +20,8 @@ from pydantic import Field, NonNegativeInt, PostgresDsn, RedisDsn
|
|
|
20
20
|
from pydantic_settings import BaseSettings
|
|
21
21
|
|
|
22
22
|
from oauth2_lib.settings import oauth2lib_settings
|
|
23
|
+
from orchestrator.services.settings_env_variables import expose_settings
|
|
24
|
+
from orchestrator.utils.expose_settings import SecretStr as OrchSecretStr
|
|
23
25
|
from pydantic_forms.types import strEnum
|
|
24
26
|
|
|
25
27
|
|
|
@@ -30,7 +32,7 @@ class ExecutorType(strEnum):
|
|
|
30
32
|
|
|
31
33
|
class AppSettings(BaseSettings):
|
|
32
34
|
TESTING: bool = True
|
|
33
|
-
SESSION_SECRET:
|
|
35
|
+
SESSION_SECRET: OrchSecretStr = "".join(secrets.choice(string.ascii_letters) for i in range(16)) # type: ignore
|
|
34
36
|
CORS_ORIGINS: str = "*"
|
|
35
37
|
CORS_ALLOW_METHODS: list[str] = ["GET", "PUT", "PATCH", "POST", "DELETE", "OPTIONS", "HEAD"]
|
|
36
38
|
CORS_ALLOW_HEADERS: list[str] = ["If-None-Match", "Authorization", "If-Match", "Content-Type"]
|
|
@@ -55,7 +57,7 @@ class AppSettings(BaseSettings):
|
|
|
55
57
|
MAIL_PORT: int = 25
|
|
56
58
|
MAIL_STARTTLS: bool = False
|
|
57
59
|
CACHE_URI: RedisDsn = "redis://localhost:6379/0" # type: ignore
|
|
58
|
-
CACHE_HMAC_SECRET:
|
|
60
|
+
CACHE_HMAC_SECRET: OrchSecretStr | None = None # HMAC signing key, used when pickling results in the cache
|
|
59
61
|
REDIS_RETRY_COUNT: NonNegativeInt = Field(
|
|
60
62
|
2, description="Number of retries for redis connection errors/timeouts, 0 to disable"
|
|
61
63
|
) # More info: https://redis-py.readthedocs.io/en/stable/retry.html
|
|
@@ -87,6 +89,8 @@ class AppSettings(BaseSettings):
|
|
|
87
89
|
ENABLE_PROMETHEUS_METRICS_ENDPOINT: bool = False
|
|
88
90
|
VALIDATE_OUT_OF_SYNC_SUBSCRIPTIONS: bool = False
|
|
89
91
|
FILTER_BY_MODE: Literal["partial", "exact"] = "exact"
|
|
92
|
+
EXPOSE_SETTINGS: bool = False
|
|
93
|
+
EXPOSE_OAUTH_SETTINGS: bool = False
|
|
90
94
|
|
|
91
95
|
|
|
92
96
|
app_settings = AppSettings()
|
|
@@ -94,3 +98,8 @@ app_settings = AppSettings()
|
|
|
94
98
|
# Set oauth2lib_settings variables to the same (default) value of settings
|
|
95
99
|
oauth2lib_settings.SERVICE_NAME = app_settings.SERVICE_NAME
|
|
96
100
|
oauth2lib_settings.ENVIRONMENT = app_settings.ENVIRONMENT
|
|
101
|
+
|
|
102
|
+
if app_settings.EXPOSE_SETTINGS:
|
|
103
|
+
expose_settings("app_settings", app_settings) # type: ignore
|
|
104
|
+
if app_settings.EXPOSE_OAUTH_SETTINGS:
|
|
105
|
+
expose_settings("oauth2lib_settings", oauth2lib_settings) # type: ignore
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Copyright 2019-2025 SURF.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
"""Utility module for exposing settings in a structured format.
|
|
14
|
+
|
|
15
|
+
Unfortunately, this module needs to be imported from the utils and cannot be added to the schemas folder.
|
|
16
|
+
This is due to circular import issues with the combination of schemas/settings.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from pydantic import BaseModel
|
|
22
|
+
from pydantic_core import core_schema
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SecretStr(str):
|
|
26
|
+
"""A string that is treated as a secret, for example, passwords or API keys.
|
|
27
|
+
|
|
28
|
+
This class is used to indicate that the string should not be logged or displayed in plaintext.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def __get_pydantic_core_schema__(cls, source_type, handler): # type: ignore
|
|
33
|
+
# This method is used to define how the SecretStr type should be handled by Pydantic.
|
|
34
|
+
# With this implementation, it will fail validation.
|
|
35
|
+
return core_schema.no_info_plain_validator_function(cls)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SettingsEnvVariablesSchema(BaseModel):
|
|
39
|
+
env_name: str
|
|
40
|
+
env_value: Any
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class SettingsExposedSchema(BaseModel):
|
|
44
|
+
name: str
|
|
45
|
+
variables: list[SettingsEnvVariablesSchema]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
orchestrator/__init__.py,sha256=
|
|
1
|
+
orchestrator/__init__.py,sha256=tOY8a4U2sGqlMaBFFS05G5fpTsG5MQWrMraMt7i-SW0,1066
|
|
2
2
|
orchestrator/app.py,sha256=7UrXKjBKNSEaSSXAd5ww_RdMFhFqE4yvfj8faS2MzAA,12089
|
|
3
3
|
orchestrator/exception_handlers.py,sha256=UsW3dw8q0QQlNLcV359bIotah8DYjMsj2Ts1LfX4ClY,1268
|
|
4
4
|
orchestrator/log_config.py,sha256=1tPRX5q65e57a6a_zEii_PFK8SzWT0mnA5w2sKg4hh8,1853
|
|
5
5
|
orchestrator/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
orchestrator/security.py,sha256=iXFxGxab54aav7oHEKLAVkTgrQMJGHy6IYLojEnD7gI,2422
|
|
7
|
-
orchestrator/settings.py,sha256=
|
|
7
|
+
orchestrator/settings.py,sha256=TFIv09JIKY-lXqd04lH_XEcijEEyheaz3zTcgeG8DEI,4339
|
|
8
8
|
orchestrator/targets.py,sha256=WizBgnp8hWX9YLFUIju7ewSubiwQqinCvyiYNcXHbHI,802
|
|
9
9
|
orchestrator/types.py,sha256=qzs7xx5AYRmKbpYRyJJP3wuDb0W0bcAzefCN0RWLAco,15459
|
|
10
10
|
orchestrator/version.py,sha256=b58e08lxs47wUNXv0jXFO_ykpksmytuzEXD4La4W-NQ,1366
|
|
@@ -21,7 +21,7 @@ orchestrator/api/api_v1/endpoints/processes.py,sha256=i5GRoszvdmpZqOxSqON83DNuc0
|
|
|
21
21
|
orchestrator/api/api_v1/endpoints/product_blocks.py,sha256=kZ6ywIOsS_S2qGq7RvZ4KzjvaS1LmwbGWR37AKRvWOw,2146
|
|
22
22
|
orchestrator/api/api_v1/endpoints/products.py,sha256=BfFtwu9dZXEQbtKxYj9icc73GKGvAGMR5ytyf41nQlQ,3081
|
|
23
23
|
orchestrator/api/api_v1/endpoints/resource_types.py,sha256=gGyuaDyOD0TAVoeFGaGmjDGnQ8eQQArOxKrrk4MaDzA,2145
|
|
24
|
-
orchestrator/api/api_v1/endpoints/settings.py,sha256=
|
|
24
|
+
orchestrator/api/api_v1/endpoints/settings.py,sha256=5s-k169podZjgGHUbVDmSQwpY_3Cs_Bbf2PPtZIkBcw,6184
|
|
25
25
|
orchestrator/api/api_v1/endpoints/subscription_customer_descriptions.py,sha256=1_6LtgQleoq3M6z_W-Qz__Bj3OFUweoPrUqHMwSH6AM,3288
|
|
26
26
|
orchestrator/api/api_v1/endpoints/subscriptions.py,sha256=V-ebvjtFEKlALx8SKX42SiNPM-GAgSMWbuaimyktUQQ,8758
|
|
27
27
|
orchestrator/api/api_v1/endpoints/translations.py,sha256=dIWh_fCnZZUxJoGiNeJ49DK_xpf75IpR_0EIMSvzIvY,963
|
|
@@ -268,6 +268,7 @@ orchestrator/services/processes.py,sha256=rTH6zLNsun3qDCPguz2LYS87MQR_LJREIPrgkG
|
|
|
268
268
|
orchestrator/services/products.py,sha256=BP4KyE8zO-8z7Trrs5T6zKBOw53S9BfBJnHWI3p6u5Y,1943
|
|
269
269
|
orchestrator/services/resource_types.py,sha256=_QBy_JOW_X3aSTqH0CuLrq4zBJL0p7Q-UDJUcuK2_qc,884
|
|
270
270
|
orchestrator/services/settings.py,sha256=HEWfFulgoEDwgfxGEO__QTr5fDiwNBEj1UhAeTAdbLQ,3159
|
|
271
|
+
orchestrator/services/settings_env_variables.py,sha256=U2xz0h3bOAE8wWQF2iCp5jf-2v0NUOOCTecNTouB1jY,2496
|
|
271
272
|
orchestrator/services/subscription_relations.py,sha256=9C126TUfFvyBe7y4x007kH_dvxJ9pZ1zSnaWeH6HC5k,12261
|
|
272
273
|
orchestrator/services/subscriptions.py,sha256=nr2HI89nC0lYjzTh2j-lEQ5cPQK43LNZv3gvP6jbepw,27189
|
|
273
274
|
orchestrator/services/tasks.py,sha256=NjPkuauQoh9UJDcjA7OcKFgPk0i6NoKdDO7HlpGbBJ8,6575
|
|
@@ -280,6 +281,7 @@ orchestrator/utils/deprecation_logger.py,sha256=oqju7ecJcB_r7cMnldaOAA79QUZYS_h6
|
|
|
280
281
|
orchestrator/utils/docs.py,sha256=GbyD61oKn1yVYaphUKHCBvrWEWJDTQfRc_VEbVb-zgU,6172
|
|
281
282
|
orchestrator/utils/enrich_process.py,sha256=o_QSy5Q4wn1SMHhzVOw6bp7uhDXr7GhAIWRDDMWUVO4,4699
|
|
282
283
|
orchestrator/utils/errors.py,sha256=6FxvXrITmRjP5bYnJJ3CxjAwA5meNjRAVYouz4TWKkU,4653
|
|
284
|
+
orchestrator/utils/expose_settings.py,sha256=0NOjLBifQy4k2zUYJ31QjGQCaXEQ1zB4UtCle7XglAM,1640
|
|
283
285
|
orchestrator/utils/fixed_inputs.py,sha256=pnL6I_19VMp_Bny8SYjSzVFNvTFDyeCxFFOWGhTnDiQ,2665
|
|
284
286
|
orchestrator/utils/functional.py,sha256=X1MDNwHmkU3-8mFb21m31HGlcfc5TygliXR0sXN3-rU,8304
|
|
285
287
|
orchestrator/utils/get_subscription_dict.py,sha256=hctkFvD3U6LpygNwz2uesRMdnXSY-PaohBqPATsi9r4,694
|
|
@@ -307,7 +309,7 @@ orchestrator/workflows/tasks/resume_workflows.py,sha256=MzJqlSXUvKStkT7NGzxZyRlf
|
|
|
307
309
|
orchestrator/workflows/tasks/validate_product_type.py,sha256=paG-NAY1bdde3Adt8zItkcBKf5Pxw6f5ngGW6an6dYU,3192
|
|
308
310
|
orchestrator/workflows/tasks/validate_products.py,sha256=GZJBoFF-WMphS7ghMs2-gqvV2iL1F0POhk0uSNt93n0,8510
|
|
309
311
|
orchestrator/workflows/translations/en-GB.json,sha256=ST53HxkphFLTMjFHonykDBOZ7-P_KxksktZU3GbxLt0,846
|
|
310
|
-
orchestrator_core-4.
|
|
311
|
-
orchestrator_core-4.
|
|
312
|
-
orchestrator_core-4.
|
|
313
|
-
orchestrator_core-4.
|
|
312
|
+
orchestrator_core-4.1.0rc1.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
|
|
313
|
+
orchestrator_core-4.1.0rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
314
|
+
orchestrator_core-4.1.0rc1.dist-info/METADATA,sha256=hyIGgttPRSo2gjx2V1kbbpd5MvEbnCttnUJ2LzZEyP4,5073
|
|
315
|
+
orchestrator_core-4.1.0rc1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|