orchestrator-core 4.2.0rc1__py3-none-any.whl → 4.2.0rc3__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/processes.py +2 -1
- orchestrator/cli/database.py +8 -1
- orchestrator/cli/domain_gen_helpers/helpers.py +44 -2
- orchestrator/cli/domain_gen_helpers/product_block_helpers.py +35 -15
- orchestrator/cli/domain_gen_helpers/resource_type_helpers.py +5 -5
- orchestrator/cli/domain_gen_helpers/types.py +7 -1
- orchestrator/cli/migrate_domain_models.py +16 -5
- orchestrator/services/settings_env_variables.py +3 -15
- orchestrator/settings.py +1 -1
- orchestrator/utils/errors.py +2 -1
- {orchestrator_core-4.2.0rc1.dist-info → orchestrator_core-4.2.0rc3.dist-info}/METADATA +1 -1
- {orchestrator_core-4.2.0rc1.dist-info → orchestrator_core-4.2.0rc3.dist-info}/RECORD +15 -15
- {orchestrator_core-4.2.0rc1.dist-info → orchestrator_core-4.2.0rc3.dist-info}/WHEEL +0 -0
- {orchestrator_core-4.2.0rc1.dist-info → orchestrator_core-4.2.0rc3.dist-info}/licenses/LICENSE +0 -0
orchestrator/__init__.py
CHANGED
|
@@ -123,6 +123,7 @@ def get_auth_callbacks(steps: StepList, workflow: Workflow) -> tuple[Authorizer
|
|
|
123
123
|
def can_be_resumed(status: ProcessStatus) -> bool:
|
|
124
124
|
return status in (
|
|
125
125
|
ProcessStatus.SUSPENDED, # Can be resumed
|
|
126
|
+
ProcessStatus.WAITING, # Can be retried
|
|
126
127
|
ProcessStatus.FAILED, # Can be retried
|
|
127
128
|
ProcessStatus.API_UNAVAILABLE, # subtype of FAILED
|
|
128
129
|
ProcessStatus.INCONSISTENT_DATA, # subtype of FAILED
|
|
@@ -212,7 +213,7 @@ def resume_process_endpoint(
|
|
|
212
213
|
if process.last_status == ProcessStatus.SUSPENDED:
|
|
213
214
|
if auth_resume is not None and not auth_resume(user_model):
|
|
214
215
|
raise_status(HTTPStatus.FORBIDDEN, "User is not authorized to resume step")
|
|
215
|
-
elif process.last_status
|
|
216
|
+
elif process.last_status in (ProcessStatus.FAILED, ProcessStatus.WAITING):
|
|
216
217
|
if auth_retry is not None and not auth_retry(user_model):
|
|
217
218
|
raise_status(HTTPStatus.FORBIDDEN, "User is not authorized to retry step")
|
|
218
219
|
|
orchestrator/cli/database.py
CHANGED
|
@@ -256,6 +256,9 @@ def migrate_domain_models(
|
|
|
256
256
|
test: bool = typer.Option(False, help="Optional boolean if you don't want to generate a migration file"),
|
|
257
257
|
inputs: str = typer.Option("{}", help="Stringified dict to prefill inputs"),
|
|
258
258
|
updates: str = typer.Option("{}", help="Stringified dict to map updates instead of using inputs"),
|
|
259
|
+
confirm_warnings: bool = typer.Option(
|
|
260
|
+
False, help="Optional boolean if you want to accept all warning inputs, fully knowing things can go wrong"
|
|
261
|
+
),
|
|
259
262
|
) -> tuple[list[str], list[str]] | None:
|
|
260
263
|
"""Create migration file based on SubscriptionModel.diff_product_in_database. BACKUP DATABASE BEFORE USING THE MIGRATION!.
|
|
261
264
|
|
|
@@ -282,6 +285,8 @@ def migrate_domain_models(
|
|
|
282
285
|
- `updates = { "resource_types": { "old_resource_type_name": "new_resource_type_name" } }`
|
|
283
286
|
- renaming a resource type to existing resource type: `updates = { "resource_types": { "old_resource_type_name": "new_resource_type_name" } }`
|
|
284
287
|
|
|
288
|
+
confirm_warnings: Optional boolean if you want to accept all warning inputs, fully knowing things can go wrong.
|
|
289
|
+
|
|
285
290
|
Returns None unless `--test` is used, in which case it returns:
|
|
286
291
|
- tuple:
|
|
287
292
|
- list of upgrade SQL statements in string format.
|
|
@@ -304,7 +309,9 @@ def migrate_domain_models(
|
|
|
304
309
|
resource_types=updates_dict.get("resource_types", {}),
|
|
305
310
|
block_resource_types=updates_dict.get("block_resource_types", {}),
|
|
306
311
|
)
|
|
307
|
-
sql_upgrade_stmts, sql_downgrade_stmts = create_domain_models_migration_sql(
|
|
312
|
+
sql_upgrade_stmts, sql_downgrade_stmts = create_domain_models_migration_sql(
|
|
313
|
+
inputs_dict, updates_class, test, confirm_warnings
|
|
314
|
+
)
|
|
308
315
|
|
|
309
316
|
if test:
|
|
310
317
|
return sql_upgrade_stmts, sql_downgrade_stmts
|
|
@@ -2,10 +2,15 @@ from collections.abc import Iterable
|
|
|
2
2
|
from itertools import groupby
|
|
3
3
|
|
|
4
4
|
import structlog
|
|
5
|
+
import typer
|
|
6
|
+
from more_itertools import first
|
|
5
7
|
from sqlalchemy.dialects import postgresql
|
|
6
8
|
from sqlalchemy.sql.dml import UpdateBase
|
|
7
9
|
|
|
8
|
-
from orchestrator.
|
|
10
|
+
from orchestrator.cli.domain_gen_helpers.types import BlockRelationDict
|
|
11
|
+
from orchestrator.cli.helpers.input_helpers import _prompt_user_menu
|
|
12
|
+
from orchestrator.cli.helpers.print_helpers import noqa_print
|
|
13
|
+
from orchestrator.domain.base import ProductBlockModel, SubscriptionModel
|
|
9
14
|
|
|
10
15
|
logger = structlog.get_logger(__name__)
|
|
11
16
|
|
|
@@ -43,10 +48,47 @@ def map_delete_resource_type_relations(model_diffs: dict[str, dict[str, set[str]
|
|
|
43
48
|
return generic_mapper("missing_resource_types_in_model", model_diffs)
|
|
44
49
|
|
|
45
50
|
|
|
46
|
-
def
|
|
51
|
+
def map_create_product_to_product_block_relations(model_diffs: dict[str, dict[str, set[str]]]) -> dict[str, set[str]]:
|
|
47
52
|
return generic_mapper("missing_product_blocks_in_db", model_diffs)
|
|
48
53
|
|
|
49
54
|
|
|
55
|
+
def format_block_relation_to_dict(
|
|
56
|
+
model_name: str,
|
|
57
|
+
block_to_find_in_props: str,
|
|
58
|
+
models: dict[str, type[SubscriptionModel]] | dict[str, type[ProductBlockModel]],
|
|
59
|
+
confirm_warnings: bool,
|
|
60
|
+
) -> BlockRelationDict:
|
|
61
|
+
model = models[model_name]
|
|
62
|
+
block_props = model._get_depends_on_product_block_types()
|
|
63
|
+
props = {k for k, v in block_props.items() if v.name == block_to_find_in_props} # type: ignore
|
|
64
|
+
|
|
65
|
+
if len(props) > 1 and not confirm_warnings:
|
|
66
|
+
noqa_print("WARNING: Relating a Product Block multiple times is not supported by this migrator!")
|
|
67
|
+
noqa_print(
|
|
68
|
+
"You will need to create your own migration to create a Product Block Instance for each attribute that is related"
|
|
69
|
+
)
|
|
70
|
+
noqa_print(f"Product Block '{block_to_find_in_props}' has been related multiple times to '{model_name}'")
|
|
71
|
+
noqa_print(f"Attributes the block ('{block_to_find_in_props}') has been related with: {', '.join(props)}")
|
|
72
|
+
noqa_print(f"The relation will only be added to the first attribute ('{first(props)}') want to continue?")
|
|
73
|
+
|
|
74
|
+
if _prompt_user_menu([("yes", "yes"), ("no", "no")]) == "no":
|
|
75
|
+
typer.echo("Aborted.")
|
|
76
|
+
raise typer.Exit(code=1)
|
|
77
|
+
|
|
78
|
+
return BlockRelationDict(name=model_name, attribute_name=first(props))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def map_create_product_block_relations(
|
|
82
|
+
model_diffs: dict[str, dict[str, set[str]]],
|
|
83
|
+
models: dict[str, type[SubscriptionModel]] | dict[str, type[ProductBlockModel]],
|
|
84
|
+
confirm_warnings: bool,
|
|
85
|
+
) -> dict[str, list[BlockRelationDict]]:
|
|
86
|
+
data = generic_mapper("missing_product_blocks_in_db", model_diffs)
|
|
87
|
+
return {
|
|
88
|
+
k: [format_block_relation_to_dict(b, k, models, confirm_warnings) for b in blocks] for k, blocks in data.items()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
50
92
|
def map_delete_product_block_relations(model_diffs: dict[str, dict[str, set[str]]]) -> dict[str, set[str]]:
|
|
51
93
|
return generic_mapper("missing_product_blocks_in_model", model_diffs)
|
|
52
94
|
|
|
@@ -7,8 +7,12 @@ from sqlalchemy import select
|
|
|
7
7
|
from sqlalchemy.sql.expression import Delete, Insert
|
|
8
8
|
from sqlalchemy.sql.selectable import ScalarSelect
|
|
9
9
|
|
|
10
|
-
from orchestrator.cli.domain_gen_helpers.helpers import
|
|
11
|
-
|
|
10
|
+
from orchestrator.cli.domain_gen_helpers.helpers import (
|
|
11
|
+
format_block_relation_to_dict,
|
|
12
|
+
get_product_block_names,
|
|
13
|
+
sql_compile,
|
|
14
|
+
)
|
|
15
|
+
from orchestrator.cli.domain_gen_helpers.types import BlockRelationDict, DomainModelChanges
|
|
12
16
|
from orchestrator.cli.helpers.input_helpers import get_user_input
|
|
13
17
|
from orchestrator.cli.helpers.print_helpers import COLOR, print_fmt, str_fmt
|
|
14
18
|
from orchestrator.db import db
|
|
@@ -68,13 +72,17 @@ def map_delete_product_blocks(product_blocks: dict[str, type[ProductBlockModel]]
|
|
|
68
72
|
return {name for name in existing_product_blocks if name not in product_blocks}
|
|
69
73
|
|
|
70
74
|
|
|
71
|
-
def map_product_block_additional_relations(
|
|
75
|
+
def map_product_block_additional_relations(
|
|
76
|
+
changes: DomainModelChanges, models: dict[str, type[ProductBlockModel]], confirm_warnings: bool
|
|
77
|
+
) -> DomainModelChanges:
|
|
72
78
|
"""Map additional relations for created product blocks.
|
|
73
79
|
|
|
74
80
|
Adds resource type and product block relations.
|
|
75
81
|
|
|
76
82
|
Args:
|
|
77
83
|
changes: DomainModelChanges class with all changes.
|
|
84
|
+
models: All product block models.
|
|
85
|
+
confirm_warnings: confirm warnings to continue, fully knowing that things can go wrong.
|
|
78
86
|
|
|
79
87
|
Returns: Updated DomainModelChanges.
|
|
80
88
|
"""
|
|
@@ -86,7 +94,12 @@ def map_product_block_additional_relations(changes: DomainModelChanges) -> Domai
|
|
|
86
94
|
product_blocks_in_model = block_class._get_depends_on_product_block_types()
|
|
87
95
|
product_blocks_types_in_model = get_depends_on_product_block_type_list(product_blocks_in_model)
|
|
88
96
|
for product_block_name in get_product_block_names(product_blocks_types_in_model):
|
|
89
|
-
changes.create_product_block_relations.
|
|
97
|
+
relation_list = changes.create_product_block_relations.get(product_block_name, [])
|
|
98
|
+
new_relation = format_block_relation_to_dict(block_name, product_block_name, models, confirm_warnings)
|
|
99
|
+
|
|
100
|
+
if new_relation not in relation_list:
|
|
101
|
+
changes.create_product_block_relations[product_block_name] = relation_list + [new_relation]
|
|
102
|
+
|
|
90
103
|
return changes
|
|
91
104
|
|
|
92
105
|
|
|
@@ -147,31 +160,35 @@ def generate_delete_product_blocks_sql(delete_product_blocks: set[str]) -> list[
|
|
|
147
160
|
]
|
|
148
161
|
|
|
149
162
|
|
|
150
|
-
def generate_create_product_block_relations_sql(
|
|
163
|
+
def generate_create_product_block_relations_sql(
|
|
164
|
+
create_block_relations: dict[str, list[BlockRelationDict]],
|
|
165
|
+
) -> list[str]:
|
|
151
166
|
"""Generate SQL to create product block to product block relations.
|
|
152
167
|
|
|
153
168
|
Args:
|
|
154
169
|
create_block_relations: Dict with product blocks by product block
|
|
155
170
|
- key: product block name.
|
|
156
|
-
-
|
|
171
|
+
- list: List of product blocks to relate with by prop names.
|
|
157
172
|
|
|
158
173
|
Returns: List of SQL to create relation between product blocks.
|
|
159
174
|
"""
|
|
160
175
|
|
|
161
|
-
def create_block_relation(depends_block_name: str,
|
|
176
|
+
def create_block_relation(depends_block_name: str, block_relations: list[BlockRelationDict]) -> str:
|
|
162
177
|
depends_block_id_sql = get_product_block_id(depends_block_name)
|
|
163
178
|
|
|
164
|
-
def create_block_relation_dict(
|
|
165
|
-
block_id_sql = get_product_block_id(
|
|
179
|
+
def create_block_relation_dict(block_relation: BlockRelationDict) -> dict[str, ScalarSelect]:
|
|
180
|
+
block_id_sql = get_product_block_id(block_relation["name"])
|
|
166
181
|
return {"in_use_by_id": block_id_sql, "depends_on_id": depends_block_id_sql}
|
|
167
182
|
|
|
168
|
-
product_product_block_relation_dicts = [create_block_relation_dict(
|
|
183
|
+
product_product_block_relation_dicts = [create_block_relation_dict(block) for block in block_relations]
|
|
169
184
|
return sql_compile(Insert(ProductBlockRelationTable).values(product_product_block_relation_dicts))
|
|
170
185
|
|
|
171
186
|
return [create_block_relation(*item) for item in create_block_relations.items()]
|
|
172
187
|
|
|
173
188
|
|
|
174
|
-
def generate_create_product_block_instance_relations_sql(
|
|
189
|
+
def generate_create_product_block_instance_relations_sql(
|
|
190
|
+
product_block_relations: dict[str, list[BlockRelationDict]],
|
|
191
|
+
) -> list[str]:
|
|
175
192
|
"""Generate SQL to create resource type instance values for existing instances.
|
|
176
193
|
|
|
177
194
|
Args:
|
|
@@ -183,12 +200,14 @@ def generate_create_product_block_instance_relations_sql(product_block_relations
|
|
|
183
200
|
"""
|
|
184
201
|
|
|
185
202
|
def create_subscription_instance_relations(
|
|
186
|
-
depends_block_name: str,
|
|
203
|
+
depends_block_name: str, block_relations: list[BlockRelationDict]
|
|
187
204
|
) -> Generator[str, None, None]:
|
|
188
205
|
depends_block_id_sql = get_product_block_id(depends_block_name)
|
|
189
206
|
|
|
190
|
-
def map_subscription_instances(
|
|
191
|
-
|
|
207
|
+
def map_subscription_instances(
|
|
208
|
+
block_relation: BlockRelationDict,
|
|
209
|
+
) -> dict[str, list[dict[str, str | ScalarSelect]]]:
|
|
210
|
+
in_use_by_id_sql = get_product_block_id(block_relation["name"])
|
|
192
211
|
stmt = select(
|
|
193
212
|
SubscriptionInstanceTable.subscription_instance_id, SubscriptionInstanceTable.subscription_id
|
|
194
213
|
).where(SubscriptionInstanceTable.product_block_id.in_(in_use_by_id_sql))
|
|
@@ -206,13 +225,14 @@ def generate_create_product_block_instance_relations_sql(product_block_relations
|
|
|
206
225
|
"in_use_by_id": instance.subscription_instance_id,
|
|
207
226
|
"depends_on_id": get_subscription_instance(instance.subscription_id, depends_block_id_sql),
|
|
208
227
|
"order_id": 0,
|
|
228
|
+
"domain_model_attr": block_relation["attribute_name"],
|
|
209
229
|
}
|
|
210
230
|
for instance in subscription_instances
|
|
211
231
|
]
|
|
212
232
|
|
|
213
233
|
return {"instance_list": instance_list, "instance_relation_list": instance_relation_list}
|
|
214
234
|
|
|
215
|
-
create_instance_list = [map_subscription_instances(
|
|
235
|
+
create_instance_list = [map_subscription_instances(block_relation) for block_relation in block_relations]
|
|
216
236
|
|
|
217
237
|
subscription_instance_dicts = list(flatten(item["instance_list"] for item in create_instance_list))
|
|
218
238
|
subscription_relation_dicts = list(flatten(item["instance_relation_list"] for item in create_instance_list))
|
|
@@ -9,7 +9,7 @@ from sqlalchemy.sql.selectable import ScalarSelect
|
|
|
9
9
|
|
|
10
10
|
from orchestrator.cli.domain_gen_helpers.helpers import sql_compile
|
|
11
11
|
from orchestrator.cli.domain_gen_helpers.product_block_helpers import get_product_block_id, get_product_block_ids
|
|
12
|
-
from orchestrator.cli.domain_gen_helpers.types import DomainModelChanges
|
|
12
|
+
from orchestrator.cli.domain_gen_helpers.types import BlockRelationDict, DomainModelChanges
|
|
13
13
|
from orchestrator.cli.helpers.input_helpers import _enumerate_menu_keys, _prompt_user_menu, get_user_input
|
|
14
14
|
from orchestrator.cli.helpers.print_helpers import COLOR, noqa_print, print_fmt, str_fmt
|
|
15
15
|
from orchestrator.db import db
|
|
@@ -262,8 +262,8 @@ def _has_product_existing_instances(product_name: str) -> bool:
|
|
|
262
262
|
return bool(product and get_product_instance_count(product.product_id))
|
|
263
263
|
|
|
264
264
|
|
|
265
|
-
def
|
|
266
|
-
return
|
|
265
|
+
def _find_new_block_relations(block_name: str, relations: dict[str, list[BlockRelationDict]]) -> set[str]:
|
|
266
|
+
return {r["name"] for r in relations.get(block_name, [])}
|
|
267
267
|
|
|
268
268
|
|
|
269
269
|
def map_create_resource_type_instances(changes: DomainModelChanges) -> dict[str, set[str]]:
|
|
@@ -285,11 +285,11 @@ def map_create_resource_type_instances(changes: DomainModelChanges) -> dict[str,
|
|
|
285
285
|
if block and get_block_instance_count(block.product_block_id):
|
|
286
286
|
return True
|
|
287
287
|
|
|
288
|
-
related_block_names =
|
|
288
|
+
related_block_names = _find_new_block_relations(block_name, changes.create_product_block_relations)
|
|
289
289
|
if related_block_names:
|
|
290
290
|
return any(_has_existing_instances(name) for name in related_block_names)
|
|
291
291
|
|
|
292
|
-
related_product_names =
|
|
292
|
+
related_product_names = changes.create_product_to_block_relations.get(block_name, set())
|
|
293
293
|
return any(_has_product_existing_instances(name) for name in related_product_names)
|
|
294
294
|
|
|
295
295
|
return {
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
from pydantic import BaseModel
|
|
2
|
+
from typing_extensions import TypedDict
|
|
2
3
|
|
|
3
4
|
from orchestrator.domain.base import ProductBlockModel, SubscriptionModel
|
|
4
5
|
|
|
5
6
|
|
|
7
|
+
class BlockRelationDict(TypedDict):
|
|
8
|
+
name: str
|
|
9
|
+
attribute_name: str
|
|
10
|
+
|
|
11
|
+
|
|
6
12
|
class DomainModelChanges(BaseModel):
|
|
7
13
|
create_products: dict[str, type[SubscriptionModel]] = {}
|
|
8
14
|
delete_products: set[str] = set()
|
|
@@ -10,7 +16,7 @@ class DomainModelChanges(BaseModel):
|
|
|
10
16
|
delete_product_to_block_relations: dict[str, set[str]] = {}
|
|
11
17
|
create_product_blocks: dict[str, type[ProductBlockModel]] = {}
|
|
12
18
|
delete_product_blocks: set[str] = set()
|
|
13
|
-
create_product_block_relations: dict[str,
|
|
19
|
+
create_product_block_relations: dict[str, list[BlockRelationDict]] = {}
|
|
14
20
|
delete_product_block_relations: dict[str, set[str]] = {}
|
|
15
21
|
create_product_fixed_inputs: dict[str, set[str]] = {}
|
|
16
22
|
update_product_fixed_inputs: dict[str, dict[str, str]] = {}
|
|
@@ -21,6 +21,7 @@ from orchestrator.cli.domain_gen_helpers.fixed_input_helpers import (
|
|
|
21
21
|
from orchestrator.cli.domain_gen_helpers.helpers import (
|
|
22
22
|
map_create_fixed_inputs,
|
|
23
23
|
map_create_product_block_relations,
|
|
24
|
+
map_create_product_to_product_block_relations,
|
|
24
25
|
map_create_resource_type_relations,
|
|
25
26
|
map_delete_fixed_inputs,
|
|
26
27
|
map_delete_product_block_relations,
|
|
@@ -191,6 +192,7 @@ def map_changes(
|
|
|
191
192
|
db_product_names: list[str],
|
|
192
193
|
inputs: dict[str, dict[str, str]],
|
|
193
194
|
updates: ModelUpdates | None,
|
|
195
|
+
confirm_warnings: bool,
|
|
194
196
|
) -> DomainModelChanges:
|
|
195
197
|
"""Map changes that need to be made to fix differences between models and database.
|
|
196
198
|
|
|
@@ -203,6 +205,7 @@ def map_changes(
|
|
|
203
205
|
db_product_names: Product names out of the database.
|
|
204
206
|
inputs: Optional Dict with prefilled values.
|
|
205
207
|
updates: Optional Dict.
|
|
208
|
+
confirm_warnings: confirm warnings to continue, fully knowing that things can go wrong.
|
|
206
209
|
|
|
207
210
|
Returns: Mapped changes.
|
|
208
211
|
"""
|
|
@@ -231,7 +234,7 @@ def map_changes(
|
|
|
231
234
|
create_product_fixed_inputs=map_create_fixed_inputs(model_diffs["products"]),
|
|
232
235
|
update_product_fixed_inputs=updates.fixed_inputs,
|
|
233
236
|
delete_product_fixed_inputs=map_delete_fixed_inputs(model_diffs["products"]),
|
|
234
|
-
create_product_to_block_relations=
|
|
237
|
+
create_product_to_block_relations=map_create_product_to_product_block_relations(model_diffs["products"]),
|
|
235
238
|
delete_product_to_block_relations=map_delete_product_block_relations(model_diffs["products"]),
|
|
236
239
|
rename_resource_types=updates.resource_types,
|
|
237
240
|
update_block_resource_types=updates.block_resource_types,
|
|
@@ -242,12 +245,14 @@ def map_changes(
|
|
|
242
245
|
delete_resource_type_relations=delete_resource_type_relations,
|
|
243
246
|
create_product_blocks=map_create_product_blocks(product_blocks),
|
|
244
247
|
delete_product_blocks=map_delete_product_blocks(product_blocks),
|
|
245
|
-
create_product_block_relations=map_create_product_block_relations(
|
|
248
|
+
create_product_block_relations=map_create_product_block_relations(
|
|
249
|
+
model_diffs["blocks"], product_blocks, confirm_warnings
|
|
250
|
+
),
|
|
246
251
|
delete_product_block_relations=map_delete_product_block_relations(model_diffs["blocks"]),
|
|
247
252
|
)
|
|
248
253
|
|
|
249
254
|
changes = map_product_additional_relations(changes)
|
|
250
|
-
changes = map_product_block_additional_relations(changes)
|
|
255
|
+
changes = map_product_block_additional_relations(changes, product_blocks, confirm_warnings)
|
|
251
256
|
temp = {key for v in changes.update_block_resource_types.values() for key in v.values()}
|
|
252
257
|
related_resource_type_names = set(changes.create_resource_type_relations.keys()) | temp
|
|
253
258
|
existing_renamed_rts = set(changes.rename_resource_types.values())
|
|
@@ -334,8 +339,12 @@ def generate_downgrade_sql(changes: DomainModelChanges) -> list[str]:
|
|
|
334
339
|
sql_revert_create_product_product_block_relations = generate_delete_product_relations_sql(
|
|
335
340
|
changes.create_product_to_block_relations,
|
|
336
341
|
)
|
|
342
|
+
|
|
343
|
+
downgrade_block_relations = {
|
|
344
|
+
k: {b["name"] for b in blocks} for k, blocks in changes.create_product_block_relations.items()
|
|
345
|
+
}
|
|
337
346
|
sql_revert_create_product_block_depends_blocks = generate_delete_product_block_relations_sql(
|
|
338
|
-
|
|
347
|
+
downgrade_block_relations
|
|
339
348
|
)
|
|
340
349
|
|
|
341
350
|
sql_revert_create_product_blocks = generate_delete_product_blocks_sql(set(changes.create_product_blocks.keys()))
|
|
@@ -361,6 +370,7 @@ def create_domain_models_migration_sql(
|
|
|
361
370
|
inputs: dict[str, dict[str, str]],
|
|
362
371
|
updates: ModelUpdates | None,
|
|
363
372
|
is_test: bool = False,
|
|
373
|
+
confirm_warnings: bool = False,
|
|
364
374
|
) -> tuple[list[str], list[str]]:
|
|
365
375
|
"""Create tuple with list for upgrade and downgrade SQL statements based on SubscriptionModel.diff_product_in_database.
|
|
366
376
|
|
|
@@ -370,6 +380,7 @@ def create_domain_models_migration_sql(
|
|
|
370
380
|
inputs: dict with pre-defined input values
|
|
371
381
|
updates: The model
|
|
372
382
|
is_test: the bool for if it is test
|
|
383
|
+
confirm_warnings: confirm warnings to continue, fully knowing that things can go wrong.
|
|
373
384
|
|
|
374
385
|
Returns tuple:
|
|
375
386
|
list of upgrade SQL statements in string format.
|
|
@@ -384,7 +395,7 @@ def create_domain_models_migration_sql(
|
|
|
384
395
|
product_blocks = map_product_blocks(list(SUBSCRIPTION_MODEL_REGISTRY.values()))
|
|
385
396
|
model_diffs = map_differences_unique(products, existing_products)
|
|
386
397
|
|
|
387
|
-
changes = map_changes(model_diffs, products, product_blocks, db_product_names, inputs, updates)
|
|
398
|
+
changes = map_changes(model_diffs, products, product_blocks, db_product_names, inputs, updates, confirm_warnings)
|
|
388
399
|
|
|
389
400
|
logger.info("create_products", create_products=changes.create_products)
|
|
390
401
|
logger.info("delete_products", delete_products=changes.delete_products)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
from typing import Any, Dict, Type
|
|
15
15
|
|
|
16
16
|
from pydantic import SecretStr as PydanticSecretStr
|
|
17
|
-
from pydantic_core import MultiHostUrl
|
|
17
|
+
from pydantic_core import MultiHostUrl, Url
|
|
18
18
|
from pydantic_settings import BaseSettings
|
|
19
19
|
|
|
20
20
|
from orchestrator.utils.expose_settings import SecretStr as OrchSecretStr
|
|
@@ -32,21 +32,9 @@ def expose_settings(settings_name: str, base_settings: Type[BaseSettings]) -> Ty
|
|
|
32
32
|
|
|
33
33
|
def mask_value(key: str, value: Any) -> Any:
|
|
34
34
|
key_lower = key.lower()
|
|
35
|
+
is_sensitive_key = "secret" in key_lower or "password" in key_lower
|
|
35
36
|
|
|
36
|
-
if
|
|
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
|
|
37
|
+
if is_sensitive_key or isinstance(value, (OrchSecretStr, PydanticSecretStr, MultiHostUrl, Url)):
|
|
50
38
|
return MASK
|
|
51
39
|
|
|
52
40
|
return value
|
orchestrator/settings.py
CHANGED
|
@@ -72,7 +72,7 @@ class AppSettings(BaseSettings):
|
|
|
72
72
|
TRACING_ENABLED: bool = False
|
|
73
73
|
TRACE_HOST: str = "http://localhost:4317"
|
|
74
74
|
TRANSLATIONS_DIR: Path | None = None
|
|
75
|
-
WEBSOCKET_BROADCASTER_URL:
|
|
75
|
+
WEBSOCKET_BROADCASTER_URL: OrchSecretStr = "memory://" # type: ignore
|
|
76
76
|
ENABLE_WEBSOCKETS: bool = True
|
|
77
77
|
DISABLE_INSYNC_CHECK: bool = False
|
|
78
78
|
DEFAULT_PRODUCT_WORKFLOWS: list[str] = ["modify_note"]
|
orchestrator/utils/errors.py
CHANGED
|
@@ -128,12 +128,13 @@ def _(err: Exception) -> ErrorDict:
|
|
|
128
128
|
# We can't dispatch on ApiException, see is_api_exception docstring
|
|
129
129
|
if is_api_exception(err):
|
|
130
130
|
err = cast(ApiException, err)
|
|
131
|
+
headers = err.headers or {}
|
|
131
132
|
return {
|
|
132
133
|
"class": type(err).__name__,
|
|
133
134
|
"error": err.reason,
|
|
134
135
|
"status_code": err.status,
|
|
135
136
|
"body": err.body,
|
|
136
|
-
"headers": "\n".join(f"{k}: {v}" for k, v in
|
|
137
|
+
"headers": "\n".join(f"{k}: {v}" for k, v in headers.items()),
|
|
137
138
|
"traceback": show_ex(err),
|
|
138
139
|
}
|
|
139
140
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
orchestrator/__init__.py,sha256=
|
|
1
|
+
orchestrator/__init__.py,sha256=MNhlJ5Q_DEafB6SuZWg0TMOJczWgoj8ZnDFt9FGHqlM,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=2Kgc6m3qUCcSM3Z_IVUeehfgO0QphMFkLrS0RC3sU-U,4365
|
|
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
|
|
@@ -17,7 +17,7 @@ orchestrator/api/api_v1/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n
|
|
|
17
17
|
orchestrator/api/api_v1/api.py,sha256=m4iDktsSpzxUDaudkdgXeZ83a6B4wfc3pczQsa-Pb-8,2866
|
|
18
18
|
orchestrator/api/api_v1/endpoints/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
|
|
19
19
|
orchestrator/api/api_v1/endpoints/health.py,sha256=iaxs1XX1_250_gKNsspuULCV2GEMBjbtjsmfQTOvMAI,1284
|
|
20
|
-
orchestrator/api/api_v1/endpoints/processes.py,sha256=
|
|
20
|
+
orchestrator/api/api_v1/endpoints/processes.py,sha256=79_nrXEfEREc_9P-aIpcJn6idfwQzMutHsPEcyrNzBA,16223
|
|
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
|
|
@@ -29,21 +29,21 @@ orchestrator/api/api_v1/endpoints/user.py,sha256=RyI32EXVu6I-IxWjz0XB5zQWzzLL60z
|
|
|
29
29
|
orchestrator/api/api_v1/endpoints/workflows.py,sha256=_0vhGiQeu3-z16Zi0WmuDWBs8gmed6BzRNwYH_sF6AY,1977
|
|
30
30
|
orchestrator/api/api_v1/endpoints/ws.py,sha256=1l7E0ag_sZ6UMfQPHlmew7ENwxjm6fflBwcMZAb7V-k,2786
|
|
31
31
|
orchestrator/cli/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
|
|
32
|
-
orchestrator/cli/database.py,sha256=
|
|
32
|
+
orchestrator/cli/database.py,sha256=YkYAbCY2VPAa6mDW0PpNKG5wL4FuAQYD2CGl1_DQtEk,19595
|
|
33
33
|
orchestrator/cli/generate.py,sha256=SBaYfRijXPF9r3VxarPKTiDzDcB6GBMMQvecQIb_ZLQ,7377
|
|
34
34
|
orchestrator/cli/main.py,sha256=GC_kxa9OZ-Y0ig_klfWc6ysOQuPVTUmTmDRj3m8cJHA,983
|
|
35
|
-
orchestrator/cli/migrate_domain_models.py,sha256=
|
|
35
|
+
orchestrator/cli/migrate_domain_models.py,sha256=WRXy_1OnziQwpsCFZXvjB30nDJtjj0ikVXy8YNLque4,20928
|
|
36
36
|
orchestrator/cli/migrate_tasks.py,sha256=bju8XColjSZD0v3rS4kl-24dLr8En_H4-6enBmqd494,7255
|
|
37
37
|
orchestrator/cli/migrate_workflows.py,sha256=nxUpx0vgEIc_8aJrjAyrw3E9Dt8JmaamTts8oiQ4vHY,8923
|
|
38
38
|
orchestrator/cli/migration_helpers.py,sha256=C5tpkP5WEBr7G9S-1k1hgSI8ili6xd9Z5ygc9notaK0,4110
|
|
39
39
|
orchestrator/cli/scheduler.py,sha256=iCKBWYUwQIYTDqKQ9rMVvs2sNiAzE-J2SkV170TPP2g,1896
|
|
40
40
|
orchestrator/cli/domain_gen_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
41
|
orchestrator/cli/domain_gen_helpers/fixed_input_helpers.py,sha256=uzpwsaau81hHSxNMOS9-o7kF-9_78R0f_UE0AvWooZQ,6775
|
|
42
|
-
orchestrator/cli/domain_gen_helpers/helpers.py,sha256=
|
|
43
|
-
orchestrator/cli/domain_gen_helpers/product_block_helpers.py,sha256=
|
|
42
|
+
orchestrator/cli/domain_gen_helpers/helpers.py,sha256=tIPxn8ezED_xYZxH7ZAtQLwkDc6RNmLZVxWAoJ3a9lw,4203
|
|
43
|
+
orchestrator/cli/domain_gen_helpers/product_block_helpers.py,sha256=IYvjch4IEqDN45FTC0xeZkJgDrxJnCin98RukPs_ARw,11273
|
|
44
44
|
orchestrator/cli/domain_gen_helpers/product_helpers.py,sha256=Pe4d_GApMErQDeuJnCEvF6jFf7FROaILvVdpKKQ7cUI,9379
|
|
45
|
-
orchestrator/cli/domain_gen_helpers/resource_type_helpers.py,sha256=
|
|
46
|
-
orchestrator/cli/domain_gen_helpers/types.py,sha256=
|
|
45
|
+
orchestrator/cli/domain_gen_helpers/resource_type_helpers.py,sha256=hrsDx5QGkQRsEq38DYHrRmG7tJ2eqqMzW0U55JxAFdM,23995
|
|
46
|
+
orchestrator/cli/domain_gen_helpers/types.py,sha256=JojWInZL04lwSHSUB_Pr4LliA5YS2WKmALQY49-va5o,1530
|
|
47
47
|
orchestrator/cli/generator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
48
|
orchestrator/cli/generator/custom_templates/README,sha256=Y0olhdLtuZCX1US1b05IAzFS8qwd02QoX2QErEPEMmU,173
|
|
49
49
|
orchestrator/cli/generator/custom_templates/additional_create_imports.j2,sha256=1TcnJutzfklzuGKKG-Zs9YwnsGCLlmexz2HBajjO8wo,307
|
|
@@ -270,7 +270,7 @@ orchestrator/services/processes.py,sha256=W-MCuGxRXLNIx3zn_jQQWXXFIBUrjJgXyBMsx2
|
|
|
270
270
|
orchestrator/services/products.py,sha256=BP4KyE8zO-8z7Trrs5T6zKBOw53S9BfBJnHWI3p6u5Y,1943
|
|
271
271
|
orchestrator/services/resource_types.py,sha256=_QBy_JOW_X3aSTqH0CuLrq4zBJL0p7Q-UDJUcuK2_qc,884
|
|
272
272
|
orchestrator/services/settings.py,sha256=HEWfFulgoEDwgfxGEO__QTr5fDiwNBEj1UhAeTAdbLQ,3159
|
|
273
|
-
orchestrator/services/settings_env_variables.py,sha256=
|
|
273
|
+
orchestrator/services/settings_env_variables.py,sha256=iPErQjqPQCxKs0sPhefB16d8SBBVUi6eiRnFBK5bgqA,2196
|
|
274
274
|
orchestrator/services/subscription_relations.py,sha256=9C126TUfFvyBe7y4x007kH_dvxJ9pZ1zSnaWeH6HC5k,12261
|
|
275
275
|
orchestrator/services/subscriptions.py,sha256=nr2HI89nC0lYjzTh2j-lEQ5cPQK43LNZv3gvP6jbepw,27189
|
|
276
276
|
orchestrator/services/tasks.py,sha256=NjPkuauQoh9UJDcjA7OcKFgPk0i6NoKdDO7HlpGbBJ8,6575
|
|
@@ -283,7 +283,7 @@ orchestrator/utils/datetime.py,sha256=a1WQ_yvu7MA0TiaRpC5avwbOSFdrj4eMrV4a7I2sD5
|
|
|
283
283
|
orchestrator/utils/deprecation_logger.py,sha256=oqju7ecJcB_r7cMnldaOAA79QUZYS_h69IkDrFV9nAg,875
|
|
284
284
|
orchestrator/utils/docs.py,sha256=GbyD61oKn1yVYaphUKHCBvrWEWJDTQfRc_VEbVb-zgU,6172
|
|
285
285
|
orchestrator/utils/enrich_process.py,sha256=sIb9jVM6MzttK1uJsRbUNMN8Aevo3erSAX0Agjbo5EA,4732
|
|
286
|
-
orchestrator/utils/errors.py,sha256=
|
|
286
|
+
orchestrator/utils/errors.py,sha256=1zgikc31XmBRyNMn9mc39nDogaDLEQbvqjlA0cJ5lEQ,4685
|
|
287
287
|
orchestrator/utils/expose_settings.py,sha256=0NOjLBifQy4k2zUYJ31QjGQCaXEQ1zB4UtCle7XglAM,1640
|
|
288
288
|
orchestrator/utils/fixed_inputs.py,sha256=pnL6I_19VMp_Bny8SYjSzVFNvTFDyeCxFFOWGhTnDiQ,2665
|
|
289
289
|
orchestrator/utils/functional.py,sha256=X1MDNwHmkU3-8mFb21m31HGlcfc5TygliXR0sXN3-rU,8304
|
|
@@ -312,7 +312,7 @@ orchestrator/workflows/tasks/resume_workflows.py,sha256=MzJqlSXUvKStkT7NGzxZyRlf
|
|
|
312
312
|
orchestrator/workflows/tasks/validate_product_type.py,sha256=paG-NAY1bdde3Adt8zItkcBKf5Pxw6f5ngGW6an6dYU,3192
|
|
313
313
|
orchestrator/workflows/tasks/validate_products.py,sha256=GZJBoFF-WMphS7ghMs2-gqvV2iL1F0POhk0uSNt93n0,8510
|
|
314
314
|
orchestrator/workflows/translations/en-GB.json,sha256=ST53HxkphFLTMjFHonykDBOZ7-P_KxksktZU3GbxLt0,846
|
|
315
|
-
orchestrator_core-4.2.
|
|
316
|
-
orchestrator_core-4.2.
|
|
317
|
-
orchestrator_core-4.2.
|
|
318
|
-
orchestrator_core-4.2.
|
|
315
|
+
orchestrator_core-4.2.0rc3.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
|
|
316
|
+
orchestrator_core-4.2.0rc3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
317
|
+
orchestrator_core-4.2.0rc3.dist-info/METADATA,sha256=tZvFy_sZGGGFM85nN9l4jzPoxVjlJa_CwifNtt9bGfo,5963
|
|
318
|
+
orchestrator_core-4.2.0rc3.dist-info/RECORD,,
|
|
File without changes
|
{orchestrator_core-4.2.0rc1.dist-info → orchestrator_core-4.2.0rc3.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|