infrahub-server 1.1.6__py3-none-any.whl → 1.2.0rc0__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/api/artifact.py +16 -4
- infrahub/api/dependencies.py +8 -0
- infrahub/api/oauth2.py +0 -1
- infrahub/api/oidc.py +0 -1
- infrahub/api/query.py +18 -7
- infrahub/api/schema.py +32 -6
- infrahub/api/transformation.py +12 -5
- infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +2 -4
- infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
- infrahub/cli/__init__.py +0 -2
- infrahub/cli/db.py +6 -7
- infrahub/cli/events.py +8 -3
- infrahub/cli/git_agent.py +9 -7
- infrahub/cli/tasks.py +4 -6
- infrahub/computed_attribute/tasks.py +63 -17
- infrahub/computed_attribute/triggers.py +90 -0
- infrahub/config.py +1 -1
- infrahub/context.py +39 -0
- infrahub/core/account.py +5 -8
- infrahub/core/attribute.py +53 -21
- infrahub/core/branch/models.py +4 -4
- infrahub/core/branch/tasks.py +89 -130
- infrahub/core/changelog/__init__.py +0 -0
- infrahub/core/changelog/diff.py +232 -0
- infrahub/core/changelog/models.py +488 -0
- infrahub/core/constants/__init__.py +19 -2
- infrahub/core/constants/infrahubkind.py +1 -0
- infrahub/core/diff/combiner.py +12 -8
- infrahub/core/diff/coordinator.py +49 -70
- infrahub/core/diff/data_check_synchronizer.py +86 -7
- infrahub/core/diff/enricher/aggregated.py +3 -3
- infrahub/core/diff/enricher/cardinality_one.py +2 -7
- infrahub/core/diff/enricher/hierarchy.py +5 -3
- infrahub/core/diff/enricher/labels.py +14 -4
- infrahub/core/diff/enricher/path_identifier.py +3 -9
- infrahub/core/diff/enricher/summary_counts.py +3 -1
- infrahub/core/diff/merger/merger.py +8 -4
- infrahub/core/diff/model/path.py +47 -29
- infrahub/core/diff/query/all_conflicts.py +6 -3
- infrahub/core/diff/query/artifact.py +1 -1
- infrahub/core/diff/query/delete_query.py +1 -1
- infrahub/core/diff/query/diff_get.py +3 -2
- infrahub/core/diff/query/diff_summary.py +1 -1
- infrahub/core/diff/query/field_specifiers.py +3 -1
- infrahub/core/diff/query/field_summary.py +3 -2
- infrahub/core/diff/query/filters.py +12 -1
- infrahub/core/diff/query/get_conflict_query.py +1 -1
- infrahub/core/diff/query/has_conflicts_query.py +6 -3
- infrahub/core/diff/query/merge.py +3 -3
- infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
- infrahub/core/diff/query/roots_metadata.py +9 -2
- infrahub/core/diff/query/save.py +151 -66
- infrahub/core/diff/query/summary_counts_enricher.py +220 -0
- infrahub/core/diff/query/time_range_query.py +3 -2
- infrahub/core/diff/query/update_conflict_query.py +1 -1
- infrahub/core/diff/query_parser.py +49 -24
- infrahub/core/diff/repository/deserializer.py +24 -25
- infrahub/core/diff/repository/repository.py +76 -20
- infrahub/core/diff/tasks.py +9 -8
- infrahub/core/enums.py +1 -1
- infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
- infrahub/core/ipam/reconciler.py +1 -1
- infrahub/core/ipam/tasks.py +2 -3
- infrahub/core/manager.py +18 -13
- infrahub/core/merge.py +5 -2
- infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
- infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
- infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
- infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
- infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
- infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
- infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
- infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
- infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
- infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
- infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
- infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
- infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
- infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
- infrahub/core/migrations/query/attribute_add.py +1 -1
- infrahub/core/migrations/query/attribute_rename.py +1 -1
- infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
- infrahub/core/migrations/query/node_duplicate.py +1 -1
- infrahub/core/migrations/query/relationship_duplicate.py +1 -1
- infrahub/core/migrations/query/schema_attribute_update.py +1 -1
- infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
- infrahub/core/migrations/schema/node_remove.py +1 -1
- infrahub/core/migrations/schema/tasks.py +5 -5
- infrahub/core/migrations/shared.py +4 -4
- infrahub/core/models.py +7 -8
- infrahub/core/node/__init__.py +161 -40
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
- infrahub/core/node/delete_validator.py +4 -4
- infrahub/core/node/ipam.py +13 -8
- infrahub/core/node/permissions.py +4 -0
- infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
- infrahub/core/node/standard.py +3 -5
- infrahub/core/property.py +1 -1
- infrahub/core/protocols.py +4 -0
- infrahub/core/protocols_base.py +4 -2
- infrahub/core/query/__init__.py +2 -5
- infrahub/core/query/attribute.py +9 -9
- infrahub/core/query/branch.py +5 -5
- infrahub/core/query/delete.py +1 -1
- infrahub/core/query/diff.py +45 -7
- infrahub/core/query/ipam.py +4 -4
- infrahub/core/query/node.py +19 -14
- infrahub/core/query/relationship.py +10 -11
- infrahub/core/query/resource_manager.py +13 -11
- infrahub/core/query/standard_node.py +6 -6
- infrahub/core/query/task.py +3 -3
- infrahub/core/query/task_log.py +1 -1
- infrahub/core/query/utils.py +5 -5
- infrahub/core/registry.py +0 -2
- infrahub/core/relationship/constraints/count.py +1 -1
- infrahub/core/relationship/constraints/peer_kind.py +1 -1
- infrahub/core/relationship/model.py +66 -26
- infrahub/core/schema/__init__.py +6 -4
- infrahub/core/schema/basenode_schema.py +1 -3
- infrahub/core/schema/definitions/core.py +14 -2
- infrahub/core/schema/definitions/internal.py +16 -0
- infrahub/core/schema/generated/genericnode_schema.py +5 -0
- infrahub/core/schema/generated/node_schema.py +5 -0
- infrahub/core/schema/generic_schema.py +5 -1
- infrahub/core/schema/manager.py +45 -42
- infrahub/core/schema/node_schema.py +4 -0
- infrahub/core/schema/profile_schema.py +4 -0
- infrahub/core/schema/relationship_schema.py +2 -2
- infrahub/core/schema/schema_branch.py +248 -14
- infrahub/core/schema/template_schema.py +36 -0
- infrahub/core/task/user_task.py +7 -5
- infrahub/core/timestamp.py +1 -1
- infrahub/core/utils.py +3 -2
- infrahub/core/validators/attribute/choices.py +1 -1
- infrahub/core/validators/attribute/enum.py +1 -1
- infrahub/core/validators/attribute/kind.py +1 -1
- infrahub/core/validators/attribute/length.py +1 -1
- infrahub/core/validators/attribute/optional.py +1 -1
- infrahub/core/validators/attribute/regex.py +1 -1
- infrahub/core/validators/attribute/unique.py +1 -1
- infrahub/core/validators/checks_runner.py +37 -0
- infrahub/core/validators/node/generate_profile.py +1 -1
- infrahub/core/validators/node/hierarchy.py +1 -1
- infrahub/core/validators/query.py +1 -1
- infrahub/core/validators/relationship/count.py +1 -1
- infrahub/core/validators/relationship/optional.py +1 -1
- infrahub/core/validators/relationship/peer.py +1 -1
- infrahub/core/validators/tasks.py +8 -6
- infrahub/core/validators/uniqueness/query.py +20 -17
- infrahub/database/__init__.py +15 -2
- infrahub/database/memgraph.py +1 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
- infrahub/dependencies/builder/diff/combiner.py +1 -1
- infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
- infrahub/dependencies/builder/diff/coordinator.py +0 -2
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
- infrahub/events/branch_action.py +47 -21
- infrahub/events/group_action.py +73 -0
- infrahub/events/models.py +159 -51
- infrahub/events/node_action.py +74 -8
- infrahub/events/repository_action.py +8 -8
- infrahub/events/schema_action.py +21 -8
- infrahub/generators/tasks.py +12 -13
- infrahub/git/base.py +3 -5
- infrahub/git/constants.py +0 -1
- infrahub/git/integrator.py +36 -35
- infrahub/git/repository.py +7 -8
- infrahub/git/tasks.py +43 -107
- infrahub/git_credential/helper.py +2 -3
- infrahub/graphql/analyzer.py +572 -11
- infrahub/graphql/app.py +34 -26
- infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
- infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
- infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
- infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
- infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
- infrahub/graphql/enums.py +1 -1
- infrahub/graphql/initialization.py +5 -1
- infrahub/graphql/loaders/node.py +2 -2
- infrahub/graphql/manager.py +59 -54
- infrahub/graphql/mutations/account.py +20 -13
- infrahub/graphql/mutations/artifact_definition.py +16 -12
- infrahub/graphql/mutations/branch.py +61 -40
- infrahub/graphql/mutations/computed_attribute.py +19 -13
- infrahub/graphql/mutations/diff.py +37 -9
- infrahub/graphql/mutations/diff_conflict.py +9 -8
- infrahub/graphql/mutations/graphql_query.py +19 -11
- infrahub/graphql/mutations/ipam.py +21 -19
- infrahub/graphql/mutations/main.py +197 -44
- infrahub/graphql/mutations/menu.py +8 -8
- infrahub/graphql/mutations/proposed_change.py +36 -28
- infrahub/graphql/mutations/relationship.py +302 -105
- infrahub/graphql/mutations/repository.py +41 -35
- infrahub/graphql/mutations/resource_manager.py +26 -26
- infrahub/graphql/mutations/schema.py +51 -33
- infrahub/graphql/mutations/tasks.py +16 -10
- infrahub/graphql/parser.py +1 -1
- infrahub/graphql/permissions.py +6 -4
- infrahub/graphql/queries/account.py +22 -18
- infrahub/graphql/queries/branch.py +6 -4
- infrahub/graphql/queries/diff/tree.py +48 -42
- infrahub/graphql/queries/event.py +112 -0
- infrahub/graphql/queries/internal.py +3 -3
- infrahub/graphql/queries/ipam.py +23 -18
- infrahub/graphql/queries/relationship.py +11 -10
- infrahub/graphql/queries/resource_manager.py +43 -27
- infrahub/graphql/queries/search.py +9 -8
- infrahub/graphql/queries/status.py +12 -9
- infrahub/graphql/queries/task.py +11 -9
- infrahub/graphql/resolvers/resolver.py +69 -43
- infrahub/graphql/resolvers/single_relationship.py +16 -10
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/subscription/__init__.py +1 -1
- infrahub/graphql/subscription/events.py +1 -1
- infrahub/graphql/subscription/graphql_query.py +8 -8
- infrahub/graphql/types/branch.py +2 -2
- infrahub/graphql/types/common.py +6 -1
- infrahub/graphql/types/enums.py +2 -0
- infrahub/graphql/types/event.py +100 -0
- infrahub/graphql/types/interface.py +2 -2
- infrahub/graphql/types/node.py +3 -3
- infrahub/graphql/types/permission.py +2 -2
- infrahub/graphql/types/relationship.py +3 -3
- infrahub/graphql/types/standard_node.py +9 -11
- infrahub/graphql/utils.py +28 -182
- infrahub/groups/tasks.py +2 -3
- infrahub/lock.py +1 -1
- infrahub/menu/constants.py +1 -0
- infrahub/menu/generator.py +14 -3
- infrahub/menu/menu.py +116 -127
- infrahub/menu/models.py +4 -4
- infrahub/message_bus/messages/__init__.py +0 -4
- infrahub/message_bus/messages/event_branch_merge.py +3 -0
- infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
- infrahub/message_bus/operations/__init__.py +3 -5
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -3
- infrahub/message_bus/operations/check/repository.py +1 -1
- infrahub/message_bus/operations/event/branch.py +7 -3
- infrahub/message_bus/operations/event/schema.py +1 -1
- infrahub/message_bus/operations/finalize/validator.py +1 -1
- infrahub/message_bus/operations/git/file.py +2 -2
- infrahub/message_bus/operations/git/repository.py +1 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -2
- infrahub/message_bus/operations/requests/generator_definition.py +1 -1
- infrahub/message_bus/operations/requests/proposed_change.py +26 -11
- infrahub/message_bus/operations/requests/repository.py +2 -2
- infrahub/message_bus/operations/send/echo.py +1 -1
- infrahub/message_bus/types.py +1 -1
- infrahub/permissions/__init__.py +2 -1
- infrahub/permissions/types.py +26 -0
- infrahub/pools/prefix.py +29 -165
- infrahub/prefect_server/__init__.py +0 -0
- infrahub/prefect_server/app.py +18 -0
- infrahub/prefect_server/database.py +20 -0
- infrahub/prefect_server/events.py +28 -0
- infrahub/prefect_server/models.py +46 -0
- infrahub/proposed_change/models.py +15 -1
- infrahub/proposed_change/tasks.py +173 -35
- infrahub/pytest_plugin.py +4 -4
- infrahub/server.py +12 -11
- infrahub/services/__init__.py +147 -62
- infrahub/services/adapters/cache/__init__.py +7 -5
- infrahub/services/adapters/cache/nats.py +40 -22
- infrahub/services/adapters/cache/redis.py +0 -4
- infrahub/services/adapters/event/__init__.py +10 -18
- infrahub/services/adapters/http/__init__.py +0 -5
- infrahub/services/adapters/http/httpx.py +22 -15
- infrahub/services/adapters/message_bus/__init__.py +23 -6
- infrahub/services/adapters/message_bus/local.py +8 -6
- infrahub/services/adapters/message_bus/nats.py +12 -6
- infrahub/services/adapters/message_bus/rabbitmq.py +22 -9
- infrahub/services/adapters/workflow/__init__.py +11 -8
- infrahub/services/adapters/workflow/local.py +28 -7
- infrahub/services/adapters/workflow/worker.py +23 -7
- infrahub/services/component.py +38 -35
- infrahub/services/scheduler.py +32 -29
- infrahub/storage.py +2 -4
- infrahub/task_manager/constants.py +1 -1
- infrahub/task_manager/event.py +182 -0
- infrahub/task_manager/models.py +125 -1
- infrahub/task_manager/task.py +1 -1
- infrahub/tasks/artifact.py +14 -16
- infrahub/tasks/registry.py +1 -1
- infrahub/tasks/telemetry.py +13 -14
- infrahub/transformations/tasks.py +3 -5
- infrahub/trigger/__init__.py +0 -0
- infrahub/trigger/catalogue.py +15 -0
- infrahub/trigger/constants.py +9 -0
- infrahub/trigger/models.py +69 -0
- infrahub/trigger/tasks.py +85 -0
- infrahub/types.py +1 -1
- infrahub/utils.py +1 -1
- infrahub/webhook/constants.py +0 -2
- infrahub/webhook/models.py +8 -2
- infrahub/webhook/tasks.py +20 -73
- infrahub/webhook/triggers.py +20 -0
- infrahub/workers/infrahub_async.py +36 -25
- infrahub/workers/utils.py +63 -0
- infrahub/workflows/catalogue.py +13 -37
- infrahub/workflows/initialization.py +6 -8
- infrahub/workflows/models.py +3 -5
- infrahub/workflows/utils.py +1 -1
- infrahub_sdk/ctl/check.py +3 -3
- infrahub_sdk/ctl/cli_commands.py +11 -10
- infrahub_sdk/ctl/exceptions.py +0 -6
- infrahub_sdk/ctl/exporter.py +1 -1
- infrahub_sdk/ctl/generator.py +5 -5
- infrahub_sdk/ctl/importer.py +3 -2
- infrahub_sdk/ctl/menu.py +1 -1
- infrahub_sdk/ctl/object.py +1 -1
- infrahub_sdk/ctl/repository.py +23 -15
- infrahub_sdk/ctl/schema.py +2 -2
- infrahub_sdk/ctl/utils.py +4 -3
- infrahub_sdk/ctl/validate.py +2 -1
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +3 -0
- infrahub_sdk/node.py +2 -2
- infrahub_sdk/schema/__init__.py +14 -2
- infrahub_sdk/schema/main.py +7 -0
- infrahub_sdk/utils.py +11 -1
- infrahub_sdk/yaml.py +2 -3
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/METADATA +46 -12
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/RECORD +338 -321
- infrahub_testcontainers/container.py +14 -6
- infrahub_testcontainers/docker-compose.test.yml +24 -5
- infrahub_testcontainers/haproxy.cfg +43 -0
- infrahub_testcontainers/helpers.py +85 -1
- infrahub/core/branch/constants.py +0 -2
- infrahub/graphql/query.py +0 -52
- infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
- infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
- infrahub/schema/constants.py +0 -1
- infrahub/schema/tasks.py +0 -76
- infrahub/services/adapters/database/__init__.py +0 -9
- infrahub_sdk/ctl/_file.py +0 -13
- /infrahub/{schema → artifacts}/__init__.py +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/entry_points.txt +0 -0
|
@@ -6,6 +6,7 @@ from uuid import uuid4
|
|
|
6
6
|
|
|
7
7
|
from infrahub import lock
|
|
8
8
|
from infrahub.core.timestamp import Timestamp
|
|
9
|
+
from infrahub.exceptions import ValidationError
|
|
9
10
|
from infrahub.log import get_logger
|
|
10
11
|
|
|
11
12
|
from .model.path import (
|
|
@@ -29,7 +30,6 @@ if TYPE_CHECKING:
|
|
|
29
30
|
from .data_check_synchronizer import DiffDataCheckSynchronizer
|
|
30
31
|
from .enricher.aggregated import AggregatedDiffEnricher
|
|
31
32
|
from .enricher.labels import DiffLabelsEnricher
|
|
32
|
-
from .enricher.summary_counts import DiffSummaryCountsEnricher
|
|
33
33
|
from .repository.repository import DiffRepository
|
|
34
34
|
|
|
35
35
|
|
|
@@ -42,7 +42,7 @@ class EnrichedDiffRequest:
|
|
|
42
42
|
diff_branch: Branch
|
|
43
43
|
from_time: Timestamp
|
|
44
44
|
to_time: Timestamp
|
|
45
|
-
tracking_id: TrackingId
|
|
45
|
+
tracking_id: TrackingId
|
|
46
46
|
node_field_specifiers: dict[str, set[str]] = field(default_factory=dict)
|
|
47
47
|
|
|
48
48
|
def __repr__(self) -> str:
|
|
@@ -65,7 +65,6 @@ class DiffCoordinator:
|
|
|
65
65
|
diff_combiner: DiffCombiner,
|
|
66
66
|
conflicts_enricher: ConflictsEnricher,
|
|
67
67
|
labels_enricher: DiffLabelsEnricher,
|
|
68
|
-
summary_counts_enricher: DiffSummaryCountsEnricher,
|
|
69
68
|
data_check_synchronizer: DiffDataCheckSynchronizer,
|
|
70
69
|
conflict_transferer: DiffConflictTransferer,
|
|
71
70
|
) -> None:
|
|
@@ -75,7 +74,6 @@ class DiffCoordinator:
|
|
|
75
74
|
self.diff_combiner = diff_combiner
|
|
76
75
|
self.conflicts_enricher = conflicts_enricher
|
|
77
76
|
self.labels_enricher = labels_enricher
|
|
78
|
-
self.summary_counts_enricher = summary_counts_enricher
|
|
79
77
|
self.data_check_synchronizer = data_check_synchronizer
|
|
80
78
|
self.conflict_transferer = conflict_transferer
|
|
81
79
|
self.lock_registry = lock.registry
|
|
@@ -101,6 +99,8 @@ class DiffCoordinator:
|
|
|
101
99
|
to_timestamp = Timestamp(to_time)
|
|
102
100
|
else:
|
|
103
101
|
to_timestamp = Timestamp()
|
|
102
|
+
if not name:
|
|
103
|
+
raise ValidationError("diff with specified time range requires a name")
|
|
104
104
|
await self.create_or_update_arbitrary_timeframe_diff(
|
|
105
105
|
base_branch=base_branch,
|
|
106
106
|
diff_branch=diff_branch,
|
|
@@ -115,27 +115,7 @@ class DiffCoordinator:
|
|
|
115
115
|
lock_name += "__incremental"
|
|
116
116
|
return lock_name
|
|
117
117
|
|
|
118
|
-
async def
|
|
119
|
-
enriched_diff = await self.update_branch_diff(base_branch=base_branch, diff_branch=diff_branch)
|
|
120
|
-
if isinstance(enriched_diff, EnrichedDiffRoot):
|
|
121
|
-
return enriched_diff
|
|
122
|
-
return await self._finalize_diff_root_metadata(diff_root_metadata=enriched_diff)
|
|
123
|
-
|
|
124
|
-
async def _finalize_diff_root_metadata(self, diff_root_metadata: EnrichedDiffRootMetadata) -> EnrichedDiffRoot:
|
|
125
|
-
# if this is EnrichedDiffMetadata, we need to retrieve the full diff and set its metadata to match
|
|
126
|
-
full_enriched_diff = await self.diff_repo.get_one(
|
|
127
|
-
diff_branch_name=diff_root_metadata.diff_branch_name, diff_id=diff_root_metadata.uuid
|
|
128
|
-
)
|
|
129
|
-
full_enriched_diff.update_metadata(
|
|
130
|
-
from_time=diff_root_metadata.from_time,
|
|
131
|
-
to_time=diff_root_metadata.to_time,
|
|
132
|
-
tracking_id=diff_root_metadata.tracking_id,
|
|
133
|
-
)
|
|
134
|
-
return full_enriched_diff
|
|
135
|
-
|
|
136
|
-
async def update_branch_diff(
|
|
137
|
-
self, base_branch: Branch, diff_branch: Branch
|
|
138
|
-
) -> EnrichedDiffRoot | EnrichedDiffRootMetadata:
|
|
118
|
+
async def update_branch_diff(self, base_branch: Branch, diff_branch: Branch) -> EnrichedDiffRootMetadata:
|
|
139
119
|
log.info(f"Received request to update branch diff for {base_branch.name} - {diff_branch.name}")
|
|
140
120
|
incremental_lock_name = self._get_lock_name(
|
|
141
121
|
base_branch_name=base_branch.name, diff_branch_name=diff_branch.name, is_incremental=True
|
|
@@ -169,12 +149,6 @@ class DiffCoordinator:
|
|
|
169
149
|
tracking_id=tracking_id,
|
|
170
150
|
force_branch_refresh=False,
|
|
171
151
|
)
|
|
172
|
-
if not isinstance(enriched_diffs, EnrichedDiffs):
|
|
173
|
-
await self._update_core_data_checks(enriched_diff=enriched_diffs.diff_branch_diff)
|
|
174
|
-
return enriched_diffs.diff_branch_diff
|
|
175
|
-
|
|
176
|
-
await self.summary_counts_enricher.enrich(enriched_diff_root=enriched_diffs.base_branch_diff)
|
|
177
|
-
await self.summary_counts_enricher.enrich(enriched_diff_root=enriched_diffs.diff_branch_diff)
|
|
178
152
|
await self.diff_repo.save(enriched_diffs=enriched_diffs)
|
|
179
153
|
await self._update_core_data_checks(enriched_diff=enriched_diffs.diff_branch_diff)
|
|
180
154
|
log.info(f"Branch diff update complete for {base_branch.name} - {diff_branch.name}")
|
|
@@ -186,11 +160,9 @@ class DiffCoordinator:
|
|
|
186
160
|
diff_branch: Branch,
|
|
187
161
|
from_time: Timestamp,
|
|
188
162
|
to_time: Timestamp,
|
|
189
|
-
name: str
|
|
190
|
-
) ->
|
|
191
|
-
tracking_id =
|
|
192
|
-
if name:
|
|
193
|
-
tracking_id = NameTrackingId(name=name)
|
|
163
|
+
name: str,
|
|
164
|
+
) -> EnrichedDiffRootMetadata:
|
|
165
|
+
tracking_id = NameTrackingId(name=name)
|
|
194
166
|
general_lock_name = self._get_lock_name(
|
|
195
167
|
base_branch_name=base_branch.name, diff_branch_name=diff_branch.name, is_incremental=False
|
|
196
168
|
)
|
|
@@ -204,13 +176,7 @@ class DiffCoordinator:
|
|
|
204
176
|
tracking_id=tracking_id,
|
|
205
177
|
force_branch_refresh=False,
|
|
206
178
|
)
|
|
207
|
-
# metadata-only diff, so no nodes to enrich
|
|
208
|
-
if not isinstance(enriched_diffs, EnrichedDiffs):
|
|
209
|
-
await self._update_core_data_checks(enriched_diff=enriched_diffs.diff_branch_diff)
|
|
210
|
-
return await self._finalize_diff_root_metadata(diff_root_metadata=enriched_diffs.diff_branch_diff)
|
|
211
179
|
|
|
212
|
-
await self.summary_counts_enricher.enrich(enriched_diff_root=enriched_diffs.base_branch_diff)
|
|
213
|
-
await self.summary_counts_enricher.enrich(enriched_diff_root=enriched_diffs.diff_branch_diff)
|
|
214
180
|
await self.diff_repo.save(enriched_diffs=enriched_diffs)
|
|
215
181
|
await self._update_core_data_checks(enriched_diff=enriched_diffs.diff_branch_diff)
|
|
216
182
|
log.info(f"Arbitrary diff update complete for {base_branch.name} - {diff_branch.name}")
|
|
@@ -252,8 +218,6 @@ class DiffCoordinator:
|
|
|
252
218
|
earlier=current_branch_diff, later=enriched_diffs.diff_branch_diff
|
|
253
219
|
)
|
|
254
220
|
|
|
255
|
-
await self.summary_counts_enricher.enrich(enriched_diff_root=enriched_diffs.base_branch_diff)
|
|
256
|
-
await self.summary_counts_enricher.enrich(enriched_diff_root=enriched_diffs.diff_branch_diff)
|
|
257
221
|
await self.diff_repo.save(enriched_diffs=enriched_diffs)
|
|
258
222
|
await self._update_core_data_checks(enriched_diff=enriched_diffs.diff_branch_diff)
|
|
259
223
|
log.info(f"Diff recalculation complete for {base_branch.name} - {diff_branch.name}")
|
|
@@ -316,7 +280,7 @@ class DiffCoordinator:
|
|
|
316
280
|
diff_branch: Branch,
|
|
317
281
|
from_time: Timestamp,
|
|
318
282
|
to_time: Timestamp,
|
|
319
|
-
tracking_id: TrackingId
|
|
283
|
+
tracking_id: TrackingId,
|
|
320
284
|
force_branch_refresh: Literal[True] = ...,
|
|
321
285
|
) -> EnrichedDiffs: ...
|
|
322
286
|
|
|
@@ -327,7 +291,7 @@ class DiffCoordinator:
|
|
|
327
291
|
diff_branch: Branch,
|
|
328
292
|
from_time: Timestamp,
|
|
329
293
|
to_time: Timestamp,
|
|
330
|
-
tracking_id: TrackingId
|
|
294
|
+
tracking_id: TrackingId,
|
|
331
295
|
force_branch_refresh: Literal[False] = ...,
|
|
332
296
|
) -> EnrichedDiffs | EnrichedDiffsMetadata: ...
|
|
333
297
|
|
|
@@ -337,7 +301,7 @@ class DiffCoordinator:
|
|
|
337
301
|
diff_branch: Branch,
|
|
338
302
|
from_time: Timestamp,
|
|
339
303
|
to_time: Timestamp,
|
|
340
|
-
tracking_id: TrackingId
|
|
304
|
+
tracking_id: TrackingId,
|
|
341
305
|
force_branch_refresh: bool = False,
|
|
342
306
|
) -> EnrichedDiffs | EnrichedDiffsMetadata:
|
|
343
307
|
# start with empty diffs b/c we only care about their metadata for now, hydrate them with data as needed
|
|
@@ -346,6 +310,7 @@ class DiffCoordinator:
|
|
|
346
310
|
diff_branch_names=[diff_branch.name],
|
|
347
311
|
from_time=from_time,
|
|
348
312
|
to_time=to_time,
|
|
313
|
+
tracking_id=tracking_id,
|
|
349
314
|
)
|
|
350
315
|
aggregated_enriched_diffs = await self._aggregate_enriched_diffs(
|
|
351
316
|
diff_request=EnrichedDiffRequest(
|
|
@@ -357,22 +322,23 @@ class DiffCoordinator:
|
|
|
357
322
|
),
|
|
358
323
|
partial_enriched_diffs=diff_pairs_metadata if not force_branch_refresh else None,
|
|
359
324
|
)
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
325
|
+
diff_uuids_to_delete: list[str] = []
|
|
326
|
+
for diff_pair in diff_pairs_metadata:
|
|
327
|
+
if (
|
|
328
|
+
diff_pair.base_branch_diff.tracking_id == tracking_id
|
|
329
|
+
and diff_pair.base_branch_diff.uuid != aggregated_enriched_diffs.base_branch_diff.uuid
|
|
330
|
+
and diff_pair.base_branch_diff.exists_on_database
|
|
331
|
+
):
|
|
332
|
+
diff_uuids_to_delete.append(diff_pair.base_branch_diff.uuid)
|
|
333
|
+
if (
|
|
334
|
+
diff_pair.diff_branch_diff.tracking_id == tracking_id
|
|
335
|
+
and diff_pair.diff_branch_diff.uuid != aggregated_enriched_diffs.diff_branch_diff.uuid
|
|
336
|
+
and diff_pair.diff_branch_diff.exists_on_database
|
|
337
|
+
):
|
|
338
|
+
diff_uuids_to_delete.append(diff_pair.diff_branch_diff.uuid)
|
|
339
|
+
|
|
340
|
+
if diff_uuids_to_delete:
|
|
341
|
+
await self.diff_repo.delete_diff_roots(diff_root_uuids=diff_uuids_to_delete)
|
|
376
342
|
|
|
377
343
|
# this is an EnrichedDiffsMetadata, so there are no nodes to enrich
|
|
378
344
|
if not isinstance(aggregated_enriched_diffs, EnrichedDiffs):
|
|
@@ -459,6 +425,7 @@ class DiffCoordinator:
|
|
|
459
425
|
diff_branch=diff_request.diff_branch,
|
|
460
426
|
from_time=current_time,
|
|
461
427
|
to_time=end_time,
|
|
428
|
+
tracking_id=diff_request.tracking_id,
|
|
462
429
|
)
|
|
463
430
|
)
|
|
464
431
|
current_time = end_time
|
|
@@ -481,7 +448,6 @@ class DiffCoordinator:
|
|
|
481
448
|
aggregated_enriched_diffs.update_metadata(
|
|
482
449
|
from_time=diff_request.from_time, to_time=diff_request.to_time, tracking_id=diff_request.tracking_id
|
|
483
450
|
)
|
|
484
|
-
aggregated_enriched_diffs.set_fresh_uuids()
|
|
485
451
|
return aggregated_enriched_diffs
|
|
486
452
|
|
|
487
453
|
async def _concatenate_diffs_and_requests(
|
|
@@ -498,6 +464,7 @@ class DiffCoordinator:
|
|
|
498
464
|
meaning multiple diffs (some that may have been freshly calculated) were combined
|
|
499
465
|
"""
|
|
500
466
|
previous_diff_pair: EnrichedDiffs | EnrichedDiffsMetadata | None = None
|
|
467
|
+
updated_node_uuids: set[str] = set()
|
|
501
468
|
for diff_or_request in diff_or_request_list:
|
|
502
469
|
if isinstance(diff_or_request, EnrichedDiffRequest):
|
|
503
470
|
if previous_diff_pair:
|
|
@@ -508,9 +475,12 @@ class DiffCoordinator:
|
|
|
508
475
|
log.info(f"Number node field specifiers: {len(node_field_specifiers)}")
|
|
509
476
|
diff_or_request.node_field_specifiers = node_field_specifiers
|
|
510
477
|
is_incremental_diff = diff_or_request.from_time != full_diff_request.from_time
|
|
511
|
-
|
|
478
|
+
calculated_diff = await self._calculate_enriched_diff(
|
|
512
479
|
diff_request=diff_or_request, is_incremental_diff=is_incremental_diff
|
|
513
480
|
)
|
|
481
|
+
updated_node_uuids |= calculated_diff.base_node_uuids
|
|
482
|
+
updated_node_uuids |= calculated_diff.branch_node_uuids
|
|
483
|
+
single_enriched_diffs: EnrichedDiffs | EnrichedDiffsMetadata = calculated_diff
|
|
514
484
|
|
|
515
485
|
elif isinstance(diff_or_request, EnrichedDiffsMetadata):
|
|
516
486
|
single_enriched_diffs = diff_or_request
|
|
@@ -522,13 +492,20 @@ class DiffCoordinator:
|
|
|
522
492
|
continue
|
|
523
493
|
|
|
524
494
|
log.info("Combining diffs...")
|
|
525
|
-
previous_diff_pair = await self._combine_diffs(
|
|
495
|
+
previous_diff_pair = await self._combine_diffs(
|
|
496
|
+
earlier=previous_diff_pair,
|
|
497
|
+
later=single_enriched_diffs,
|
|
498
|
+
node_uuids=updated_node_uuids,
|
|
499
|
+
)
|
|
526
500
|
log.info("Diffs combined.")
|
|
527
501
|
|
|
528
502
|
return previous_diff_pair
|
|
529
503
|
|
|
530
504
|
async def _combine_diffs(
|
|
531
|
-
self,
|
|
505
|
+
self,
|
|
506
|
+
earlier: EnrichedDiffs | EnrichedDiffsMetadata,
|
|
507
|
+
later: EnrichedDiffs | EnrichedDiffsMetadata,
|
|
508
|
+
node_uuids: set[str],
|
|
532
509
|
) -> EnrichedDiffs | EnrichedDiffsMetadata:
|
|
533
510
|
log.info(f"Earlier diff to combine: {earlier!r}")
|
|
534
511
|
log.info(f"Later diff to combine: {later!r}")
|
|
@@ -545,11 +522,11 @@ class DiffCoordinator:
|
|
|
545
522
|
# hydrate the diffs to combine, if necessary
|
|
546
523
|
if not isinstance(earlier, EnrichedDiffs):
|
|
547
524
|
log.info("Hydrating earlier diff...")
|
|
548
|
-
earlier = await self.diff_repo.hydrate_diff_pair(enriched_diffs_metadata=earlier)
|
|
525
|
+
earlier = await self.diff_repo.hydrate_diff_pair(enriched_diffs_metadata=earlier, node_uuids=node_uuids)
|
|
549
526
|
log.info("Earlier diff hydrated.")
|
|
550
527
|
if not isinstance(later, EnrichedDiffs):
|
|
551
528
|
log.info("Hydrating later diff...")
|
|
552
|
-
later = await self.diff_repo.hydrate_diff_pair(enriched_diffs_metadata=later)
|
|
529
|
+
later = await self.diff_repo.hydrate_diff_pair(enriched_diffs_metadata=later, node_uuids=node_uuids)
|
|
553
530
|
log.info("Later diff hydrated.")
|
|
554
531
|
|
|
555
532
|
return await self.diff_combiner.combine(earlier_diffs=earlier, later_diffs=later)
|
|
@@ -570,6 +547,8 @@ class DiffCoordinator:
|
|
|
570
547
|
previous_node_specifiers=diff_request.node_field_specifiers,
|
|
571
548
|
)
|
|
572
549
|
log.info("Calculation complete. Enriching diff...")
|
|
573
|
-
enriched_diff_pair = await self.diff_enricher.enrich(
|
|
550
|
+
enriched_diff_pair = await self.diff_enricher.enrich(
|
|
551
|
+
calculated_diffs=calculated_diff_pair, tracking_id=diff_request.tracking_id
|
|
552
|
+
)
|
|
574
553
|
log.info("Enrichment complete")
|
|
575
554
|
return enriched_diff_pair
|
|
@@ -10,7 +10,13 @@ from infrahub.proposed_change.constants import ProposedChangeState
|
|
|
10
10
|
|
|
11
11
|
from .conflicts_extractor import DiffConflictsExtractor
|
|
12
12
|
from .model.diff import DataConflict
|
|
13
|
-
from .model.path import
|
|
13
|
+
from .model.path import (
|
|
14
|
+
ConflictSelection,
|
|
15
|
+
EnrichedDiffConflict,
|
|
16
|
+
EnrichedDiffNode,
|
|
17
|
+
EnrichedDiffRoot,
|
|
18
|
+
EnrichedDiffRootMetadata,
|
|
19
|
+
)
|
|
14
20
|
from .repository.repository import DiffRepository
|
|
15
21
|
|
|
16
22
|
|
|
@@ -54,20 +60,31 @@ class DiffDataCheckSynchronizer:
|
|
|
54
60
|
if not proposed_changes:
|
|
55
61
|
return []
|
|
56
62
|
all_data_checks = []
|
|
63
|
+
enriched_diff_all_conflicts: EnrichedDiffRoot | None = None
|
|
57
64
|
for pc in proposed_changes:
|
|
58
65
|
# if the enriched_diff is EnrichedDiffRootMetadata, then it has no new data in it
|
|
59
66
|
if not isinstance(enriched_diff, EnrichedDiffRoot):
|
|
60
67
|
has_validator = bool(await self.conflict_recorder.get_validator(proposed_change=pc))
|
|
61
|
-
# if this pc
|
|
68
|
+
# if this pc has a validator, then the conflicts for this diff have already been synchronized and we can be done
|
|
62
69
|
if has_validator:
|
|
63
70
|
continue
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
|
|
72
|
+
# we need to get the conflicts for this diff from the database b/c `enriched_diff` might not include all nodes
|
|
73
|
+
if not enriched_diff_all_conflicts:
|
|
74
|
+
retrieved_diff_conflicts_only = await self.diff_repository.get_one(
|
|
75
|
+
diff_branch_name=enriched_diff.diff_branch_name,
|
|
76
|
+
diff_id=enriched_diff.uuid,
|
|
77
|
+
filters={"only_conflicted": True},
|
|
67
78
|
)
|
|
79
|
+
enriched_diff_all_conflicts = retrieved_diff_conflicts_only
|
|
80
|
+
# if `enriched_diff` is an EnrichedDiffRootsMetadata, then there have been no changes to the diff and
|
|
81
|
+
# we can use `retrieved_diff_conflicts_only`
|
|
82
|
+
# otherwise, we need to combine the changes to `enriched_diff` with the conflicts from the database
|
|
83
|
+
if isinstance(enriched_diff, EnrichedDiffRoot):
|
|
84
|
+
self._update_diff_conflicts(updated_diff=enriched_diff, retrieved_diff=enriched_diff_all_conflicts)
|
|
68
85
|
|
|
69
|
-
data_conflicts = await self._get_data_conflicts(enriched_diff=
|
|
70
|
-
enriched_conflicts_map = self._get_enriched_conflicts_map(enriched_diff=
|
|
86
|
+
data_conflicts = await self._get_data_conflicts(enriched_diff=enriched_diff_all_conflicts)
|
|
87
|
+
enriched_conflicts_map = self._get_enriched_conflicts_map(enriched_diff=enriched_diff_all_conflicts)
|
|
71
88
|
core_data_checks = await self.conflict_recorder.record_conflicts(
|
|
72
89
|
proposed_change_id=pc.get_id(), conflicts=data_conflicts
|
|
73
90
|
)
|
|
@@ -95,3 +112,65 @@ class DiffDataCheckSynchronizer:
|
|
|
95
112
|
if enriched_conflict.selected_branch is ConflictSelection.DIFF_BRANCH:
|
|
96
113
|
return BranchConflictKeep.SOURCE
|
|
97
114
|
return None
|
|
115
|
+
|
|
116
|
+
def _update_diff_conflicts(self, updated_diff: EnrichedDiffRoot, retrieved_diff: EnrichedDiffRoot) -> None:
|
|
117
|
+
for updated_node in updated_diff.nodes:
|
|
118
|
+
try:
|
|
119
|
+
retrieved_node = retrieved_diff.get_node(node_uuid=updated_node.uuid)
|
|
120
|
+
except ValueError:
|
|
121
|
+
retrieved_node = None
|
|
122
|
+
if not retrieved_node:
|
|
123
|
+
retrieved_diff.nodes.add(updated_node)
|
|
124
|
+
continue
|
|
125
|
+
retrieved_node.conflict = updated_node.conflict
|
|
126
|
+
self._update_diff_attr_conflicts(updated_node=updated_node, retrieved_node=retrieved_node)
|
|
127
|
+
self._update_diff_relationship_conflicts(updated_node=updated_node, retrieved_node=retrieved_node)
|
|
128
|
+
|
|
129
|
+
def _update_diff_attr_conflicts(self, updated_node: EnrichedDiffNode, retrieved_node: EnrichedDiffNode) -> None:
|
|
130
|
+
for updated_attr in updated_node.attributes:
|
|
131
|
+
try:
|
|
132
|
+
retrieved_attr = retrieved_node.get_attribute(name=updated_attr.name)
|
|
133
|
+
except ValueError:
|
|
134
|
+
retrieved_attr = None
|
|
135
|
+
if not retrieved_attr:
|
|
136
|
+
retrieved_node.attributes.add(updated_attr)
|
|
137
|
+
continue
|
|
138
|
+
for updated_prop in updated_attr.properties:
|
|
139
|
+
try:
|
|
140
|
+
retrieved_prop = retrieved_attr.get_property(updated_prop.property_type)
|
|
141
|
+
except ValueError:
|
|
142
|
+
retrieved_prop = None
|
|
143
|
+
if not retrieved_prop:
|
|
144
|
+
retrieved_attr.properties.add(updated_prop)
|
|
145
|
+
continue
|
|
146
|
+
retrieved_prop.conflict = updated_prop.conflict
|
|
147
|
+
|
|
148
|
+
def _update_diff_relationship_conflicts(
|
|
149
|
+
self, updated_node: EnrichedDiffNode, retrieved_node: EnrichedDiffNode
|
|
150
|
+
) -> None:
|
|
151
|
+
for updated_rel in updated_node.relationships:
|
|
152
|
+
try:
|
|
153
|
+
retrieved_rel = retrieved_node.get_relationship(name=updated_rel.name)
|
|
154
|
+
except ValueError:
|
|
155
|
+
retrieved_rel = None
|
|
156
|
+
if not retrieved_rel:
|
|
157
|
+
retrieved_node.relationships.add(updated_rel)
|
|
158
|
+
continue
|
|
159
|
+
for updated_element in updated_rel.relationships:
|
|
160
|
+
try:
|
|
161
|
+
retrieved_element = retrieved_rel.get_element(updated_element.peer_id)
|
|
162
|
+
except ValueError:
|
|
163
|
+
retrieved_element = None
|
|
164
|
+
if not retrieved_element:
|
|
165
|
+
retrieved_rel.relationships.add(updated_element)
|
|
166
|
+
continue
|
|
167
|
+
retrieved_element.conflict = updated_element.conflict
|
|
168
|
+
for updated_prop in updated_element.properties:
|
|
169
|
+
try:
|
|
170
|
+
retrieved_prop = retrieved_element.get_property(updated_prop.property_type)
|
|
171
|
+
except ValueError:
|
|
172
|
+
retrieved_prop = None
|
|
173
|
+
if not retrieved_prop:
|
|
174
|
+
retrieved_element.properties.add(updated_prop)
|
|
175
|
+
continue
|
|
176
|
+
retrieved_prop.conflict = updated_prop.conflict
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from ..model.path import CalculatedDiffs, EnrichedDiffs
|
|
1
|
+
from ..model.path import CalculatedDiffs, EnrichedDiffs, TrackingId
|
|
2
2
|
from .interface import DiffEnricherInterface
|
|
3
3
|
|
|
4
4
|
|
|
@@ -6,8 +6,8 @@ class AggregatedDiffEnricher:
|
|
|
6
6
|
def __init__(self, enrichers: list[DiffEnricherInterface]) -> None:
|
|
7
7
|
self.enrichers = enrichers
|
|
8
8
|
|
|
9
|
-
async def enrich(self, calculated_diffs: CalculatedDiffs) -> EnrichedDiffs:
|
|
10
|
-
enriched_diffs = EnrichedDiffs.from_calculated_diffs(calculated_diffs=calculated_diffs)
|
|
9
|
+
async def enrich(self, calculated_diffs: CalculatedDiffs, tracking_id: TrackingId) -> EnrichedDiffs:
|
|
10
|
+
enriched_diffs = EnrichedDiffs.from_calculated_diffs(calculated_diffs=calculated_diffs, tracking_id=tracking_id)
|
|
11
11
|
|
|
12
12
|
for enricher in self.enrichers:
|
|
13
13
|
await enricher.enrich(enriched_diff_root=enriched_diffs.base_branch_diff, calculated_diffs=calculated_diffs)
|
|
@@ -32,7 +32,7 @@ class DiffCardinalityOneEnricher(DiffEnricherInterface):
|
|
|
32
32
|
self.db = db
|
|
33
33
|
self._node_schema_map: dict[str, MainSchemaTypes] = {}
|
|
34
34
|
|
|
35
|
-
async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None:
|
|
35
|
+
async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None: # noqa: ARG002
|
|
36
36
|
self._node_schema_map = {}
|
|
37
37
|
for diff_node in enriched_diff_root.nodes:
|
|
38
38
|
for relationship_group in diff_node.relationships:
|
|
@@ -103,14 +103,9 @@ class DiffCardinalityOneEnricher(DiffEnricherInterface):
|
|
|
103
103
|
)
|
|
104
104
|
)
|
|
105
105
|
if consolidated_properties:
|
|
106
|
-
element_timestamps = {element.changed_at for element in diff_relationship.relationships}
|
|
107
106
|
element_actions = {element.action for element in diff_relationship.relationships}
|
|
108
107
|
# check if this is a simultaneous update
|
|
109
|
-
if (
|
|
110
|
-
len(diff_relationship.relationships) > 1
|
|
111
|
-
and len(element_timestamps) == 1
|
|
112
|
-
and {DiffAction.REMOVED, DiffAction.ADDED} <= element_actions
|
|
113
|
-
):
|
|
108
|
+
if len(diff_relationship.relationships) > 1 and {DiffAction.REMOVED, DiffAction.ADDED} <= element_actions:
|
|
114
109
|
latest_element = [
|
|
115
110
|
element for element in diff_relationship.relationships if element.action is DiffAction.ADDED
|
|
116
111
|
][0]
|
|
@@ -5,7 +5,7 @@ from infrahub.core.constants import RelationshipHierarchyDirection, Relationship
|
|
|
5
5
|
from infrahub.core.constants.database import DatabaseEdgeType
|
|
6
6
|
from infrahub.core.query.node import NodeGetHierarchyQuery
|
|
7
7
|
from infrahub.core.query.relationship import RelationshipGetPeerQuery, RelationshipPeerData
|
|
8
|
-
from infrahub.core.schema import ProfileSchema
|
|
8
|
+
from infrahub.core.schema import ProfileSchema, TemplateSchema
|
|
9
9
|
from infrahub.database import InfrahubDatabase
|
|
10
10
|
|
|
11
11
|
from ..model.path import (
|
|
@@ -22,7 +22,9 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
22
22
|
self.db = db
|
|
23
23
|
|
|
24
24
|
async def enrich(
|
|
25
|
-
self,
|
|
25
|
+
self,
|
|
26
|
+
enriched_diff_root: EnrichedDiffRoot,
|
|
27
|
+
calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
|
|
26
28
|
) -> None:
|
|
27
29
|
# A hierarchy can be defined in 2 ways
|
|
28
30
|
# - A node has a relationship of kind parent
|
|
@@ -36,7 +38,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
36
38
|
name=node.kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
|
|
37
39
|
)
|
|
38
40
|
|
|
39
|
-
if isinstance(schema_node, ProfileSchema):
|
|
41
|
+
if isinstance(schema_node, ProfileSchema | TemplateSchema):
|
|
40
42
|
continue
|
|
41
43
|
|
|
42
44
|
if schema_node.has_parent_relationship:
|
|
@@ -154,10 +154,20 @@ class DiffLabelsEnricher(DiffEnricherInterface):
|
|
|
154
154
|
for node in enriched_diff.nodes:
|
|
155
155
|
if not node.relationships:
|
|
156
156
|
continue
|
|
157
|
-
|
|
157
|
+
|
|
158
|
+
node_schema = self.db.schema.get(name=node.kind, branch=enriched_diff.diff_branch_name, duplicate=False)
|
|
159
|
+
alternate_node_schema = None
|
|
160
|
+
if enriched_diff.diff_branch_name != enriched_diff.base_branch_name and self.db.schema.has(
|
|
161
|
+
name=node.kind, branch=enriched_diff.base_branch_name
|
|
162
|
+
):
|
|
163
|
+
alternate_node_schema = self.db.schema.get(
|
|
164
|
+
name=node.kind, branch=enriched_diff.base_branch_name, duplicate=False
|
|
165
|
+
)
|
|
158
166
|
for relationship_diff in node.relationships:
|
|
159
|
-
relationship_schema = node_schema.
|
|
160
|
-
|
|
167
|
+
relationship_schema = node_schema.get_relationship_or_none(name=relationship_diff.name)
|
|
168
|
+
if not relationship_schema and alternate_node_schema:
|
|
169
|
+
relationship_schema = alternate_node_schema.get_relationship_or_none(name=relationship_diff.name)
|
|
170
|
+
relationship_diff.label = relationship_schema.label or "" if relationship_schema else ""
|
|
161
171
|
|
|
162
172
|
async def _get_display_label_map(
|
|
163
173
|
self, display_label_requests: set[DisplayLabelRequest]
|
|
@@ -181,7 +191,7 @@ class DiffLabelsEnricher(DiffEnricherInterface):
|
|
|
181
191
|
async def enrich(
|
|
182
192
|
self,
|
|
183
193
|
enriched_diff_root: EnrichedDiffRoot,
|
|
184
|
-
calculated_diffs: CalculatedDiffs | None = None,
|
|
194
|
+
calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
|
|
185
195
|
conflicts_only: bool = False,
|
|
186
196
|
) -> None:
|
|
187
197
|
self._base_branch_name = enriched_diff_root.base_branch_name
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from infrahub.core.constants import PathType
|
|
1
|
+
from infrahub.core.constants import PathType
|
|
2
2
|
from infrahub.core.path import DataPath
|
|
3
3
|
from infrahub.database import InfrahubDatabase
|
|
4
4
|
|
|
@@ -19,7 +19,7 @@ class DiffPathIdentifierEnricher(DiffEnricherInterface):
|
|
|
19
19
|
raise RuntimeError("diff_branch_name not set")
|
|
20
20
|
return self._diff_branch_name
|
|
21
21
|
|
|
22
|
-
async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None:
|
|
22
|
+
async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None: # noqa: ARG002
|
|
23
23
|
self._diff_branch_name = enriched_diff_root.diff_branch_name
|
|
24
24
|
for node in enriched_diff_root.nodes:
|
|
25
25
|
node_path = DataPath(
|
|
@@ -44,14 +44,8 @@ class DiffPathIdentifierEnricher(DiffEnricherInterface):
|
|
|
44
44
|
attribute_property.path_identifier = property_path.get_path()
|
|
45
45
|
if not node.relationships:
|
|
46
46
|
continue
|
|
47
|
-
node_schema = self.db.schema.get(name=node.kind, branch=self.diff_branch_name, duplicate=False)
|
|
48
47
|
for relationship in node.relationships:
|
|
49
|
-
|
|
50
|
-
path_type = (
|
|
51
|
-
PathType.RELATIONSHIP_ONE
|
|
52
|
-
if relationship_schema.cardinality is RelationshipCardinality.ONE
|
|
53
|
-
else PathType.RELATIONSHIP_MANY
|
|
54
|
-
)
|
|
48
|
+
path_type = PathType.from_relationship(relationship.cardinality)
|
|
55
49
|
relationship_path = DataPath(
|
|
56
50
|
branch=enriched_diff_root.diff_branch_name,
|
|
57
51
|
path_type=path_type,
|
|
@@ -17,7 +17,9 @@ from .interface import DiffEnricherInterface
|
|
|
17
17
|
|
|
18
18
|
class DiffSummaryCountsEnricher(DiffEnricherInterface):
|
|
19
19
|
async def enrich(
|
|
20
|
-
self,
|
|
20
|
+
self,
|
|
21
|
+
enriched_diff_root: EnrichedDiffRoot,
|
|
22
|
+
calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
|
|
21
23
|
) -> None:
|
|
22
24
|
self._add_root_summaries(diff_root=enriched_diff_root)
|
|
23
25
|
|
|
@@ -9,6 +9,7 @@ from infrahub.log import get_logger
|
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
11
|
from infrahub.core.branch import Branch
|
|
12
|
+
from infrahub.core.diff.model.path import EnrichedDiffRoot
|
|
12
13
|
from infrahub.core.diff.repository.repository import DiffRepository
|
|
13
14
|
from infrahub.core.timestamp import Timestamp
|
|
14
15
|
from infrahub.database import InfrahubDatabase
|
|
@@ -33,14 +34,16 @@ class DiffMerger:
|
|
|
33
34
|
self.diff_repository = diff_repository
|
|
34
35
|
self.serializer = serializer
|
|
35
36
|
|
|
36
|
-
async def merge_graph(self, at: Timestamp) ->
|
|
37
|
+
async def merge_graph(self, at: Timestamp) -> EnrichedDiffRoot:
|
|
38
|
+
tracking_id = BranchTrackingId(name=self.source_branch.name)
|
|
37
39
|
enriched_diffs = await self.diff_repository.get_roots_metadata(
|
|
38
|
-
diff_branch_names=[self.source_branch.name],
|
|
40
|
+
diff_branch_names=[self.source_branch.name],
|
|
41
|
+
base_branch_names=[self.destination_branch.name],
|
|
42
|
+
tracking_id=tracking_id,
|
|
39
43
|
)
|
|
40
44
|
latest_diff = None
|
|
41
|
-
tracking_id = BranchTrackingId(name=self.source_branch.name)
|
|
42
45
|
for diff in enriched_diffs:
|
|
43
|
-
if latest_diff is None or (diff.
|
|
46
|
+
if latest_diff is None or (diff.to_time > latest_diff.to_time):
|
|
44
47
|
latest_diff = diff
|
|
45
48
|
if latest_diff is None:
|
|
46
49
|
raise RuntimeError(f"Missing diff for branch {self.source_branch.name}")
|
|
@@ -75,6 +78,7 @@ class DiffMerger:
|
|
|
75
78
|
self.source_branch.branched_from = at.to_string()
|
|
76
79
|
await self.source_branch.save(db=self.db)
|
|
77
80
|
registry.branch[self.source_branch.name] = self.source_branch
|
|
81
|
+
return enriched_diff
|
|
78
82
|
|
|
79
83
|
async def rollback(self, at: Timestamp) -> None:
|
|
80
84
|
rollback_query = await DiffMergeRollbackQuery.init(
|