infrahub-server 1.3.0a0__py3-none-any.whl → 1.3.0b2__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.
- infrahub/actions/tasks.py +4 -11
- infrahub/branch/__init__.py +0 -0
- infrahub/branch/tasks.py +29 -0
- infrahub/branch/triggers.py +22 -0
- infrahub/cli/db.py +2 -2
- infrahub/computed_attribute/gather.py +3 -1
- infrahub/computed_attribute/tasks.py +23 -29
- infrahub/core/attribute.py +3 -3
- infrahub/core/constants/__init__.py +10 -0
- infrahub/core/constants/database.py +1 -0
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/convert_object_type/conversion.py +1 -1
- infrahub/core/diff/query/save.py +67 -40
- infrahub/core/diff/query/time_range_query.py +0 -1
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/migrations/graph/__init__.py +6 -0
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +0 -2
- infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
- infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
- infrahub/core/migrations/query/attribute_add.py +13 -9
- infrahub/core/migrations/query/attribute_rename.py +2 -4
- infrahub/core/migrations/query/delete_element_in_schema.py +16 -11
- infrahub/core/migrations/query/node_duplicate.py +16 -15
- infrahub/core/migrations/query/relationship_duplicate.py +16 -12
- infrahub/core/migrations/schema/node_attribute_remove.py +1 -2
- infrahub/core/migrations/schema/node_remove.py +16 -14
- infrahub/core/node/__init__.py +74 -14
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -2
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -2
- infrahub/core/node/resource_manager/number_pool.py +31 -5
- infrahub/core/node/standard.py +6 -1
- infrahub/core/path.py +1 -1
- infrahub/core/protocols.py +10 -0
- infrahub/core/query/node.py +1 -1
- infrahub/core/query/relationship.py +4 -6
- infrahub/core/query/standard_node.py +19 -5
- infrahub/core/relationship/constraints/peer_relatives.py +72 -0
- infrahub/core/relationship/model.py +1 -1
- infrahub/core/schema/attribute_parameters.py +129 -5
- infrahub/core/schema/attribute_schema.py +62 -14
- infrahub/core/schema/basenode_schema.py +2 -2
- infrahub/core/schema/definitions/core/__init__.py +16 -2
- infrahub/core/schema/definitions/core/group.py +45 -0
- infrahub/core/schema/definitions/core/resource_pool.py +29 -0
- infrahub/core/schema/definitions/internal.py +25 -4
- infrahub/core/schema/generated/attribute_schema.py +12 -5
- infrahub/core/schema/generated/relationship_schema.py +6 -1
- infrahub/core/schema/manager.py +7 -2
- infrahub/core/schema/schema_branch.py +69 -5
- infrahub/core/validators/__init__.py +8 -0
- infrahub/core/validators/attribute/choices.py +0 -1
- infrahub/core/validators/attribute/enum.py +0 -1
- infrahub/core/validators/attribute/kind.py +0 -1
- infrahub/core/validators/attribute/length.py +0 -1
- infrahub/core/validators/attribute/min_max.py +118 -0
- infrahub/core/validators/attribute/number_pool.py +106 -0
- infrahub/core/validators/attribute/optional.py +0 -2
- infrahub/core/validators/attribute/regex.py +0 -1
- infrahub/core/validators/enum.py +5 -0
- infrahub/core/validators/tasks.py +1 -1
- infrahub/database/__init__.py +16 -4
- infrahub/database/validation.py +100 -0
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/registry.py +2 -0
- infrahub/events/models.py +1 -1
- infrahub/git/base.py +5 -3
- infrahub/git/integrator.py +102 -3
- infrahub/graphql/mutations/main.py +1 -1
- infrahub/graphql/mutations/resource_manager.py +54 -6
- infrahub/graphql/queries/resource_manager.py +7 -1
- infrahub/graphql/queries/task.py +10 -0
- infrahub/graphql/resolvers/many_relationship.py +1 -1
- infrahub/graphql/resolvers/resolver.py +2 -2
- infrahub/graphql/resolvers/single_relationship.py +1 -1
- infrahub/graphql/types/task_log.py +3 -2
- infrahub/menu/menu.py +8 -7
- infrahub/message_bus/operations/refresh/registry.py +3 -3
- infrahub/patch/queries/delete_duplicated_edges.py +40 -29
- infrahub/pools/number.py +5 -3
- infrahub/pools/registration.py +22 -0
- infrahub/pools/tasks.py +56 -0
- infrahub/schema/__init__.py +0 -0
- infrahub/schema/tasks.py +27 -0
- infrahub/schema/triggers.py +23 -0
- infrahub/task_manager/task.py +44 -4
- infrahub/trigger/catalogue.py +4 -0
- infrahub/trigger/models.py +5 -4
- infrahub/trigger/setup.py +26 -2
- infrahub/trigger/tasks.py +1 -1
- infrahub/types.py +6 -0
- infrahub/webhook/tasks.py +6 -9
- infrahub/workflows/catalogue.py +27 -1
- infrahub_sdk/client.py +43 -10
- infrahub_sdk/node/__init__.py +39 -0
- infrahub_sdk/node/attribute.py +122 -0
- infrahub_sdk/node/constants.py +21 -0
- infrahub_sdk/{node.py → node/node.py} +50 -749
- infrahub_sdk/node/parsers.py +15 -0
- infrahub_sdk/node/property.py +24 -0
- infrahub_sdk/node/related_node.py +266 -0
- infrahub_sdk/node/relationship.py +302 -0
- infrahub_sdk/protocols.py +112 -0
- infrahub_sdk/protocols_base.py +34 -2
- infrahub_sdk/query_groups.py +13 -2
- infrahub_sdk/schema/main.py +1 -0
- infrahub_sdk/schema/repository.py +16 -0
- infrahub_sdk/spec/object.py +1 -1
- infrahub_sdk/store.py +1 -1
- infrahub_sdk/testing/schemas/car_person.py +1 -0
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/METADATA +3 -3
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/RECORD +122 -100
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/WHEEL +1 -1
- infrahub_testcontainers/container.py +239 -64
- infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
- infrahub_testcontainers/docker-compose.test.yml +1 -0
- infrahub_testcontainers/helpers.py +15 -1
- infrahub_testcontainers/plugin.py +9 -0
- infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -106
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/entry_points.txt +0 -0
infrahub/actions/tasks.py
CHANGED
|
@@ -2,13 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from infrahub_sdk.graphql import Mutation
|
|
4
4
|
from prefect import flow
|
|
5
|
-
from prefect.client.orchestration import get_client
|
|
6
5
|
|
|
7
|
-
from infrahub import lock
|
|
8
6
|
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
|
|
9
7
|
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
10
8
|
from infrahub.trigger.models import TriggerType
|
|
11
|
-
from infrahub.trigger.setup import
|
|
9
|
+
from infrahub.trigger.setup import setup_triggers_specific
|
|
12
10
|
from infrahub.workflows.utils import add_tags
|
|
13
11
|
|
|
14
12
|
from .gather import gather_trigger_action_rules
|
|
@@ -101,14 +99,9 @@ async def run_generator_group_event(
|
|
|
101
99
|
async def configure_action_rules(
|
|
102
100
|
service: InfrahubServices,
|
|
103
101
|
) -> None:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
await setup_triggers(
|
|
108
|
-
client=prefect_client,
|
|
109
|
-
triggers=triggers,
|
|
110
|
-
trigger_type=TriggerType.ACTION_TRIGGER_RULE,
|
|
111
|
-
) # type: ignore[misc]
|
|
102
|
+
await setup_triggers_specific(
|
|
103
|
+
gatherer=gather_trigger_action_rules, trigger_type=TriggerType.ACTION_TRIGGER_RULE, db=service.database
|
|
104
|
+
) # type: ignore[misc]
|
|
112
105
|
|
|
113
106
|
|
|
114
107
|
async def _run_generator(
|
|
File without changes
|
infrahub/branch/tasks.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from prefect import flow
|
|
4
|
+
from prefect.logging import get_run_logger
|
|
5
|
+
|
|
6
|
+
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
|
|
7
|
+
from infrahub.core.registry import registry
|
|
8
|
+
from infrahub.pools.tasks import validate_schema_number_pools
|
|
9
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
10
|
+
from infrahub.workflows.utils import wait_for_schema_to_converge
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@flow(
|
|
14
|
+
name="branch-merged",
|
|
15
|
+
flow_run_name="Running actions after '{source_branch}' was merged",
|
|
16
|
+
)
|
|
17
|
+
async def branch_merged(
|
|
18
|
+
source_branch: str, # noqa: ARG001
|
|
19
|
+
context: InfrahubContext,
|
|
20
|
+
service: InfrahubServices,
|
|
21
|
+
target_branch: str | None = None,
|
|
22
|
+
) -> None:
|
|
23
|
+
target_branch = target_branch or registry.default_branch
|
|
24
|
+
log = get_run_logger()
|
|
25
|
+
await wait_for_schema_to_converge(
|
|
26
|
+
branch_name=target_branch, component=service.component, db=service.database, log=log
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
await validate_schema_number_pools(branch_name=target_branch, context=context, service=service)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from infrahub.events.branch_action import BranchMergedEvent
|
|
2
|
+
from infrahub.trigger.models import BuiltinTriggerDefinition, EventTrigger, ExecuteWorkflow
|
|
3
|
+
from infrahub.workflows.catalogue import BRANCH_MERGED
|
|
4
|
+
|
|
5
|
+
TRIGGER_BRANCH_MERGED = BuiltinTriggerDefinition(
|
|
6
|
+
name="branch-merged-trigger",
|
|
7
|
+
trigger=EventTrigger(
|
|
8
|
+
events={BranchMergedEvent.event_name},
|
|
9
|
+
),
|
|
10
|
+
actions=[
|
|
11
|
+
ExecuteWorkflow(
|
|
12
|
+
workflow=BRANCH_MERGED,
|
|
13
|
+
parameters={
|
|
14
|
+
"source_branch": "{{ event.payload['data']['branch_name'] }}",
|
|
15
|
+
"context": {
|
|
16
|
+
"__prefect_kind": "json",
|
|
17
|
+
"value": {"__prefect_kind": "jinja", "template": "{{ event.payload['context'] | tojson }}"},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
),
|
|
21
|
+
],
|
|
22
|
+
)
|
infrahub/cli/db.py
CHANGED
|
@@ -326,7 +326,7 @@ async def migrate_database(db: InfrahubDatabase, initialize: bool = False, check
|
|
|
326
326
|
root_node.graph_version = migration.minimum_version + 1
|
|
327
327
|
await root_node.save(db=db)
|
|
328
328
|
|
|
329
|
-
if not execution_result.success or validation_result and not validation_result.success:
|
|
329
|
+
if not execution_result.success or (validation_result and not validation_result.success):
|
|
330
330
|
rprint(f"Migration: {migration.name} {FAILED_BADGE}")
|
|
331
331
|
for error in execution_result.errors:
|
|
332
332
|
rprint(f" {error}")
|
|
@@ -449,7 +449,7 @@ async def selected_export_cmd(
|
|
|
449
449
|
ctx: typer.Context,
|
|
450
450
|
kinds: list[str] = typer.Option([], help="Node kinds to export"), # noqa: B008
|
|
451
451
|
uuids: list[str] = typer.Option([], help="UUIDs of nodes to export"), # noqa: B008
|
|
452
|
-
query_limit: int = typer.Option(1000, help="Maximum batch size of export query"),
|
|
452
|
+
query_limit: int = typer.Option(1000, help="Maximum batch size of export query"),
|
|
453
453
|
export_dir: Path = typer.Option(Path("infrahub-exports"), help="Path of directory to save exports"), # noqa: B008
|
|
454
454
|
config_file: str = typer.Argument("infrahub.toml", envvar="INFRAHUB_CONFIG"),
|
|
455
455
|
) -> None:
|
|
@@ -100,7 +100,9 @@ async def gather_python_transform_attributes(
|
|
|
100
100
|
name="gather-trigger-computed-attribute-jinja2",
|
|
101
101
|
cache_policy=NONE,
|
|
102
102
|
)
|
|
103
|
-
async def gather_trigger_computed_attribute_jinja2(
|
|
103
|
+
async def gather_trigger_computed_attribute_jinja2(
|
|
104
|
+
db: InfrahubDatabase | None = None, # noqa: ARG001 Needed to have a common function signature for gathering functions
|
|
105
|
+
) -> list[ComputedAttrJinja2TriggerDefinition]:
|
|
104
106
|
log = get_run_logger()
|
|
105
107
|
|
|
106
108
|
# Build a list of all branches to process based on which branch is different from main
|
|
@@ -15,7 +15,7 @@ from infrahub.events import BranchDeletedEvent
|
|
|
15
15
|
from infrahub.git.repository import get_initialized_repo
|
|
16
16
|
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
17
17
|
from infrahub.trigger.models import TriggerSetupReport, TriggerType
|
|
18
|
-
from infrahub.trigger.setup import setup_triggers
|
|
18
|
+
from infrahub.trigger.setup import setup_triggers, setup_triggers_specific
|
|
19
19
|
from infrahub.workflows.catalogue import (
|
|
20
20
|
COMPUTED_ATTRIBUTE_PROCESS_JINJA2,
|
|
21
21
|
COMPUTED_ATTRIBUTE_PROCESS_TRANSFORM,
|
|
@@ -304,36 +304,30 @@ async def computed_attribute_setup_jinja2(
|
|
|
304
304
|
await add_tags(branches=[branch_name])
|
|
305
305
|
await wait_for_schema_to_converge(branch_name=branch_name, component=service.component, db=db, log=log)
|
|
306
306
|
|
|
307
|
-
|
|
308
|
-
|
|
307
|
+
report: TriggerSetupReport = await setup_triggers_specific(
|
|
308
|
+
gatherer=gather_trigger_computed_attribute_jinja2, trigger_type=TriggerType.COMPUTED_ATTR_JINJA2
|
|
309
|
+
) # type: ignore[misc]
|
|
309
310
|
# Configure all ComputedAttrJinja2Trigger in Prefect
|
|
310
|
-
async with get_client(sync_client=False) as prefect_client:
|
|
311
|
-
report: TriggerSetupReport = await setup_triggers(
|
|
312
|
-
client=prefect_client,
|
|
313
|
-
triggers=triggers,
|
|
314
|
-
trigger_type=TriggerType.COMPUTED_ATTR_JINJA2,
|
|
315
|
-
force_update=False,
|
|
316
|
-
) # type: ignore[misc]
|
|
317
311
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
log.info(f"{
|
|
312
|
+
# Since we can have multiple trigger per NodeKind
|
|
313
|
+
# we need to extract the list of unique node that should be processed
|
|
314
|
+
unique_nodes: set[tuple[str, str, str]] = {
|
|
315
|
+
(trigger.branch, trigger.computed_attribute.kind, trigger.computed_attribute.attribute.name) # type: ignore[attr-defined]
|
|
316
|
+
for trigger in report.updated + report.created
|
|
317
|
+
}
|
|
318
|
+
for branch, kind, attribute_name in unique_nodes:
|
|
319
|
+
if event_name != BranchDeletedEvent.event_name and branch == branch_name:
|
|
320
|
+
await service.workflow.submit_workflow(
|
|
321
|
+
workflow=TRIGGER_UPDATE_JINJA_COMPUTED_ATTRIBUTES,
|
|
322
|
+
context=context,
|
|
323
|
+
parameters={
|
|
324
|
+
"branch_name": branch,
|
|
325
|
+
"computed_attribute_name": attribute_name,
|
|
326
|
+
"computed_attribute_kind": kind,
|
|
327
|
+
},
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
log.info(f"{report.in_use_count} Computed Attribute for Jinja2 automation configuration completed")
|
|
337
331
|
|
|
338
332
|
|
|
339
333
|
@flow(
|
infrahub/core/attribute.py
CHANGED
|
@@ -93,8 +93,8 @@ class BaseAttribute(FlagPropertyMixin, NodePropertyMixin):
|
|
|
93
93
|
updated_at: Timestamp | str | None = None,
|
|
94
94
|
is_default: bool = False,
|
|
95
95
|
is_from_profile: bool = False,
|
|
96
|
-
**kwargs,
|
|
97
|
-
):
|
|
96
|
+
**kwargs: dict[str, Any],
|
|
97
|
+
) -> None:
|
|
98
98
|
self.id = id
|
|
99
99
|
self.db_id = db_id
|
|
100
100
|
|
|
@@ -169,7 +169,7 @@ class BaseAttribute(FlagPropertyMixin, NodePropertyMixin):
|
|
|
169
169
|
return self.branch
|
|
170
170
|
|
|
171
171
|
@classmethod
|
|
172
|
-
def __init_subclass__(cls, **kwargs) -> None:
|
|
172
|
+
def __init_subclass__(cls, **kwargs: dict[str, Any]) -> None:
|
|
173
173
|
super().__init_subclass__(**kwargs)
|
|
174
174
|
registry.attribute[cls.__name__] = cls
|
|
175
175
|
|
|
@@ -112,6 +112,11 @@ class AccountType(InfrahubStringEnum):
|
|
|
112
112
|
Git = "Git"
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
class NumberPoolType(InfrahubStringEnum):
|
|
116
|
+
USER = "User"
|
|
117
|
+
SCHEMA = "Schema"
|
|
118
|
+
|
|
119
|
+
|
|
115
120
|
class AccountStatus(InfrahubStringEnum):
|
|
116
121
|
ACTIVE = "active"
|
|
117
122
|
INACTIVE = "inactive"
|
|
@@ -146,6 +151,11 @@ class AllowOverrideType(InfrahubStringEnum):
|
|
|
146
151
|
ANY = "any"
|
|
147
152
|
|
|
148
153
|
|
|
154
|
+
class RepositoryObjects(InfrahubStringEnum):
|
|
155
|
+
OBJECT = "object"
|
|
156
|
+
MENU = "menu"
|
|
157
|
+
|
|
158
|
+
|
|
149
159
|
class ContentType(InfrahubStringEnum):
|
|
150
160
|
APPLICATION_JSON = "application/json"
|
|
151
161
|
APPLICATION_YAML = "application/yaml"
|
|
@@ -58,6 +58,7 @@ PROFILE = "CoreProfile"
|
|
|
58
58
|
PROPOSEDCHANGE = "CoreProposedChange"
|
|
59
59
|
REFRESHTOKEN = "InternalRefreshToken"
|
|
60
60
|
REPOSITORY = "CoreRepository"
|
|
61
|
+
REPOSITORYGROUP = "CoreRepositoryGroup"
|
|
61
62
|
RESOURCEPOOL = "CoreResourcePool"
|
|
62
63
|
GENERICREPOSITORY = "CoreGenericRepository"
|
|
63
64
|
READONLYREPOSITORY = "CoreReadOnlyRepository"
|
|
@@ -78,3 +79,4 @@ TRIGGERRULE = "CoreTriggerRule"
|
|
|
78
79
|
USERVALIDATOR = "CoreUserValidator"
|
|
79
80
|
VALIDATOR = "CoreValidator"
|
|
80
81
|
WEBHOOK = "CoreWebhook"
|
|
82
|
+
WEIGHTED_POOL_RESOURCE = "CoreWeightedPoolResource"
|
|
@@ -97,7 +97,7 @@ async def convert_object_type(
|
|
|
97
97
|
if not isinstance(node_schema, NodeSchema):
|
|
98
98
|
raise ValueError(f"Only a node with a NodeSchema can be converted, got {type(node_schema)}")
|
|
99
99
|
|
|
100
|
-
async with db.start_transaction() as dbt:
|
|
100
|
+
async with db.start_transaction() as dbt:
|
|
101
101
|
deleted_node_out_rels_peer_ids = await get_out_rels_peers_ids(node=node, db=dbt)
|
|
102
102
|
deleted_node_unidir_rels_peer_ids = await get_unidirectional_rels_peers_ids(node=node, db=dbt, branch=branch)
|
|
103
103
|
|
infrahub/core/diff/query/save.py
CHANGED
|
@@ -78,6 +78,7 @@ class EnrichedNodeBatchCreateQuery(Query):
|
|
|
78
78
|
|
|
79
79
|
async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
|
|
80
80
|
self.params = self._build_node_batch_params()
|
|
81
|
+
|
|
81
82
|
query = """
|
|
82
83
|
UNWIND $node_details_list AS node_details
|
|
83
84
|
WITH
|
|
@@ -131,57 +132,74 @@ CALL (diff_node, has_node_conflict, node_conflict_params) {
|
|
|
131
132
|
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_CONFLICT]->(node_conflict:DiffConflict)
|
|
132
133
|
SET node_conflict = node_conflict_params
|
|
133
134
|
}
|
|
135
|
+
// -------------------------
|
|
136
|
+
// resetting the UNWIND and starting over here reduces memory usage
|
|
137
|
+
// -------------------------
|
|
138
|
+
WITH root_uuid LIMIT 1
|
|
139
|
+
UNWIND $node_details_list AS node_details
|
|
140
|
+
WITH
|
|
141
|
+
node_details.root_uuid AS root_uuid,
|
|
142
|
+
node_details.node_map AS node_map,
|
|
143
|
+
toString(node_details.node_map.node_properties.uuid) AS node_uuid,
|
|
144
|
+
node_details.node_map.node_properties.db_id AS node_db_id
|
|
145
|
+
MATCH (:DiffRoot {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid, db_id: node_db_id})
|
|
146
|
+
WITH diff_node, node_map, %(attr_name_list_comp)s AS attr_names
|
|
147
|
+
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(attr_to_delete:DiffAttribute)
|
|
148
|
+
WHERE NOT (attr_to_delete.name IN attr_names)
|
|
149
|
+
OPTIONAL MATCH (attr_to_delete)-[*..6]->(next_to_delete)
|
|
150
|
+
DETACH DELETE next_to_delete
|
|
151
|
+
DETACH DELETE attr_to_delete
|
|
152
|
+
// -------------------------
|
|
153
|
+
// add attributes for this node
|
|
154
|
+
// -------------------------
|
|
155
|
+
WITH DISTINCT diff_node, node_map
|
|
134
156
|
CALL (diff_node, node_map) {
|
|
135
|
-
// -------------------------
|
|
136
|
-
// remove stale attributes for this node
|
|
137
|
-
// -------------------------
|
|
138
|
-
CALL (diff_node, node_map) {
|
|
139
|
-
WITH %(attr_name_list_comp)s AS attr_names
|
|
140
|
-
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(attr_to_delete:DiffAttribute)
|
|
141
|
-
WHERE NOT (attr_to_delete.name IN attr_names)
|
|
142
|
-
OPTIONAL MATCH (attr_to_delete)-[*..6]->(next_to_delete)
|
|
143
|
-
DETACH DELETE next_to_delete
|
|
144
|
-
DETACH DELETE attr_to_delete
|
|
145
|
-
}
|
|
146
|
-
// -------------------------
|
|
147
|
-
// add attributes for this node
|
|
148
|
-
// -------------------------
|
|
149
157
|
UNWIND node_map.attributes AS node_attribute
|
|
150
158
|
MERGE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute {name: node_attribute.node_properties.name})
|
|
151
159
|
SET diff_attribute = node_attribute.node_properties
|
|
152
160
|
// -------------------------
|
|
153
|
-
//
|
|
161
|
+
// remove stale properties for this attribute
|
|
154
162
|
// -------------------------
|
|
155
|
-
WITH diff_attribute, node_attribute
|
|
163
|
+
WITH diff_attribute, node_attribute, %(attr_props_list_comp)s AS prop_types
|
|
164
|
+
OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
|
|
165
|
+
WHERE NOT (prop_to_delete.property_type IN prop_types)
|
|
166
|
+
OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
|
|
167
|
+
DETACH DELETE next_to_delete
|
|
168
|
+
DETACH DELETE prop_to_delete
|
|
156
169
|
// -------------------------
|
|
157
|
-
//
|
|
170
|
+
// set attribute property values
|
|
158
171
|
// -------------------------
|
|
159
|
-
|
|
160
|
-
WITH %(attr_props_list_comp)s AS prop_types
|
|
161
|
-
OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
|
|
162
|
-
WHERE NOT (prop_to_delete.property_type IN prop_types)
|
|
163
|
-
OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
|
|
164
|
-
DETACH DELETE next_to_delete
|
|
165
|
-
DETACH DELETE prop_to_delete
|
|
166
|
-
}
|
|
172
|
+
WITH DISTINCT diff_attribute, node_attribute
|
|
167
173
|
UNWIND node_attribute.properties AS attr_property
|
|
168
174
|
MERGE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty {property_type: attr_property.node_properties.property_type})
|
|
169
175
|
SET diff_attr_prop = attr_property.node_properties
|
|
170
|
-
// -------------------------
|
|
171
|
-
// add/remove conflict for this property
|
|
172
|
-
// -------------------------
|
|
173
176
|
WITH diff_attr_prop, attr_property
|
|
174
177
|
OPTIONAL MATCH (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(current_attr_prop_conflict:DiffConflict)
|
|
175
178
|
WITH diff_attr_prop, attr_property, current_attr_prop_conflict, (attr_property.conflict_params IS NOT NULL) AS has_prop_conflict
|
|
176
|
-
|
|
179
|
+
CALL (has_prop_conflict, current_attr_prop_conflict) {
|
|
180
|
+
WITH has_prop_conflict, current_attr_prop_conflict
|
|
181
|
+
WHERE has_prop_conflict = FALSE AND current_attr_prop_conflict IS NOT NULL
|
|
177
182
|
DETACH DELETE current_attr_prop_conflict
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
}
|
|
184
|
+
CALL (has_prop_conflict, diff_attr_prop, attr_property) {
|
|
185
|
+
WITH has_prop_conflict
|
|
186
|
+
WHERE has_prop_conflict = TRUE
|
|
180
187
|
MERGE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attr_prop_conflict:DiffConflict)
|
|
181
188
|
SET diff_attr_prop_conflict = attr_property.conflict_params
|
|
182
|
-
|
|
189
|
+
}
|
|
183
190
|
}
|
|
184
191
|
// -------------------------
|
|
192
|
+
// resetting the UNWIND and starting over here reduces memory usage
|
|
193
|
+
// -------------------------
|
|
194
|
+
WITH 1 AS resetting LIMIT 1
|
|
195
|
+
UNWIND $node_details_list AS node_details
|
|
196
|
+
WITH
|
|
197
|
+
node_details.root_uuid AS root_uuid,
|
|
198
|
+
node_details.node_map AS node_map,
|
|
199
|
+
toString(node_details.node_map.node_properties.uuid) AS node_uuid,
|
|
200
|
+
node_details.node_map.node_properties.db_id AS node_db_id
|
|
201
|
+
MATCH (:DiffRoot {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid, db_id: node_db_id})
|
|
202
|
+
// -------------------------
|
|
185
203
|
// remove stale relationships for this node
|
|
186
204
|
// -------------------------
|
|
187
205
|
CALL (diff_node, node_map) {
|
|
@@ -226,13 +244,17 @@ WITH diff_relationship_element, node_single_relationship
|
|
|
226
244
|
OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(current_element_conflict:DiffConflict)
|
|
227
245
|
WITH diff_relationship_element, node_single_relationship, current_element_conflict,
|
|
228
246
|
(node_single_relationship.conflict_params IS NOT NULL) AS has_element_conflict
|
|
229
|
-
|
|
247
|
+
CALL (has_element_conflict, current_element_conflict) {
|
|
248
|
+
WITH has_element_conflict
|
|
249
|
+
WHERE has_element_conflict = FALSE
|
|
230
250
|
DETACH DELETE current_element_conflict
|
|
231
|
-
|
|
232
|
-
|
|
251
|
+
}
|
|
252
|
+
CALL (has_element_conflict, diff_relationship_element, node_single_relationship) {
|
|
253
|
+
WITH has_element_conflict
|
|
254
|
+
WHERE has_element_conflict = TRUE
|
|
233
255
|
MERGE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(element_conflict:DiffConflict)
|
|
234
256
|
SET element_conflict = node_single_relationship.conflict_params
|
|
235
|
-
|
|
257
|
+
}
|
|
236
258
|
// -------------------------
|
|
237
259
|
// remove stale properties for this relationship element
|
|
238
260
|
// -------------------------
|
|
@@ -260,13 +282,18 @@ WITH diff_relationship_property, node_relationship_property
|
|
|
260
282
|
OPTIONAL MATCH (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict)
|
|
261
283
|
WITH diff_relationship_property, node_relationship_property, diff_relationship_property_conflict,
|
|
262
284
|
(node_relationship_property.conflict_params IS NOT NULL) AS has_property_conflict
|
|
263
|
-
|
|
285
|
+
|
|
286
|
+
CALL (has_property_conflict, diff_relationship_property_conflict) {
|
|
287
|
+
WITH has_property_conflict
|
|
288
|
+
WHERE has_property_conflict = FALSE
|
|
264
289
|
DETACH DELETE diff_relationship_property_conflict
|
|
265
|
-
|
|
266
|
-
|
|
290
|
+
}
|
|
291
|
+
CALL (has_property_conflict, diff_relationship_property, node_relationship_property) {
|
|
292
|
+
WITH has_property_conflict
|
|
293
|
+
WHERE has_property_conflict = TRUE
|
|
267
294
|
MERGE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(property_conflict:DiffConflict)
|
|
268
295
|
SET property_conflict = node_relationship_property.conflict_params
|
|
269
|
-
|
|
296
|
+
}
|
|
270
297
|
""" % {
|
|
271
298
|
"attr_name_list_comp": db.render_list_comprehension(
|
|
272
299
|
items="node_map.attributes", item_name="node_properties.name"
|
infrahub/core/graph/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
GRAPH_VERSION =
|
|
1
|
+
GRAPH_VERSION = 30
|
|
@@ -29,6 +29,9 @@ from .m024_missing_hierarchy_backfill import Migration024
|
|
|
29
29
|
from .m025_uniqueness_nulls import Migration025
|
|
30
30
|
from .m026_0000_prefix_fix import Migration026
|
|
31
31
|
from .m027_delete_isolated_nodes import Migration027
|
|
32
|
+
from .m028_delete_diffs import Migration028
|
|
33
|
+
from .m029_duplicates_cleanup import Migration029
|
|
34
|
+
from .m030_illegal_edges import Migration030
|
|
32
35
|
|
|
33
36
|
if TYPE_CHECKING:
|
|
34
37
|
from infrahub.core.root import Root
|
|
@@ -63,6 +66,9 @@ MIGRATIONS: list[type[GraphMigration | InternalSchemaMigration | ArbitraryMigrat
|
|
|
63
66
|
Migration025,
|
|
64
67
|
Migration026,
|
|
65
68
|
Migration027,
|
|
69
|
+
Migration028,
|
|
70
|
+
Migration029,
|
|
71
|
+
Migration030,
|
|
66
72
|
]
|
|
67
73
|
|
|
68
74
|
|
|
@@ -77,7 +77,6 @@ class Migration013ConvertCoreRepositoryWithCred(Query):
|
|
|
77
77
|
|
|
78
78
|
self.params["rel_identifier"] = "gitrepository__credential"
|
|
79
79
|
|
|
80
|
-
# ruff: noqa: E501
|
|
81
80
|
query = """
|
|
82
81
|
// --------------------------------
|
|
83
82
|
// Identify the git repositories to convert
|
|
@@ -194,7 +193,6 @@ class Migration013ConvertCoreRepositoryWithoutCred(Query):
|
|
|
194
193
|
|
|
195
194
|
self.params["current_time"] = self.at.to_string()
|
|
196
195
|
|
|
197
|
-
# ruff: noqa: E501
|
|
198
196
|
query = """
|
|
199
197
|
// --------------------------------
|
|
200
198
|
// Identify the git repositories to convert
|