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
|
@@ -28,7 +28,6 @@ from .model.path import (
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
from infrahub.core.branch import Branch
|
|
30
30
|
from infrahub.core.query import QueryResult
|
|
31
|
-
from infrahub.core.schema import MainSchemaTypes
|
|
32
31
|
from infrahub.core.schema.manager import SchemaManager
|
|
33
32
|
from infrahub.core.schema.relationship_schema import RelationshipSchema
|
|
34
33
|
|
|
@@ -397,8 +396,12 @@ class DiffNodeIntermediate(TrackedStatusUpdates):
|
|
|
397
396
|
force_action: DiffAction | None
|
|
398
397
|
uuid: str
|
|
399
398
|
kind: str
|
|
399
|
+
db_id: str
|
|
400
|
+
from_time: Timestamp
|
|
401
|
+
status: RelationshipStatus
|
|
400
402
|
attributes_by_name: dict[str, DiffAttributeIntermediate] = field(default_factory=dict)
|
|
401
|
-
|
|
403
|
+
# {(name, identifier): DiffRelationshipIntermediate}
|
|
404
|
+
relationships_by_identifier: dict[tuple[str, str], DiffRelationshipIntermediate] = field(default_factory=dict)
|
|
402
405
|
|
|
403
406
|
def to_diff_node(self, from_time: Timestamp, include_unchanged: bool) -> DiffNode:
|
|
404
407
|
attributes = []
|
|
@@ -408,7 +411,7 @@ class DiffNodeIntermediate(TrackedStatusUpdates):
|
|
|
408
411
|
attributes.append(diff_attr)
|
|
409
412
|
action, changed_at = self.get_action_and_timestamp(from_time=from_time)
|
|
410
413
|
relationships = []
|
|
411
|
-
for rel in self.
|
|
414
|
+
for rel in self.relationships_by_identifier.values():
|
|
412
415
|
diff_rel = rel.to_diff_relationship(include_unchanged=include_unchanged)
|
|
413
416
|
if include_unchanged or diff_rel.action is not DiffAction.UNCHANGED:
|
|
414
417
|
relationships.append(diff_rel)
|
|
@@ -431,7 +434,7 @@ class DiffNodeIntermediate(TrackedStatusUpdates):
|
|
|
431
434
|
|
|
432
435
|
@property
|
|
433
436
|
def is_empty(self) -> bool:
|
|
434
|
-
return len(self.attributes_by_name) == 0 and len(self.
|
|
437
|
+
return len(self.attributes_by_name) == 0 and len(self.relationships_by_identifier) == 0
|
|
435
438
|
|
|
436
439
|
|
|
437
440
|
@dataclass
|
|
@@ -495,7 +498,7 @@ class DiffQueryParser:
|
|
|
495
498
|
for node in diff_root.nodes_by_id.values():
|
|
496
499
|
for attribute_name in node.attributes_by_name:
|
|
497
500
|
node_field_specifiers_map[node.uuid].add(attribute_name)
|
|
498
|
-
for relationship_diff in node.
|
|
501
|
+
for relationship_diff in node.relationships_by_identifier.values():
|
|
499
502
|
node_field_specifiers_map[node.uuid].add(relationship_diff.identifier)
|
|
500
503
|
return node_field_specifiers_map
|
|
501
504
|
|
|
@@ -567,35 +570,53 @@ class DiffQueryParser:
|
|
|
567
570
|
diff_root.nodes_by_id[node_id] = DiffNodeIntermediate(
|
|
568
571
|
uuid=node_id,
|
|
569
572
|
kind=database_path.node_kind,
|
|
573
|
+
db_id=database_path.node_db_id,
|
|
574
|
+
from_time=database_path.node_changed_at,
|
|
575
|
+
status=database_path.node_status,
|
|
570
576
|
force_action=DiffAction.UPDATED
|
|
571
577
|
if database_path.node_branch_support is BranchSupportType.AGNOSTIC
|
|
572
578
|
else None,
|
|
573
579
|
)
|
|
574
580
|
diff_node = diff_root.nodes_by_id[node_id]
|
|
581
|
+
# special handling for nodes that have their kind updated, which results in 2 nodes with the same uuid
|
|
582
|
+
if diff_node.db_id != database_path.node_db_id and (
|
|
583
|
+
database_path.node_changed_at > diff_node.from_time
|
|
584
|
+
or (
|
|
585
|
+
database_path.node_changed_at >= diff_node.from_time
|
|
586
|
+
and (diff_node.status, database_path.node_status)
|
|
587
|
+
== (RelationshipStatus.DELETED, RelationshipStatus.ACTIVE)
|
|
588
|
+
)
|
|
589
|
+
):
|
|
590
|
+
diff_node.kind = database_path.node_kind
|
|
591
|
+
diff_node.db_id = database_path.node_db_id
|
|
592
|
+
diff_node.from_time = database_path.node_changed_at
|
|
593
|
+
diff_node.status = database_path.node_status
|
|
575
594
|
diff_node.track_database_path(database_path=database_path)
|
|
576
595
|
return diff_node
|
|
577
596
|
|
|
578
|
-
def _get_relationship_schema(
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
597
|
+
def _get_relationship_schema(self, database_path: DatabasePath) -> RelationshipSchema | None:
|
|
598
|
+
branches_to_check = [database_path.deepest_branch]
|
|
599
|
+
if database_path.deepest_branch == self.diff_branch_name:
|
|
600
|
+
branches_to_check.append(self.base_branch_name)
|
|
601
|
+
for schema_branch_name in branches_to_check:
|
|
602
|
+
node_schema = self.schema_manager.get(
|
|
603
|
+
name=database_path.node_kind, branch=schema_branch_name, duplicate=False
|
|
604
|
+
)
|
|
605
|
+
relationship_schemas = node_schema.get_relationships_by_identifier(id=database_path.attribute_name)
|
|
606
|
+
if len(relationship_schemas) == 1:
|
|
607
|
+
return relationship_schemas[0]
|
|
608
|
+
possible_path_directions = database_path.possible_relationship_directions
|
|
609
|
+
for rel_schema in relationship_schemas:
|
|
610
|
+
if rel_schema.direction in possible_path_directions:
|
|
611
|
+
return rel_schema
|
|
588
612
|
return None
|
|
589
613
|
|
|
590
614
|
def _update_attribute_level(self, database_path: DatabasePath, diff_node: DiffNodeIntermediate) -> None:
|
|
591
|
-
node_schema = self.schema_manager.get(
|
|
592
|
-
name=database_path.node_kind, branch=database_path.deepest_branch, duplicate=False
|
|
593
|
-
)
|
|
594
615
|
if "Attribute" in database_path.attribute_node.labels:
|
|
595
616
|
diff_attribute = self._get_diff_attribute(database_path=database_path, diff_node=diff_node)
|
|
596
617
|
self._update_attribute_property(database_path=database_path, diff_attribute=diff_attribute)
|
|
597
618
|
return
|
|
598
|
-
relationship_schema = self._get_relationship_schema(database_path=database_path
|
|
619
|
+
relationship_schema = self._get_relationship_schema(database_path=database_path)
|
|
599
620
|
if not relationship_schema:
|
|
600
621
|
return
|
|
601
622
|
diff_relationship = self._get_diff_relationship(
|
|
@@ -649,7 +670,9 @@ class DiffQueryParser:
|
|
|
649
670
|
relationship_schema: RelationshipSchema,
|
|
650
671
|
database_path: DatabasePath,
|
|
651
672
|
) -> DiffRelationshipIntermediate:
|
|
652
|
-
diff_relationship = diff_node.
|
|
673
|
+
diff_relationship = diff_node.relationships_by_identifier.get(
|
|
674
|
+
(relationship_schema.name, relationship_schema.get_identifier())
|
|
675
|
+
)
|
|
653
676
|
if not diff_relationship:
|
|
654
677
|
branch_name = database_path.deepest_branch
|
|
655
678
|
from_time = self.from_time
|
|
@@ -663,7 +686,9 @@ class DiffQueryParser:
|
|
|
663
686
|
identifier=relationship_schema.get_identifier(),
|
|
664
687
|
from_time=from_time,
|
|
665
688
|
)
|
|
666
|
-
diff_node.
|
|
689
|
+
diff_node.relationships_by_identifier[relationship_schema.name, relationship_schema.get_identifier()] = (
|
|
690
|
+
diff_relationship
|
|
691
|
+
)
|
|
667
692
|
return diff_relationship
|
|
668
693
|
|
|
669
694
|
def _apply_base_branch_previous_values(self) -> None:
|
|
@@ -700,8 +725,8 @@ class DiffQueryParser:
|
|
|
700
725
|
def _apply_relationship_previous_values(
|
|
701
726
|
self, diff_node: DiffNodeIntermediate, base_diff_node: DiffNodeIntermediate
|
|
702
727
|
) -> None:
|
|
703
|
-
for
|
|
704
|
-
base_diff_relationship = base_diff_node.
|
|
728
|
+
for relationship_key, diff_relationship in diff_node.relationships_by_identifier.items():
|
|
729
|
+
base_diff_relationship = base_diff_node.relationships_by_identifier.get(relationship_key)
|
|
705
730
|
if not base_diff_relationship:
|
|
706
731
|
continue
|
|
707
732
|
for db_id, property_set in diff_relationship.properties_by_db_id.items():
|
|
@@ -754,7 +779,7 @@ class DiffQueryParser:
|
|
|
754
779
|
continue
|
|
755
780
|
if ordered_diff_values[-1].changed_at >= self.diff_branched_from_time:
|
|
756
781
|
return
|
|
757
|
-
for relationship_diff in node_diff.
|
|
782
|
+
for relationship_diff in node_diff.relationships_by_identifier.values():
|
|
758
783
|
for diff_relationship_property_list in relationship_diff.properties_by_db_id.values():
|
|
759
784
|
for diff_relationship_property in diff_relationship_property_list:
|
|
760
785
|
if diff_relationship_property.changed_at >= self.diff_branched_from_time:
|
|
@@ -133,7 +133,7 @@ class EnrichedDiffDeserializer:
|
|
|
133
133
|
|
|
134
134
|
# TODO Ensure the list is even
|
|
135
135
|
current_node_uuid = node_uuid
|
|
136
|
-
for rel, parent in zip(parents_path_slice[::2], parents_path_slice[1::2]):
|
|
136
|
+
for rel, parent in zip(parents_path_slice[::2], parents_path_slice[1::2], strict=False):
|
|
137
137
|
enriched_root.add_parent(
|
|
138
138
|
node_id=current_node_uuid,
|
|
139
139
|
parent_id=parent.get("uuid"),
|
|
@@ -164,10 +164,8 @@ class EnrichedDiffDeserializer:
|
|
|
164
164
|
def build_diff_root_metadata(cls, root_node: Neo4jNode) -> EnrichedDiffRootMetadata:
|
|
165
165
|
from_time = Timestamp(str(root_node.get("from_time")))
|
|
166
166
|
to_time = Timestamp(str(root_node.get("to_time")))
|
|
167
|
-
tracking_id_str =
|
|
168
|
-
tracking_id =
|
|
169
|
-
if tracking_id_str:
|
|
170
|
-
tracking_id = deserialize_tracking_id(tracking_id_str=tracking_id_str)
|
|
167
|
+
tracking_id_str = str(root_node.get("tracking_id"))
|
|
168
|
+
tracking_id = deserialize_tracking_id(tracking_id_str=tracking_id_str)
|
|
171
169
|
return EnrichedDiffRootMetadata(
|
|
172
170
|
base_branch_name=str(root_node.get("base_branch")),
|
|
173
171
|
diff_branch_name=str(root_node.get("diff_branch")),
|
|
@@ -176,11 +174,12 @@ class EnrichedDiffDeserializer:
|
|
|
176
174
|
uuid=str(root_node.get("uuid")),
|
|
177
175
|
partner_uuid=str(root_node.get("partner_uuid")),
|
|
178
176
|
tracking_id=tracking_id,
|
|
179
|
-
num_added=int(root_node.get("num_added")),
|
|
180
|
-
num_updated=int(root_node.get("num_updated")),
|
|
181
|
-
num_removed=int(root_node.get("num_removed")),
|
|
182
|
-
num_conflicts=int(root_node.get("num_conflicts")),
|
|
177
|
+
num_added=int(root_node.get("num_added", 0)),
|
|
178
|
+
num_updated=int(root_node.get("num_updated", 0)),
|
|
179
|
+
num_removed=int(root_node.get("num_removed", 0)),
|
|
180
|
+
num_conflicts=int(root_node.get("num_conflicts", 0)),
|
|
183
181
|
contains_conflict=str(root_node.get("contains_conflict")).lower() == "true",
|
|
182
|
+
exists_on_database=True,
|
|
184
183
|
)
|
|
185
184
|
|
|
186
185
|
def _deserialize_diff_node(self, node_node: Neo4jNode, enriched_root: EnrichedDiffRoot) -> EnrichedDiffNode:
|
|
@@ -197,10 +196,10 @@ class EnrichedDiffDeserializer:
|
|
|
197
196
|
changed_at=Timestamp(timestamp_str) if timestamp_str else None,
|
|
198
197
|
action=DiffAction(str(node_node.get("action"))),
|
|
199
198
|
path_identifier=str(node_node.get("path_identifier")),
|
|
200
|
-
num_added=int(node_node.get("num_added")),
|
|
201
|
-
num_updated=int(node_node.get("num_updated")),
|
|
202
|
-
num_removed=int(node_node.get("num_removed")),
|
|
203
|
-
num_conflicts=int(node_node.get("num_conflicts")),
|
|
199
|
+
num_added=int(node_node.get("num_added", 0)),
|
|
200
|
+
num_updated=int(node_node.get("num_updated", 0)),
|
|
201
|
+
num_removed=int(node_node.get("num_removed", 0)),
|
|
202
|
+
num_conflicts=int(node_node.get("num_conflicts", 0)),
|
|
204
203
|
contains_conflict=str(node_node.get("contains_conflict")).lower() == "true",
|
|
205
204
|
)
|
|
206
205
|
self._diff_node_map[node_key] = enriched_node
|
|
@@ -220,10 +219,10 @@ class EnrichedDiffDeserializer:
|
|
|
220
219
|
changed_at=Timestamp(str(diff_attr_node.get("changed_at"))),
|
|
221
220
|
path_identifier=str(diff_attr_node.get("path_identifier")),
|
|
222
221
|
action=DiffAction(str(diff_attr_node.get("action"))),
|
|
223
|
-
num_added=int(diff_attr_node.get("num_added")),
|
|
224
|
-
num_updated=int(diff_attr_node.get("num_updated")),
|
|
225
|
-
num_removed=int(diff_attr_node.get("num_removed")),
|
|
226
|
-
num_conflicts=int(diff_attr_node.get("num_conflicts")),
|
|
222
|
+
num_added=int(diff_attr_node.get("num_added", 0)),
|
|
223
|
+
num_updated=int(diff_attr_node.get("num_updated", 0)),
|
|
224
|
+
num_removed=int(diff_attr_node.get("num_removed", 0)),
|
|
225
|
+
num_conflicts=int(diff_attr_node.get("num_conflicts", 0)),
|
|
227
226
|
contains_conflict=str(diff_attr_node.get("contains_conflict")).lower() == "true",
|
|
228
227
|
)
|
|
229
228
|
self._diff_node_attr_map[attr_key] = enriched_attr
|
|
@@ -247,10 +246,10 @@ class EnrichedDiffDeserializer:
|
|
|
247
246
|
changed_at=Timestamp(timestamp_str) if timestamp_str else None,
|
|
248
247
|
action=DiffAction(str(relationship_group_node.get("action"))),
|
|
249
248
|
path_identifier=str(relationship_group_node.get("path_identifier")),
|
|
250
|
-
num_added=int(relationship_group_node.get("num_added")),
|
|
251
|
-
num_conflicts=int(relationship_group_node.get("num_conflicts")),
|
|
252
|
-
num_removed=int(relationship_group_node.get("num_removed")),
|
|
253
|
-
num_updated=int(relationship_group_node.get("num_updated")),
|
|
249
|
+
num_added=int(relationship_group_node.get("num_added", 0)),
|
|
250
|
+
num_conflicts=int(relationship_group_node.get("num_conflicts", 0)),
|
|
251
|
+
num_removed=int(relationship_group_node.get("num_removed", 0)),
|
|
252
|
+
num_updated=int(relationship_group_node.get("num_updated", 0)),
|
|
254
253
|
contains_conflict=str(relationship_group_node.get("contains_conflict")).lower() == "true",
|
|
255
254
|
)
|
|
256
255
|
|
|
@@ -282,10 +281,10 @@ class EnrichedDiffDeserializer:
|
|
|
282
281
|
peer_id=diff_element_peer_id,
|
|
283
282
|
peer_label=peer_label,
|
|
284
283
|
path_identifier=str(relationship_element_node.get("path_identifier")),
|
|
285
|
-
num_added=int(relationship_element_node.get("num_added")),
|
|
286
|
-
num_updated=int(relationship_element_node.get("num_updated")),
|
|
287
|
-
num_removed=int(relationship_element_node.get("num_removed")),
|
|
288
|
-
num_conflicts=int(relationship_element_node.get("num_conflicts")),
|
|
284
|
+
num_added=int(relationship_element_node.get("num_added", 0)),
|
|
285
|
+
num_updated=int(relationship_element_node.get("num_updated", 0)),
|
|
286
|
+
num_removed=int(relationship_element_node.get("num_removed", 0)),
|
|
287
|
+
num_conflicts=int(relationship_element_node.get("num_conflicts", 0)),
|
|
289
288
|
contains_conflict=str(relationship_element_node.get("contains_conflict")).lower() == "true",
|
|
290
289
|
)
|
|
291
290
|
enriched_relationship_group.relationships.add(enriched_rel_element)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from collections import defaultdict
|
|
2
|
-
from typing import AsyncGenerator, Generator
|
|
2
|
+
from typing import AsyncGenerator, Generator, Iterable
|
|
3
3
|
|
|
4
4
|
from infrahub import config
|
|
5
5
|
from infrahub.core import registry
|
|
6
6
|
from infrahub.core.diff.query.field_summary import EnrichedDiffNodeFieldSummaryQuery
|
|
7
|
+
from infrahub.core.diff.query.summary_counts_enricher import DiffSummaryCountsEnricherQuery
|
|
7
8
|
from infrahub.core.query.diff import DiffCountChanges
|
|
8
9
|
from infrahub.core.timestamp import Timestamp
|
|
9
10
|
from infrahub.database import InfrahubDatabase, retry_db_transaction
|
|
@@ -26,13 +27,13 @@ from ..query.all_conflicts import EnrichedDiffAllConflictsQuery
|
|
|
26
27
|
from ..query.delete_query import EnrichedDiffDeleteQuery
|
|
27
28
|
from ..query.diff_get import EnrichedDiffGetQuery
|
|
28
29
|
from ..query.diff_summary import DiffSummaryCounters, DiffSummaryQuery
|
|
29
|
-
from ..query.drop_tracking_id import EnrichedDiffDropTrackingIdQuery
|
|
30
30
|
from ..query.field_specifiers import EnrichedDiffFieldSpecifiersQuery
|
|
31
31
|
from ..query.filters import EnrichedDiffQueryFilters
|
|
32
32
|
from ..query.get_conflict_query import EnrichedDiffConflictQuery
|
|
33
33
|
from ..query.has_conflicts_query import EnrichedDiffHasConflictQuery
|
|
34
|
+
from ..query.merge_tracking_id import EnrichedDiffMergedTrackingIdQuery
|
|
34
35
|
from ..query.roots_metadata import EnrichedDiffRootsMetadataQuery
|
|
35
|
-
from ..query.save import
|
|
36
|
+
from ..query.save import EnrichedDiffRootsUpsertQuery, EnrichedNodeBatchCreateQuery, EnrichedNodesLinkQuery
|
|
36
37
|
from ..query.time_range_query import EnrichedDiffTimeRangeQuery
|
|
37
38
|
from ..query.update_conflict_query import EnrichedDiffConflictUpdateQuery
|
|
38
39
|
from .deserializer import EnrichedDiffDeserializer
|
|
@@ -51,7 +52,8 @@ class DiffRepository:
|
|
|
51
52
|
self,
|
|
52
53
|
base_branch_name: str,
|
|
53
54
|
diff_branch_names: list[str],
|
|
54
|
-
|
|
55
|
+
batch_size_limit: int,
|
|
56
|
+
limit: int | None = None,
|
|
55
57
|
from_time: Timestamp | None = None,
|
|
56
58
|
to_time: Timestamp | None = None,
|
|
57
59
|
filters: EnrichedDiffQueryFilters | None = None,
|
|
@@ -62,8 +64,13 @@ class DiffRepository:
|
|
|
62
64
|
diff_ids: list[str] | None = None,
|
|
63
65
|
) -> list[EnrichedDiffRoot]:
|
|
64
66
|
self.deserializer.initialize()
|
|
67
|
+
final_row_number = None
|
|
68
|
+
if limit:
|
|
69
|
+
final_row_number = offset + limit
|
|
65
70
|
has_more_data = True
|
|
66
|
-
while has_more_data:
|
|
71
|
+
while has_more_data and (final_row_number is None or offset < final_row_number):
|
|
72
|
+
if final_row_number is not None and offset + batch_size_limit > final_row_number:
|
|
73
|
+
batch_size_limit = final_row_number - offset
|
|
67
74
|
get_query = await EnrichedDiffGetQuery.init(
|
|
68
75
|
db=self.db,
|
|
69
76
|
base_branch_name=base_branch_name,
|
|
@@ -72,12 +79,12 @@ class DiffRepository:
|
|
|
72
79
|
to_time=to_time,
|
|
73
80
|
filters=filters,
|
|
74
81
|
max_depth=max_depth,
|
|
75
|
-
limit=
|
|
82
|
+
limit=batch_size_limit,
|
|
76
83
|
offset=offset,
|
|
77
84
|
tracking_id=tracking_id,
|
|
78
85
|
diff_ids=diff_ids,
|
|
79
86
|
)
|
|
80
|
-
log.info(f"Beginning enriched diff get query {
|
|
87
|
+
log.info(f"Beginning enriched diff get query {batch_size_limit=}, {offset=}")
|
|
81
88
|
await get_query.execute(db=self.db)
|
|
82
89
|
log.info("Enriched diff get query complete")
|
|
83
90
|
last_result = None
|
|
@@ -87,7 +94,7 @@ class DiffRepository:
|
|
|
87
94
|
has_more_data = False
|
|
88
95
|
if last_result:
|
|
89
96
|
has_more_data = last_result.get_as_type("has_more_data", bool)
|
|
90
|
-
offset +=
|
|
97
|
+
offset += batch_size_limit
|
|
91
98
|
return await self.deserializer.deserialize()
|
|
92
99
|
|
|
93
100
|
async def get(
|
|
@@ -105,16 +112,17 @@ class DiffRepository:
|
|
|
105
112
|
include_empty: bool = False,
|
|
106
113
|
) -> list[EnrichedDiffRoot]:
|
|
107
114
|
final_max_depth = config.SETTINGS.database.max_depth_search_hierarchy
|
|
108
|
-
|
|
115
|
+
batch_size_limit = int(config.SETTINGS.database.query_size_limit / 10)
|
|
109
116
|
diff_roots = await self._run_get_diff_query(
|
|
110
117
|
base_branch_name=base_branch_name,
|
|
111
118
|
diff_branch_names=diff_branch_names,
|
|
119
|
+
batch_size_limit=batch_size_limit,
|
|
120
|
+
limit=limit,
|
|
112
121
|
from_time=from_time,
|
|
113
122
|
to_time=to_time,
|
|
114
123
|
filters=EnrichedDiffQueryFilters(**dict(filters or {})),
|
|
115
124
|
include_parents=include_parents,
|
|
116
125
|
max_depth=final_max_depth,
|
|
117
|
-
limit=limit,
|
|
118
126
|
offset=offset or 0,
|
|
119
127
|
tracking_id=tracking_id,
|
|
120
128
|
diff_ids=diff_ids,
|
|
@@ -131,21 +139,21 @@ class DiffRepository:
|
|
|
131
139
|
to_time: Timestamp,
|
|
132
140
|
) -> list[EnrichedDiffs]:
|
|
133
141
|
max_depth = config.SETTINGS.database.max_depth_search_hierarchy
|
|
134
|
-
|
|
142
|
+
batch_size_limit = int(config.SETTINGS.database.query_size_limit / 10)
|
|
135
143
|
diff_branch_roots = await self._run_get_diff_query(
|
|
136
144
|
base_branch_name=base_branch_name,
|
|
137
145
|
diff_branch_names=[diff_branch_name],
|
|
138
146
|
from_time=from_time,
|
|
139
147
|
to_time=to_time,
|
|
140
148
|
max_depth=max_depth,
|
|
141
|
-
|
|
149
|
+
batch_size_limit=batch_size_limit,
|
|
142
150
|
)
|
|
143
151
|
diffs_by_uuid = {dbr.uuid: dbr for dbr in diff_branch_roots}
|
|
144
152
|
base_branch_roots = await self._run_get_diff_query(
|
|
145
153
|
base_branch_name=base_branch_name,
|
|
146
154
|
diff_branch_names=[base_branch_name],
|
|
147
155
|
max_depth=max_depth,
|
|
148
|
-
|
|
156
|
+
batch_size_limit=batch_size_limit,
|
|
149
157
|
diff_ids=[d.partner_uuid for d in diffs_by_uuid.values()],
|
|
150
158
|
)
|
|
151
159
|
diffs_by_uuid.update({bbr.uuid: bbr for bbr in base_branch_roots})
|
|
@@ -159,14 +167,23 @@ class DiffRepository:
|
|
|
159
167
|
for dbr in diff_branch_roots
|
|
160
168
|
]
|
|
161
169
|
|
|
162
|
-
async def hydrate_diff_pair(
|
|
170
|
+
async def hydrate_diff_pair(
|
|
171
|
+
self,
|
|
172
|
+
enriched_diffs_metadata: EnrichedDiffsMetadata,
|
|
173
|
+
node_uuids: Iterable[str] | None = None,
|
|
174
|
+
) -> EnrichedDiffs:
|
|
175
|
+
filters = None
|
|
176
|
+
if node_uuids:
|
|
177
|
+
filters = {"ids": list(node_uuids) if node_uuids is not None else None}
|
|
163
178
|
hydrated_base_diff = await self.get_one(
|
|
164
179
|
diff_branch_name=enriched_diffs_metadata.base_branch_name,
|
|
165
180
|
diff_id=enriched_diffs_metadata.base_branch_diff.uuid,
|
|
181
|
+
filters=filters,
|
|
166
182
|
)
|
|
167
183
|
hydrated_branch_diff = await self.get_one(
|
|
168
184
|
diff_branch_name=enriched_diffs_metadata.diff_branch_name,
|
|
169
185
|
diff_id=enriched_diffs_metadata.diff_branch_diff.uuid,
|
|
186
|
+
filters=filters,
|
|
170
187
|
)
|
|
171
188
|
return EnrichedDiffs(
|
|
172
189
|
base_branch_name=enriched_diffs_metadata.base_branch_name,
|
|
@@ -217,17 +234,34 @@ class DiffRepository:
|
|
|
217
234
|
yield node_requests
|
|
218
235
|
|
|
219
236
|
@retry_db_transaction(name="enriched_diff_save")
|
|
220
|
-
async def save(self, enriched_diffs: EnrichedDiffs) -> None:
|
|
237
|
+
async def save(self, enriched_diffs: EnrichedDiffs | EnrichedDiffsMetadata, do_summary_counts: bool = True) -> None:
|
|
238
|
+
log.info("Updating diff metadata...")
|
|
239
|
+
root_query = await EnrichedDiffRootsUpsertQuery.init(db=self.db, enriched_diffs=enriched_diffs)
|
|
240
|
+
await root_query.execute(db=self.db)
|
|
241
|
+
log.info("Diff metadata updated.")
|
|
242
|
+
if not isinstance(enriched_diffs, EnrichedDiffs):
|
|
243
|
+
return
|
|
221
244
|
num_nodes = len(enriched_diffs.base_branch_diff.nodes) + len(enriched_diffs.diff_branch_diff.nodes)
|
|
222
245
|
log.info(f"Saving diff (num_nodes={num_nodes})...")
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
246
|
+
for batch_num, node_create_batch in enumerate(
|
|
247
|
+
self._get_node_create_request_batch(enriched_diffs=enriched_diffs)
|
|
248
|
+
):
|
|
249
|
+
log.info(f"Saving node batch #{batch_num}...")
|
|
226
250
|
node_query = await EnrichedNodeBatchCreateQuery.init(db=self.db, node_create_batch=node_create_batch)
|
|
227
251
|
await node_query.execute(db=self.db)
|
|
252
|
+
log.info(f"Batch #{batch_num} saved")
|
|
228
253
|
link_query = await EnrichedNodesLinkQuery.init(db=self.db, enriched_diffs=enriched_diffs)
|
|
229
254
|
await link_query.execute(db=self.db)
|
|
230
255
|
log.info("Diff saved.")
|
|
256
|
+
if do_summary_counts:
|
|
257
|
+
node_uuids: list[str] | None = None
|
|
258
|
+
if enriched_diffs.diff_branch_diff.exists_on_database:
|
|
259
|
+
node_uuids = list(enriched_diffs.branch_node_uuids)
|
|
260
|
+
await self.add_summary_counts(
|
|
261
|
+
diff_branch_name=enriched_diffs.diff_branch_name,
|
|
262
|
+
diff_id=enriched_diffs.diff_branch_diff.uuid,
|
|
263
|
+
node_uuids=node_uuids,
|
|
264
|
+
)
|
|
231
265
|
|
|
232
266
|
async def summary(
|
|
233
267
|
self,
|
|
@@ -277,6 +311,7 @@ class DiffRepository:
|
|
|
277
311
|
base_branch_names: list[str] | None = None,
|
|
278
312
|
from_time: Timestamp | None = None,
|
|
279
313
|
to_time: Timestamp | None = None,
|
|
314
|
+
tracking_id: TrackingId | None = None,
|
|
280
315
|
) -> list[EnrichedDiffsMetadata]:
|
|
281
316
|
if diff_branch_names and base_branch_names:
|
|
282
317
|
diff_branch_names += base_branch_names
|
|
@@ -285,6 +320,7 @@ class DiffRepository:
|
|
|
285
320
|
base_branch_names=base_branch_names,
|
|
286
321
|
from_time=from_time,
|
|
287
322
|
to_time=to_time,
|
|
323
|
+
tracking_id=tracking_id,
|
|
288
324
|
)
|
|
289
325
|
roots_by_id = {root.uuid: root for root in empty_roots}
|
|
290
326
|
pairs: list[EnrichedDiffsMetadata] = []
|
|
@@ -308,6 +344,7 @@ class DiffRepository:
|
|
|
308
344
|
base_branch_names: list[str] | None = None,
|
|
309
345
|
from_time: Timestamp | None = None,
|
|
310
346
|
to_time: Timestamp | None = None,
|
|
347
|
+
tracking_id: TrackingId | None = None,
|
|
311
348
|
) -> list[EnrichedDiffRootMetadata]:
|
|
312
349
|
query = await EnrichedDiffRootsMetadataQuery.init(
|
|
313
350
|
db=self.db,
|
|
@@ -315,6 +352,7 @@ class DiffRepository:
|
|
|
315
352
|
base_branch_names=base_branch_names,
|
|
316
353
|
from_time=from_time,
|
|
317
354
|
to_time=to_time,
|
|
355
|
+
tracking_id=tracking_id,
|
|
318
356
|
)
|
|
319
357
|
await query.execute(db=self.db)
|
|
320
358
|
diff_roots = []
|
|
@@ -374,8 +412,8 @@ class DiffRepository:
|
|
|
374
412
|
await query.execute(db=self.db)
|
|
375
413
|
return await query.get_field_summaries()
|
|
376
414
|
|
|
377
|
-
async def
|
|
378
|
-
query = await
|
|
415
|
+
async def mark_tracking_ids_merged(self, tracking_ids: list[TrackingId]) -> None:
|
|
416
|
+
query = await EnrichedDiffMergedTrackingIdQuery.init(db=self.db, tracking_ids=tracking_ids)
|
|
379
417
|
await query.execute(db=self.db)
|
|
380
418
|
|
|
381
419
|
async def get_num_changes_in_time_range_by_branch(
|
|
@@ -400,3 +438,21 @@ class DiffRepository:
|
|
|
400
438
|
break
|
|
401
439
|
offset += limit
|
|
402
440
|
return specifiers
|
|
441
|
+
|
|
442
|
+
async def add_summary_counts(
|
|
443
|
+
self,
|
|
444
|
+
diff_branch_name: str,
|
|
445
|
+
tracking_id: TrackingId | None = None,
|
|
446
|
+
diff_id: str | None = None,
|
|
447
|
+
node_uuids: list[str] | None = None,
|
|
448
|
+
) -> None:
|
|
449
|
+
log.info("Updating summary counts...")
|
|
450
|
+
query = await DiffSummaryCountsEnricherQuery.init(
|
|
451
|
+
db=self.db,
|
|
452
|
+
diff_branch_name=diff_branch_name,
|
|
453
|
+
tracking_id=tracking_id,
|
|
454
|
+
diff_id=diff_id,
|
|
455
|
+
node_uuids=node_uuids,
|
|
456
|
+
)
|
|
457
|
+
await query.execute(db=self.db)
|
|
458
|
+
log.info("Summary counts updated...")
|
infrahub/core/diff/tasks.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from prefect import flow
|
|
2
4
|
|
|
5
|
+
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
|
|
3
6
|
from infrahub.core import registry
|
|
4
7
|
from infrahub.core.diff.coordinator import DiffCoordinator
|
|
5
|
-
from infrahub.core.diff.models import RequestDiffUpdate
|
|
8
|
+
from infrahub.core.diff.models import RequestDiffUpdate # noqa: TC001 needed for prefect flow
|
|
6
9
|
from infrahub.core.diff.repository.repository import DiffRepository
|
|
7
10
|
from infrahub.dependencies.registry import get_component_registry
|
|
8
11
|
from infrahub.log import get_logger
|
|
9
|
-
from infrahub.services import
|
|
12
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
10
13
|
from infrahub.workflows.catalogue import DIFF_REFRESH
|
|
11
14
|
from infrahub.workflows.utils import add_branch_tag
|
|
12
15
|
|
|
@@ -14,8 +17,7 @@ log = get_logger()
|
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
@flow(name="diff-update", flow_run_name="Update diff for branch {model.branch_name}")
|
|
17
|
-
async def update_diff(model: RequestDiffUpdate) -> None:
|
|
18
|
-
service = services.service
|
|
20
|
+
async def update_diff(model: RequestDiffUpdate, service: InfrahubServices) -> None:
|
|
19
21
|
await add_branch_tag(branch_name=model.branch_name)
|
|
20
22
|
|
|
21
23
|
async with service.database.start_session() as db:
|
|
@@ -35,8 +37,7 @@ async def update_diff(model: RequestDiffUpdate) -> None:
|
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
@flow(name="diff-refresh", flow_run_name="Recreate diff for branch {branch_name}")
|
|
38
|
-
async def refresh_diff(branch_name: str, diff_id: str) -> None:
|
|
39
|
-
service = services.service
|
|
40
|
+
async def refresh_diff(branch_name: str, diff_id: str, service: InfrahubServices) -> None:
|
|
40
41
|
await add_branch_tag(branch_name=branch_name)
|
|
41
42
|
|
|
42
43
|
async with service.database.start_session() as db:
|
|
@@ -49,8 +50,7 @@ async def refresh_diff(branch_name: str, diff_id: str) -> None:
|
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
@flow(name="diff-refresh-all", flow_run_name="Recreate all diffs for branch {branch_name}")
|
|
52
|
-
async def refresh_diff_all(branch_name: str) -> None:
|
|
53
|
-
service = services.service
|
|
53
|
+
async def refresh_diff_all(branch_name: str, context: InfrahubContext, service: InfrahubServices) -> None:
|
|
54
54
|
await add_branch_tag(branch_name=branch_name)
|
|
55
55
|
|
|
56
56
|
async with service.database.start_session() as db:
|
|
@@ -63,5 +63,6 @@ async def refresh_diff_all(branch_name: str) -> None:
|
|
|
63
63
|
if diff_root.base_branch_name != diff_root.diff_branch_name:
|
|
64
64
|
await service.workflow.submit_workflow(
|
|
65
65
|
workflow=DIFF_REFRESH,
|
|
66
|
+
context=context,
|
|
66
67
|
parameters={"branch_name": diff_root.diff_branch_name, "diff_id": diff_root.uuid},
|
|
67
68
|
)
|
infrahub/core/enums.py
CHANGED
|
@@ -17,7 +17,7 @@ class ObjectConflictValidatorRecorder:
|
|
|
17
17
|
self.validator_label = validator_label
|
|
18
18
|
self.check_schema_kind = check_schema_kind
|
|
19
19
|
|
|
20
|
-
async def record_conflicts(self, proposed_change_id: str, conflicts: Sequence[ObjectConflict]) -> list[Node]:
|
|
20
|
+
async def record_conflicts(self, proposed_change_id: str, conflicts: Sequence[ObjectConflict]) -> list[Node]:
|
|
21
21
|
try:
|
|
22
22
|
proposed_change = await NodeManager.get_one_by_id_or_default_filter(
|
|
23
23
|
id=proposed_change_id, kind=InfrahubKind.PROPOSEDCHANGE, db=self.db
|
infrahub/core/ipam/reconciler.py
CHANGED
|
@@ -104,7 +104,7 @@ class IpamReconciler:
|
|
|
104
104
|
ip_node_uuid = query.get_ip_node_uuid()
|
|
105
105
|
if not ip_node_uuid:
|
|
106
106
|
node_type = InfrahubKind.IPPREFIX
|
|
107
|
-
if isinstance(ip_value,
|
|
107
|
+
if isinstance(ip_value, ipaddress.IPv6Interface | ipaddress.IPv4Interface):
|
|
108
108
|
node_type = InfrahubKind.IPADDRESS
|
|
109
109
|
raise NodeNotFoundError(node_type=node_type, identifier=str(ip_value))
|
|
110
110
|
current_parent_uuid = query.get_current_parent_uuid()
|
infrahub/core/ipam/tasks.py
CHANGED
|
@@ -5,7 +5,7 @@ from prefect import flow
|
|
|
5
5
|
|
|
6
6
|
from infrahub.core import registry
|
|
7
7
|
from infrahub.core.ipam.reconciler import IpamReconciler
|
|
8
|
-
from infrahub.services import
|
|
8
|
+
from infrahub.services import InfrahubServices
|
|
9
9
|
from infrahub.workflows.utils import add_branch_tag
|
|
10
10
|
|
|
11
11
|
from .model import IpamNodeDetails
|
|
@@ -20,8 +20,7 @@ if TYPE_CHECKING:
|
|
|
20
20
|
description="Ensure the IPAM Tree is up to date",
|
|
21
21
|
persist_result=False,
|
|
22
22
|
)
|
|
23
|
-
async def ipam_reconciliation(branch: str, ipam_node_details: list[IpamNodeDetails]) -> None:
|
|
24
|
-
service = services.service
|
|
23
|
+
async def ipam_reconciliation(branch: str, ipam_node_details: list[IpamNodeDetails], service: InfrahubServices) -> None:
|
|
25
24
|
async with service.database.start_session() as db:
|
|
26
25
|
branch_obj = await registry.get_branch(db=db, branch=branch)
|
|
27
26
|
|