infrahub-server 1.2.0rc0__py3-none-any.whl → 1.2.1__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/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +5 -3
- infrahub/artifacts/tasks.py +3 -5
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +240 -12
- infrahub/computed_attribute/tasks.py +77 -441
- infrahub/computed_attribute/triggers.py +13 -47
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +58 -58
- infrahub/core/branch/tasks.py +74 -22
- infrahub/core/changelog/diff.py +95 -36
- infrahub/core/changelog/models.py +217 -43
- infrahub/core/constants/__init__.py +28 -0
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constants/schema.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/enricher/cardinality_one.py +5 -0
- infrahub/core/diff/enricher/hierarchy.py +17 -4
- infrahub/core/diff/enricher/labels.py +5 -0
- infrahub/core/diff/enricher/path_identifier.py +4 -0
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +32 -9
- infrahub/core/diff/parent_node_adder.py +78 -0
- infrahub/core/diff/payload_builder.py +13 -2
- infrahub/core/diff/query/filters.py +2 -2
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query/save.py +188 -182
- infrahub/core/diff/query/summary_counts_enricher.py +51 -4
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/diff/repository/deserializer.py +8 -3
- infrahub/core/diff/repository/repository.py +156 -38
- infrahub/core/diff/tasks.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/index.py +3 -0
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +36 -36
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +12 -3
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +43 -26
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/node_remove.py +26 -12
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +43 -39
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +7 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +228 -40
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +51 -59
- infrahub/core/schema/attribute_schema.py +16 -8
- infrahub/core/schema/basenode_schema.py +105 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +147 -0
- infrahub/core/schema/definitions/core/account.py +171 -0
- infrahub/core/schema/definitions/core/artifact.py +136 -0
- infrahub/core/schema/definitions/core/builtin.py +24 -0
- infrahub/core/schema/definitions/core/check.py +68 -0
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +100 -0
- infrahub/core/schema/definitions/core/graphql_query.py +79 -0
- infrahub/core/schema/definitions/core/group.py +108 -0
- infrahub/core/schema/definitions/core/ipam.py +193 -0
- infrahub/core/schema/definitions/core/lineage.py +19 -0
- infrahub/core/schema/definitions/core/menu.py +48 -0
- infrahub/core/schema/definitions/core/permission.py +163 -0
- infrahub/core/schema/definitions/core/profile.py +18 -0
- infrahub/core/schema/definitions/core/propose_change.py +97 -0
- infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
- infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
- infrahub/core/schema/definitions/core/repository.py +286 -0
- infrahub/core/schema/definitions/core/resource_pool.py +170 -0
- infrahub/core/schema/definitions/core/template.py +27 -0
- infrahub/core/schema/definitions/core/transform.py +96 -0
- infrahub/core/schema/definitions/core/webhook.py +134 -0
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +14 -6
- infrahub/core/schema/schema_branch.py +292 -144
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/timestamp.py +3 -3
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +27 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/builder/diff/deserializer.py +3 -1
- infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
- infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +64 -0
- infrahub/events/branch_action.py +33 -22
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +51 -21
- infrahub/events/models.py +18 -19
- infrahub/events/node_action.py +88 -37
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +32 -24
- infrahub/generators/models.py +2 -3
- infrahub/generators/tasks.py +24 -4
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +48 -24
- infrahub/git/models.py +101 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +408 -6
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +39 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +17 -19
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/branch.py +26 -1
- infrahub/graphql/mutations/computed_attribute.py +9 -5
- infrahub/graphql/mutations/diff.py +23 -11
- infrahub/graphql/mutations/diff_conflict.py +5 -0
- infrahub/graphql/mutations/generator.py +83 -0
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +54 -74
- infrahub/graphql/mutations/main.py +195 -132
- infrahub/graphql/mutations/menu.py +7 -7
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +93 -19
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +19 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/permissions.py +1 -10
- infrahub/graphql/queries/diff/tree.py +19 -14
- infrahub/graphql/queries/event.py +5 -2
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/context.py +12 -0
- infrahub/graphql/types/event.py +84 -17
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/lock.py +20 -20
- infrahub/menu/constants.py +0 -1
- infrahub/menu/generator.py +9 -21
- infrahub/menu/menu.py +17 -38
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/__init__.py +11 -13
- infrahub/message_bus/messages/__init__.py +1 -21
- infrahub/message_bus/messages/check_generator_run.py +3 -3
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/messages/send_echo_request.py +1 -1
- infrahub/message_bus/operations/__init__.py +1 -10
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/event/worker.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -2
- infrahub/message_bus/operations/requests/generator_definition.py +21 -23
- infrahub/message_bus/operations/requests/proposed_change.py +14 -10
- infrahub/permissions/globals.py +15 -0
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/models.py +3 -0
- infrahub/proposed_change/tasks.py +58 -45
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +2 -3
- infrahub/services/__init__.py +2 -2
- infrahub/services/adapters/cache/__init__.py +4 -6
- infrahub/services/adapters/cache/nats.py +4 -5
- infrahub/services/adapters/cache/redis.py +3 -7
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/services/adapters/message_bus/__init__.py +3 -3
- infrahub/services/adapters/message_bus/local.py +2 -2
- infrahub/services/adapters/message_bus/nats.py +4 -4
- infrahub/services/adapters/message_bus/rabbitmq.py +4 -4
- infrahub/services/adapters/workflow/local.py +2 -2
- infrahub/services/component.py +5 -5
- infrahub/services/protocols.py +7 -7
- infrahub/services/scheduler.py +1 -3
- infrahub/task_manager/event.py +102 -9
- infrahub/task_manager/models.py +27 -7
- infrahub/tasks/artifact.py +7 -6
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +4 -6
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +54 -5
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -84
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +176 -44
- infrahub/webhook/tasks.py +154 -155
- infrahub/webhook/triggers.py +31 -7
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +86 -35
- infrahub/workflows/initialization.py +8 -2
- infrahub/workflows/models.py +27 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +35 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/cli_commands.py +5 -1
- infrahub_sdk/ctl/utils.py +0 -16
- infrahub_sdk/exceptions.py +12 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +71 -22
- infrahub_sdk/protocols.py +21 -8
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +11 -0
- infrahub_sdk/task/constants.py +3 -0
- infrahub_sdk/task/exceptions.py +25 -0
- infrahub_sdk/task/manager.py +551 -0
- infrahub_sdk/task/models.py +74 -0
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +142 -33
- infrahub_sdk/utils.py +29 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +8 -6
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +349 -293
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/core/schema/definitions/core.py +0 -2286
- infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
- infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
- infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/messages/request_repository_checks.py +0 -12
- infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
- infrahub/message_bus/operations/check/repository.py +0 -293
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/message_bus/operations/requests/repository.py +0 -133
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from collections import defaultdict
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from typing_extensions import Self
|
|
8
8
|
|
|
@@ -35,12 +35,12 @@ class BranchDiffer:
|
|
|
35
35
|
def __init__(
|
|
36
36
|
self,
|
|
37
37
|
branch: Branch,
|
|
38
|
-
origin_branch:
|
|
38
|
+
origin_branch: Branch | None = None,
|
|
39
39
|
branch_only: bool = False,
|
|
40
|
-
diff_from:
|
|
41
|
-
diff_to:
|
|
42
|
-
db:
|
|
43
|
-
service:
|
|
40
|
+
diff_from: str | Timestamp | None = None,
|
|
41
|
+
diff_to: str | Timestamp | None = None,
|
|
42
|
+
db: InfrahubDatabase | None = None,
|
|
43
|
+
service: InfrahubServices | None = None,
|
|
44
44
|
):
|
|
45
45
|
"""_summary_
|
|
46
46
|
|
|
@@ -81,7 +81,7 @@ class BranchDiffer:
|
|
|
81
81
|
|
|
82
82
|
# Results organized by Branch
|
|
83
83
|
self._results: dict[str, dict] = defaultdict(lambda: {"nodes": {}, "rels": defaultdict(dict), "files": {}})
|
|
84
|
-
self._calculated_diff_files_at:
|
|
84
|
+
self._calculated_diff_files_at: Timestamp | None = None
|
|
85
85
|
|
|
86
86
|
@property
|
|
87
87
|
def service(self) -> InfrahubServices:
|
|
@@ -101,9 +101,9 @@ class BranchDiffer:
|
|
|
101
101
|
db: InfrahubDatabase,
|
|
102
102
|
branch: Branch,
|
|
103
103
|
branch_only: bool = False,
|
|
104
|
-
diff_from:
|
|
105
|
-
diff_to:
|
|
106
|
-
service:
|
|
104
|
+
diff_from: str | Timestamp | None = None,
|
|
105
|
+
diff_to: str | Timestamp | None = None,
|
|
106
|
+
service: InfrahubServices | None = None,
|
|
107
107
|
) -> Self:
|
|
108
108
|
origin_branch = branch.get_origin_branch()
|
|
109
109
|
|
|
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
3
3
|
from infrahub.core.constants import NULL_VALUE, DiffAction, RelationshipCardinality
|
|
4
4
|
from infrahub.core.constants.database import DatabaseEdgeType
|
|
5
5
|
from infrahub.database import InfrahubDatabase
|
|
6
|
+
from infrahub.log import get_logger
|
|
6
7
|
|
|
7
8
|
from ..model.path import (
|
|
8
9
|
CalculatedDiffs,
|
|
@@ -16,6 +17,8 @@ from .interface import DiffEnricherInterface
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
17
18
|
from infrahub.core.schema import MainSchemaTypes
|
|
18
19
|
|
|
20
|
+
log = get_logger()
|
|
21
|
+
|
|
19
22
|
|
|
20
23
|
class DiffCardinalityOneEnricher(DiffEnricherInterface):
|
|
21
24
|
"""Clean up diffs for cardinality=one relationships to make them cleaner and more intuitive
|
|
@@ -34,6 +37,7 @@ class DiffCardinalityOneEnricher(DiffEnricherInterface):
|
|
|
34
37
|
|
|
35
38
|
async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None: # noqa: ARG002
|
|
36
39
|
self._node_schema_map = {}
|
|
40
|
+
log.info("Beginning cardinality-one diff enrichment...")
|
|
37
41
|
for diff_node in enriched_diff_root.nodes:
|
|
38
42
|
for relationship_group in diff_node.relationships:
|
|
39
43
|
if (
|
|
@@ -41,6 +45,7 @@ class DiffCardinalityOneEnricher(DiffEnricherInterface):
|
|
|
41
45
|
and len(relationship_group.relationships) > 0
|
|
42
46
|
):
|
|
43
47
|
self.consolidate_cardinality_one_diff_elements(diff_relationship=relationship_group)
|
|
48
|
+
log.info("Cardinality-one diff enrichment complete.")
|
|
44
49
|
|
|
45
50
|
def _determine_action(self, previous_value: Any, new_value: Any) -> DiffAction:
|
|
46
51
|
if previous_value == new_value:
|
|
@@ -7,19 +7,24 @@ from infrahub.core.query.node import NodeGetHierarchyQuery
|
|
|
7
7
|
from infrahub.core.query.relationship import RelationshipGetPeerQuery, RelationshipPeerData
|
|
8
8
|
from infrahub.core.schema import ProfileSchema, TemplateSchema
|
|
9
9
|
from infrahub.database import InfrahubDatabase
|
|
10
|
+
from infrahub.log import get_logger
|
|
10
11
|
|
|
11
12
|
from ..model.path import (
|
|
12
13
|
CalculatedDiffs,
|
|
13
14
|
EnrichedDiffRoot,
|
|
14
15
|
)
|
|
16
|
+
from ..parent_node_adder import DiffParentNodeAdder, ParentNodeAddRequest
|
|
15
17
|
from .interface import DiffEnricherInterface
|
|
16
18
|
|
|
19
|
+
log = get_logger()
|
|
20
|
+
|
|
17
21
|
|
|
18
22
|
class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
19
23
|
"""Add hierarchy and parent/component nodes to diff even if the higher-level nodes are unchanged"""
|
|
20
24
|
|
|
21
|
-
def __init__(self, db: InfrahubDatabase):
|
|
25
|
+
def __init__(self, db: InfrahubDatabase, parent_adder: DiffParentNodeAdder):
|
|
22
26
|
self.db = db
|
|
27
|
+
self.parent_adder = parent_adder
|
|
23
28
|
|
|
24
29
|
async def enrich(
|
|
25
30
|
self,
|
|
@@ -30,6 +35,8 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
30
35
|
# - A node has a relationship of kind parent
|
|
31
36
|
# - A node is part of a hierarchy
|
|
32
37
|
|
|
38
|
+
log.info("Beginning hierarchical diff enrichment...")
|
|
39
|
+
self.parent_adder.initialize(enriched_diff_root=enriched_diff_root)
|
|
33
40
|
node_rel_parent_map: dict[str, list[str]] = defaultdict(list)
|
|
34
41
|
node_hierarchy_map: dict[str, list[str]] = defaultdict(list)
|
|
35
42
|
|
|
@@ -55,6 +62,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
55
62
|
|
|
56
63
|
await self._enrich_nodes_with_parent(enriched_diff_root=enriched_diff_root, node_map=node_rel_parent_map)
|
|
57
64
|
await self._enrich_hierarchical_nodes(enriched_diff_root=enriched_diff_root, node_map=node_hierarchy_map)
|
|
65
|
+
log.info("Hierarchical diff enrichment complete.")
|
|
58
66
|
|
|
59
67
|
async def _enrich_hierarchical_nodes(
|
|
60
68
|
self,
|
|
@@ -65,6 +73,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
65
73
|
|
|
66
74
|
# Retrieve the ID of all ancestors
|
|
67
75
|
for kind, node_ids in node_map.items():
|
|
76
|
+
log.info(f"Beginning hierarchy enrichment for {kind} node, num_nodes={len(node_ids)}...")
|
|
68
77
|
hierarchy_schema = self.db.schema.get(
|
|
69
78
|
name=kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
|
|
70
79
|
)
|
|
@@ -89,7 +98,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
89
98
|
|
|
90
99
|
current_node = node
|
|
91
100
|
for ancestor in ancestors:
|
|
92
|
-
|
|
101
|
+
parent_request = ParentNodeAddRequest(
|
|
93
102
|
node_id=current_node.uuid,
|
|
94
103
|
parent_id=str(ancestor.uuid),
|
|
95
104
|
parent_kind=ancestor.kind,
|
|
@@ -99,6 +108,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
99
108
|
parent_rel_cardinality=parent_rel.cardinality,
|
|
100
109
|
parent_rel_label=parent_rel.label or "",
|
|
101
110
|
)
|
|
111
|
+
parent = self.parent_adder.add_parent(parent_request=parent_request)
|
|
102
112
|
|
|
103
113
|
current_node = parent
|
|
104
114
|
|
|
@@ -116,6 +126,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
116
126
|
|
|
117
127
|
# Query the UUID of the parent
|
|
118
128
|
for kind, ids in node_map.items():
|
|
129
|
+
log.info(f"Beginning parent enrichment for {kind} node, num_nodes={len(ids)}...")
|
|
119
130
|
schema_node = self.db.schema.get(name=kind, branch=enriched_diff_root.diff_branch_name, duplicate=False)
|
|
120
131
|
|
|
121
132
|
parent_rel = [rel for rel in schema_node.relationships if rel.kind == RelationshipKind.PARENT][0]
|
|
@@ -140,15 +151,16 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
140
151
|
# Check if the parent are already present
|
|
141
152
|
# If parent is already in the list of node we need to add a relationship
|
|
142
153
|
# If parent is not in the list of node, we need to add it
|
|
154
|
+
diff_node_map = enriched_diff_root.get_node_map(node_uuids=set(parent_peers.keys()))
|
|
143
155
|
for node_id, peer_parent in parent_peers.items():
|
|
144
156
|
# TODO check if we can optimize this part to avoid querying this multiple times
|
|
145
|
-
node =
|
|
157
|
+
node = diff_node_map[node_id]
|
|
146
158
|
schema_node = self.db.schema.get(
|
|
147
159
|
name=node.kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
|
|
148
160
|
)
|
|
149
161
|
parent_rel = [rel for rel in schema_node.relationships if rel.kind == RelationshipKind.PARENT][0]
|
|
150
162
|
|
|
151
|
-
|
|
163
|
+
parent_request = ParentNodeAddRequest(
|
|
152
164
|
node_id=node.uuid,
|
|
153
165
|
parent_id=str(peer_parent.peer_id),
|
|
154
166
|
parent_kind=peer_parent.peer_kind,
|
|
@@ -158,6 +170,7 @@ class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
|
158
170
|
parent_rel_cardinality=parent_rel.cardinality,
|
|
159
171
|
parent_rel_label=parent_rel.label or "",
|
|
160
172
|
)
|
|
173
|
+
self.parent_adder.add_parent(parent_request=parent_request)
|
|
161
174
|
|
|
162
175
|
if node_parent_with_parent_map:
|
|
163
176
|
await self._enrich_nodes_with_parent(
|
|
@@ -6,6 +6,7 @@ from infrahub.core.constants import DiffAction
|
|
|
6
6
|
from infrahub.core.constants.database import DatabaseEdgeType
|
|
7
7
|
from infrahub.core.query.node import NodeGetKindQuery
|
|
8
8
|
from infrahub.database import InfrahubDatabase
|
|
9
|
+
from infrahub.log import get_logger
|
|
9
10
|
|
|
10
11
|
from ..model.path import (
|
|
11
12
|
CalculatedDiffs,
|
|
@@ -17,6 +18,8 @@ from ..model.path import (
|
|
|
17
18
|
from ..payload_builder import get_display_labels
|
|
18
19
|
from .interface import DiffEnricherInterface
|
|
19
20
|
|
|
21
|
+
log = get_logger()
|
|
22
|
+
|
|
20
23
|
PROPERTY_TYPES_WITH_LABELS = {DatabaseEdgeType.IS_RELATED, DatabaseEdgeType.HAS_OWNER, DatabaseEdgeType.HAS_SOURCE}
|
|
21
24
|
|
|
22
25
|
|
|
@@ -194,6 +197,7 @@ class DiffLabelsEnricher(DiffEnricherInterface):
|
|
|
194
197
|
calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
|
|
195
198
|
conflicts_only: bool = False,
|
|
196
199
|
) -> None:
|
|
200
|
+
log.info("Beginning display labels diff enrichment...")
|
|
197
201
|
self._base_branch_name = enriched_diff_root.base_branch_name
|
|
198
202
|
self._diff_branch_name = enriched_diff_root.diff_branch_name
|
|
199
203
|
self._conflicts_only = conflicts_only
|
|
@@ -214,3 +218,4 @@ class DiffLabelsEnricher(DiffEnricherInterface):
|
|
|
214
218
|
...
|
|
215
219
|
|
|
216
220
|
self._update_relationship_labels(enriched_diff=enriched_diff_root)
|
|
221
|
+
log.info("Display labels diff enrichment complete.")
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
from infrahub.core.constants import PathType
|
|
2
2
|
from infrahub.core.path import DataPath
|
|
3
3
|
from infrahub.database import InfrahubDatabase
|
|
4
|
+
from infrahub.log import get_logger
|
|
4
5
|
|
|
5
6
|
from ..model.path import CalculatedDiffs, EnrichedDiffRoot
|
|
6
7
|
from .interface import DiffEnricherInterface
|
|
7
8
|
|
|
9
|
+
log = get_logger()
|
|
10
|
+
|
|
8
11
|
|
|
9
12
|
class DiffPathIdentifierEnricher(DiffEnricherInterface):
|
|
10
13
|
"""Add path identifiers to every element in the diff"""
|
|
@@ -62,3 +65,4 @@ class DiffPathIdentifierEnricher(DiffEnricherInterface):
|
|
|
62
65
|
relationship_property_path = relationship_element_path.model_copy()
|
|
63
66
|
relationship_property_path.property_name = relationship_property.property_type.value
|
|
64
67
|
relationship_property.path_identifier = relationship_property_path.get_path(with_peer=False)
|
|
68
|
+
log.info("Path identifier diff enrichment complete.")
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
from infrahub.core.constants import DiffAction
|
|
5
4
|
from infrahub.core.constants.database import DatabaseEdgeType
|
|
@@ -18,8 +17,8 @@ class ChangedIpamNodeDetails:
|
|
|
18
17
|
node_uuid: str
|
|
19
18
|
is_address: bool
|
|
20
19
|
is_delete: bool
|
|
21
|
-
namespace_id:
|
|
22
|
-
ip_value:
|
|
20
|
+
namespace_id: str | None
|
|
21
|
+
ip_value: str | None
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
class IpamDiffParser:
|
|
@@ -142,7 +141,7 @@ class IpamDiffParser:
|
|
|
142
141
|
uuids_missing_data=uuids_missing_data,
|
|
143
142
|
)
|
|
144
143
|
|
|
145
|
-
def _get_ip_value(self, node_diff: EnrichedDiffNode) ->
|
|
144
|
+
def _get_ip_value(self, node_diff: EnrichedDiffNode) -> str | None:
|
|
146
145
|
ip_attr_diff = None
|
|
147
146
|
for diff_attr in node_diff.attributes:
|
|
148
147
|
if diff_attr.name in {"prefix", "address"}:
|
|
@@ -155,7 +154,7 @@ class IpamDiffParser:
|
|
|
155
154
|
return diff_property.new_value or diff_property.previous_value
|
|
156
155
|
return None
|
|
157
156
|
|
|
158
|
-
def _get_namespace_id(self, node_diff: EnrichedDiffNode) ->
|
|
157
|
+
def _get_namespace_id(self, node_diff: EnrichedDiffNode) -> str | None:
|
|
159
158
|
namespace_rel = None
|
|
160
159
|
for diff_rel in node_diff.relationships:
|
|
161
160
|
if diff_rel.name == "ip_namespace":
|
infrahub/core/diff/model/diff.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from enum import Enum
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, ConfigDict, Field
|
|
7
7
|
|
|
@@ -46,8 +46,8 @@ class BaseDiffElement(BaseModel):
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class ValueElement(BaseDiffElement):
|
|
49
|
-
previous:
|
|
50
|
-
new:
|
|
49
|
+
previous: Any | None = None
|
|
50
|
+
new: Any | None = None
|
|
51
51
|
|
|
52
52
|
def __hash__(self) -> int:
|
|
53
53
|
return hash(type(self))
|
|
@@ -57,12 +57,12 @@ class PropertyDiffElement(BaseDiffElement):
|
|
|
57
57
|
branch: str
|
|
58
58
|
type: str
|
|
59
59
|
action: DiffAction
|
|
60
|
-
path:
|
|
60
|
+
path: str | None = None
|
|
61
61
|
db_id: str = Field(exclude=True)
|
|
62
62
|
rel_id: str = Field(exclude=True)
|
|
63
|
-
origin_rel_id:
|
|
64
|
-
value:
|
|
65
|
-
changed_at:
|
|
63
|
+
origin_rel_id: str | None = Field(None, exclude=True)
|
|
64
|
+
value: ValueElement | None = None
|
|
65
|
+
changed_at: Timestamp | None = None
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
class NodeAttributeDiffElement(BaseDiffElement):
|
|
@@ -72,28 +72,28 @@ class NodeAttributeDiffElement(BaseDiffElement):
|
|
|
72
72
|
action: DiffAction
|
|
73
73
|
db_id: str = Field(exclude=True)
|
|
74
74
|
rel_id: str = Field(exclude=True)
|
|
75
|
-
origin_rel_id:
|
|
76
|
-
changed_at:
|
|
75
|
+
origin_rel_id: str | None = Field(None, exclude=True)
|
|
76
|
+
changed_at: Timestamp | None = None
|
|
77
77
|
properties: dict[str, PropertyDiffElement]
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
class NodeDiffElement(BaseDiffElement):
|
|
81
|
-
branch:
|
|
81
|
+
branch: str | None = None
|
|
82
82
|
labels: list[str]
|
|
83
83
|
kind: str
|
|
84
84
|
id: str
|
|
85
85
|
path: str
|
|
86
86
|
action: DiffAction
|
|
87
87
|
db_id: str = Field(exclude=True)
|
|
88
|
-
rel_id:
|
|
89
|
-
changed_at:
|
|
88
|
+
rel_id: str | None = Field(None, exclude=True)
|
|
89
|
+
changed_at: Timestamp | None = None
|
|
90
90
|
attributes: dict[str, NodeAttributeDiffElement] = Field(default_factory=dict)
|
|
91
91
|
|
|
92
92
|
|
|
93
93
|
class RelationshipEdgeNodeDiffElement(BaseDiffElement):
|
|
94
94
|
id: str
|
|
95
|
-
db_id:
|
|
96
|
-
rel_id:
|
|
95
|
+
db_id: str | None = Field(None, exclude=True)
|
|
96
|
+
rel_id: str | None = Field(None, exclude=True)
|
|
97
97
|
labels: list[str]
|
|
98
98
|
kind: str
|
|
99
99
|
|
|
@@ -106,11 +106,11 @@ class RelationshipDiffElement(BaseDiffElement):
|
|
|
106
106
|
action: DiffAction
|
|
107
107
|
nodes: dict[str, RelationshipEdgeNodeDiffElement]
|
|
108
108
|
properties: dict[str, PropertyDiffElement]
|
|
109
|
-
changed_at:
|
|
109
|
+
changed_at: Timestamp | None = None
|
|
110
110
|
paths: list[str]
|
|
111
111
|
conflict_paths: list[str]
|
|
112
112
|
|
|
113
|
-
def get_node_id_by_kind(self, kind: str) ->
|
|
113
|
+
def get_node_id_by_kind(self, kind: str) -> str | None:
|
|
114
114
|
ids = [rel.id for rel in self.nodes.values() if rel.kind == kind]
|
|
115
115
|
if ids:
|
|
116
116
|
return ids[0]
|
|
@@ -149,11 +149,11 @@ class ModifiedPath(BaseModel):
|
|
|
149
149
|
node_id: str
|
|
150
150
|
path_type: PathType
|
|
151
151
|
kind: str
|
|
152
|
-
element_name:
|
|
153
|
-
property_name:
|
|
154
|
-
peer_id:
|
|
152
|
+
element_name: str | None = None
|
|
153
|
+
property_name: str | None = None
|
|
154
|
+
peer_id: str | None = None
|
|
155
155
|
action: DiffAction
|
|
156
|
-
change:
|
|
156
|
+
change: ValueElement | None = None
|
|
157
157
|
|
|
158
158
|
def __eq__(self, other: object) -> bool:
|
|
159
159
|
if not isinstance(other, ModifiedPath):
|
|
@@ -248,7 +248,7 @@ class DataConflict(ObjectConflict):
|
|
|
248
248
|
conflict_path: str
|
|
249
249
|
path: str
|
|
250
250
|
path_type: PathType
|
|
251
|
-
property_name:
|
|
251
|
+
property_name: str | None = None
|
|
252
252
|
change_type: str
|
|
253
253
|
changes: list[BranchChanges] = Field(default_factory=list)
|
|
254
254
|
|
|
@@ -311,7 +311,7 @@ class BranchDiffFile(BaseModel):
|
|
|
311
311
|
class BranchDiffRepository(BaseModel):
|
|
312
312
|
branch: str
|
|
313
313
|
id: str
|
|
314
|
-
display_name:
|
|
314
|
+
display_name: str | None = None
|
|
315
315
|
commit_from: str
|
|
316
316
|
commit_to: str
|
|
317
317
|
files: list[BranchDiffFile] = Field(default_factory=list)
|
|
@@ -325,14 +325,14 @@ class BranchDiffArtifactStorage(BaseModel):
|
|
|
325
325
|
class ArtifactTarget(BaseModel):
|
|
326
326
|
id: str
|
|
327
327
|
kind: str
|
|
328
|
-
display_label:
|
|
328
|
+
display_label: str | None = None
|
|
329
329
|
|
|
330
330
|
|
|
331
331
|
class BranchDiffArtifact(BaseModel):
|
|
332
332
|
branch: str
|
|
333
333
|
id: str
|
|
334
|
-
display_label:
|
|
334
|
+
display_label: str | None = None
|
|
335
335
|
action: DiffAction
|
|
336
|
-
target:
|
|
337
|
-
item_new:
|
|
338
|
-
item_previous:
|
|
336
|
+
target: ArtifactTarget | None = None
|
|
337
|
+
item_new: BranchDiffArtifactStorage | None = None
|
|
338
|
+
item_previous: BranchDiffArtifactStorage | None = None
|
infrahub/core/diff/model/path.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import asdict, dataclass, field
|
|
4
4
|
from enum import Enum
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
from infrahub.core.constants import (
|
|
8
8
|
BranchSupportType,
|
|
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
|
|
|
20
20
|
from neo4j.graph import Node as Neo4jNode
|
|
21
21
|
from neo4j.graph import Path as Neo4jPath
|
|
22
22
|
from neo4j.graph import Relationship as Neo4jRelationship
|
|
23
|
-
from
|
|
23
|
+
from whenever import TimeDelta
|
|
24
24
|
|
|
25
25
|
from infrahub.graphql.initialization import GraphqlContext
|
|
26
26
|
|
|
@@ -163,6 +163,10 @@ class EnrichedDiffAttribute(BaseSummary):
|
|
|
163
163
|
def __hash__(self) -> int:
|
|
164
164
|
return hash(self.name)
|
|
165
165
|
|
|
166
|
+
@property
|
|
167
|
+
def num_properties(self) -> int:
|
|
168
|
+
return len(self.properties)
|
|
169
|
+
|
|
166
170
|
def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
|
|
167
171
|
return {prop.path_identifier: prop.conflict for prop in self.properties if prop.conflict}
|
|
168
172
|
|
|
@@ -202,6 +206,10 @@ class EnrichedDiffSingleRelationship(BaseSummary):
|
|
|
202
206
|
def __hash__(self) -> int:
|
|
203
207
|
return hash(self.peer_id)
|
|
204
208
|
|
|
209
|
+
@property
|
|
210
|
+
def num_properties(self) -> int:
|
|
211
|
+
return len(self.properties)
|
|
212
|
+
|
|
205
213
|
def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
|
|
206
214
|
all_conflicts: dict[str, EnrichedDiffConflict] = {}
|
|
207
215
|
if self.conflict:
|
|
@@ -248,6 +256,10 @@ class EnrichedDiffRelationship(BaseSummary):
|
|
|
248
256
|
def __hash__(self) -> int:
|
|
249
257
|
return hash(self.name)
|
|
250
258
|
|
|
259
|
+
@property
|
|
260
|
+
def num_properties(self) -> int:
|
|
261
|
+
return sum(r.num_properties for r in self.relationships)
|
|
262
|
+
|
|
251
263
|
def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
|
|
252
264
|
all_conflicts: dict[str, EnrichedDiffConflict] = {}
|
|
253
265
|
for element in self.relationships:
|
|
@@ -308,6 +320,10 @@ class EnrichedDiffNode(BaseSummary):
|
|
|
308
320
|
def __hash__(self) -> int:
|
|
309
321
|
return hash(self.uuid)
|
|
310
322
|
|
|
323
|
+
@property
|
|
324
|
+
def num_properties(self) -> int:
|
|
325
|
+
return sum(a.num_properties for a in self.attributes) + sum(r.num_properties for r in self.relationships)
|
|
326
|
+
|
|
311
327
|
def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
|
|
312
328
|
all_conflicts: dict[str, EnrichedDiffConflict] = {}
|
|
313
329
|
if self.conflict:
|
|
@@ -409,16 +425,16 @@ class EnrichedDiffRootMetadata(BaseSummary):
|
|
|
409
425
|
from_time: Timestamp
|
|
410
426
|
to_time: Timestamp
|
|
411
427
|
uuid: str
|
|
412
|
-
partner_uuid: str
|
|
413
428
|
tracking_id: TrackingId
|
|
429
|
+
partner_uuid: str | None = field(default=None)
|
|
414
430
|
exists_on_database: bool = field(default=False)
|
|
415
431
|
|
|
416
432
|
def __hash__(self) -> int:
|
|
417
433
|
return hash(self.uuid)
|
|
418
434
|
|
|
419
435
|
@property
|
|
420
|
-
def time_range(self) ->
|
|
421
|
-
return self.to_time.
|
|
436
|
+
def time_range(self) -> TimeDelta:
|
|
437
|
+
return self.to_time.get_obj() - self.from_time.get_obj()
|
|
422
438
|
|
|
423
439
|
def update_metadata(
|
|
424
440
|
self,
|
|
@@ -447,8 +463,8 @@ class EnrichedDiffRoot(EnrichedDiffRootMetadata):
|
|
|
447
463
|
return hash(self.uuid)
|
|
448
464
|
|
|
449
465
|
@property
|
|
450
|
-
def time_range(self) ->
|
|
451
|
-
return self.to_time.
|
|
466
|
+
def time_range(self) -> TimeDelta:
|
|
467
|
+
return self.to_time.get_obj() - self.from_time.get_obj()
|
|
452
468
|
|
|
453
469
|
def get_nodes_without_parents(self) -> set[EnrichedDiffNode]:
|
|
454
470
|
nodes_with_parent_uuids = set()
|
|
@@ -470,6 +486,13 @@ class EnrichedDiffRoot(EnrichedDiffRootMetadata):
|
|
|
470
486
|
except ValueError:
|
|
471
487
|
return False
|
|
472
488
|
|
|
489
|
+
def get_node_map(self, node_uuids: set[str] | None = None) -> dict[str, EnrichedDiffNode]:
|
|
490
|
+
node_map = {}
|
|
491
|
+
for node in self.nodes:
|
|
492
|
+
if node_uuids is None or node.uuid in node_uuids:
|
|
493
|
+
node_map[node.uuid] = node
|
|
494
|
+
return node_map
|
|
495
|
+
|
|
473
496
|
def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
|
|
474
497
|
all_conflicts: dict[str, EnrichedDiffConflict] = {}
|
|
475
498
|
for node in self.nodes:
|
|
@@ -825,13 +848,13 @@ class DatabasePath:
|
|
|
825
848
|
return "Node" in self.property_node.labels
|
|
826
849
|
|
|
827
850
|
@property
|
|
828
|
-
def peer_id(self) ->
|
|
851
|
+
def peer_id(self) -> str | None:
|
|
829
852
|
if not self.property_is_peer:
|
|
830
853
|
return None
|
|
831
854
|
return str(self.property_node.get("uuid"))
|
|
832
855
|
|
|
833
856
|
@property
|
|
834
|
-
def peer_kind(self) ->
|
|
857
|
+
def peer_kind(self) -> str | None:
|
|
835
858
|
if not self.property_is_peer:
|
|
836
859
|
return None
|
|
837
860
|
return str(self.property_node.get("kind"))
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
|
|
3
|
+
from infrahub.core.constants import DiffAction, RelationshipCardinality
|
|
4
|
+
|
|
5
|
+
from .model.path import EnrichedDiffNode, EnrichedDiffRelationship, EnrichedDiffRoot
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class ParentNodeAddRequest:
|
|
10
|
+
node_id: str
|
|
11
|
+
parent_id: str
|
|
12
|
+
parent_kind: str
|
|
13
|
+
parent_label: str
|
|
14
|
+
parent_rel_name: str
|
|
15
|
+
parent_rel_identifier: str
|
|
16
|
+
parent_rel_cardinality: RelationshipCardinality
|
|
17
|
+
parent_rel_label: str = field(default="")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DiffParentNodeAdder:
|
|
21
|
+
def __init__(self) -> None:
|
|
22
|
+
self._diff_root: EnrichedDiffRoot | None = None
|
|
23
|
+
self._node_map: dict[str, EnrichedDiffNode] = {}
|
|
24
|
+
|
|
25
|
+
def initialize(self, enriched_diff_root: EnrichedDiffRoot) -> None:
|
|
26
|
+
self._diff_root = enriched_diff_root
|
|
27
|
+
self._node_map = enriched_diff_root.get_node_map()
|
|
28
|
+
|
|
29
|
+
def get_root(self) -> EnrichedDiffRoot:
|
|
30
|
+
if not self._diff_root:
|
|
31
|
+
raise RuntimeError("Must call initialize before using")
|
|
32
|
+
return self._diff_root
|
|
33
|
+
|
|
34
|
+
def get_node(self, node_uuid: str) -> EnrichedDiffNode:
|
|
35
|
+
return self._node_map[node_uuid]
|
|
36
|
+
|
|
37
|
+
def has_node(self, node_uuid: str) -> bool:
|
|
38
|
+
return node_uuid in self._node_map
|
|
39
|
+
|
|
40
|
+
def add_node(self, node: EnrichedDiffNode) -> None:
|
|
41
|
+
if node.uuid in self._node_map:
|
|
42
|
+
return
|
|
43
|
+
self._node_map[node.uuid] = node
|
|
44
|
+
self.get_root().nodes.add(node)
|
|
45
|
+
|
|
46
|
+
def add_parent(self, parent_request: ParentNodeAddRequest) -> EnrichedDiffNode:
|
|
47
|
+
if not self._diff_root:
|
|
48
|
+
raise RuntimeError("Must call initialize before using")
|
|
49
|
+
node = self.get_node(node_uuid=parent_request.node_id)
|
|
50
|
+
if not self.has_node(node_uuid=parent_request.parent_id):
|
|
51
|
+
parent = EnrichedDiffNode(
|
|
52
|
+
uuid=parent_request.parent_id,
|
|
53
|
+
kind=parent_request.parent_kind,
|
|
54
|
+
label=parent_request.parent_label,
|
|
55
|
+
action=DiffAction.UNCHANGED,
|
|
56
|
+
changed_at=None,
|
|
57
|
+
)
|
|
58
|
+
self.add_node(parent)
|
|
59
|
+
else:
|
|
60
|
+
parent = self.get_node(node_uuid=parent_request.parent_id)
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
rel = node.get_relationship(name=parent_request.parent_rel_name)
|
|
64
|
+
rel.nodes.add(parent)
|
|
65
|
+
except ValueError:
|
|
66
|
+
node.relationships.add(
|
|
67
|
+
EnrichedDiffRelationship(
|
|
68
|
+
name=parent_request.parent_rel_name,
|
|
69
|
+
identifier=parent_request.parent_rel_identifier,
|
|
70
|
+
label=parent_request.parent_rel_label,
|
|
71
|
+
cardinality=parent_request.parent_rel_cardinality,
|
|
72
|
+
changed_at=None,
|
|
73
|
+
action=DiffAction.UNCHANGED,
|
|
74
|
+
nodes={parent},
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return parent
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
from infrahub import config
|
|
5
6
|
from infrahub.core.manager import NodeManager
|
|
6
7
|
from infrahub.core.registry import registry
|
|
7
8
|
from infrahub.exceptions import SchemaNotFoundError
|
|
@@ -26,8 +27,18 @@ async def get_display_labels_per_kind(
|
|
|
26
27
|
if skip_missing_schema:
|
|
27
28
|
return {}
|
|
28
29
|
raise
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
display_label_map: dict[str, str] = {}
|
|
31
|
+
offset = 0
|
|
32
|
+
limit = config.SETTINGS.database.query_size_limit
|
|
33
|
+
while True:
|
|
34
|
+
limited_ids = ids[offset : offset + limit]
|
|
35
|
+
if not limited_ids:
|
|
36
|
+
break
|
|
37
|
+
node_map = await NodeManager.get_many(ids=limited_ids, fields=fields, db=db, branch=branch)
|
|
38
|
+
for node_id, node in node_map.items():
|
|
39
|
+
display_label_map[node_id] = await node.render_display_label(db=db)
|
|
40
|
+
offset += limit
|
|
41
|
+
return display_label_map
|
|
31
42
|
|
|
32
43
|
|
|
33
44
|
async def get_display_labels(nodes: dict[str, dict[str, list[str]]], db: InfrahubDatabase) -> dict[str, dict[str, str]]:
|
|
@@ -16,8 +16,8 @@ class IncExclFilterOptions(BaseModel):
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class IncExclActionFilterOptions(BaseModel):
|
|
19
|
-
includes: set[DiffAction] = Field(default_factory=
|
|
20
|
-
excludes: set[DiffAction] = Field(default_factory=
|
|
19
|
+
includes: set[DiffAction] = Field(default_factory=set)
|
|
20
|
+
excludes: set[DiffAction] = Field(default_factory=set)
|
|
21
21
|
|
|
22
22
|
@property
|
|
23
23
|
def is_empty(self) -> bool:
|