infrahub-server 1.2.0b1__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 +1 -3
- infrahub/artifacts/tasks.py +1 -3
- 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 +239 -11
- infrahub/computed_attribute/tasks.py +77 -442
- infrahub/computed_attribute/triggers.py +11 -45
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +57 -57
- infrahub/core/branch/tasks.py +12 -9
- infrahub/core/changelog/diff.py +16 -8
- infrahub/core/changelog/models.py +189 -26
- infrahub/core/constants/__init__.py +5 -1
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +3 -3
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- 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 +34 -34
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +9 -4
- 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/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/{m020_add_generate_template_attr.py → m022_add_generate_template_attr.py} +3 -3
- 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 +18 -21
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- 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 +29 -28
- 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 +5 -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 +24 -24
- 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 +40 -46
- infrahub/core/schema/attribute_schema.py +9 -9
- infrahub/core/schema/basenode_schema.py +93 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +13 -19
- infrahub/core/schema/definitions/core/account.py +151 -148
- infrahub/core/schema/definitions/core/artifact.py +122 -113
- infrahub/core/schema/definitions/core/builtin.py +19 -16
- infrahub/core/schema/definitions/core/check.py +61 -53
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +89 -85
- infrahub/core/schema/definitions/core/graphql_query.py +72 -70
- infrahub/core/schema/definitions/core/group.py +96 -93
- infrahub/core/schema/definitions/core/ipam.py +176 -235
- infrahub/core/schema/definitions/core/lineage.py +18 -16
- infrahub/core/schema/definitions/core/menu.py +42 -40
- infrahub/core/schema/definitions/core/permission.py +144 -142
- infrahub/core/schema/definitions/core/profile.py +16 -27
- infrahub/core/schema/definitions/core/propose_change.py +88 -79
- infrahub/core/schema/definitions/core/propose_change_comment.py +170 -165
- infrahub/core/schema/definitions/core/propose_change_validator.py +290 -288
- infrahub/core/schema/definitions/core/repository.py +231 -225
- infrahub/core/schema/definitions/core/resource_pool.py +156 -166
- infrahub/core/schema/definitions/core/template.py +27 -12
- infrahub/core/schema/definitions/core/transform.py +85 -76
- infrahub/core/schema/definitions/core/webhook.py +127 -101
- 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 +7 -7
- infrahub/core/schema/schema_branch.py +276 -138
- 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/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 +26 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +13 -25
- infrahub/events/branch_action.py +26 -18
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +10 -24
- infrahub/events/models.py +10 -16
- infrahub/events/node_action.py +87 -32
- 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 +23 -24
- infrahub/generators/models.py +1 -3
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +26 -25
- infrahub/git/models.py +22 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +67 -49
- 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 +6 -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 +13 -10
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/computed_attribute.py +4 -5
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +50 -70
- infrahub/graphql/mutations/main.py +164 -141
- infrahub/graphql/mutations/menu.py +5 -5
- 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 +67 -35
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +4 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/queries/diff/tree.py +4 -4
- 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/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/event.py +20 -11
- 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/menu/generator.py +7 -7
- infrahub/menu/menu.py +0 -10
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/messages/__init__.py +1 -11
- infrahub/message_bus/messages/check_generator_run.py +2 -0
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/operations/__init__.py +0 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/generator_definition.py +19 -19
- infrahub/message_bus/operations/requests/proposed_change.py +3 -1
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/tasks.py +37 -28
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +1 -2
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/task_manager/event.py +23 -9
- infrahub/tasks/artifact.py +2 -4
- 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 +2 -5
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +14 -1
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -90
- 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 +22 -5
- infrahub/webhook/tasks.py +44 -19
- infrahub/webhook/triggers.py +22 -5
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +28 -20
- infrahub/workflows/initialization.py +1 -3
- infrahub/workflows/models.py +1 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +27 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +69 -20
- 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 +10 -0
- infrahub_sdk/task/manager.py +12 -6
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +12 -4
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +3 -2
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +289 -260
- {infrahub_server-1.2.0b1.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/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/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
5
|
from graphene import InputObjectType, Mutation
|
|
6
6
|
from typing_extensions import Self
|
|
@@ -28,7 +28,7 @@ class InfrahubArtifactDefinitionMutation(InfrahubMutationMixin, Mutation):
|
|
|
28
28
|
def __init_subclass_with_meta__(
|
|
29
29
|
cls,
|
|
30
30
|
schema: NodeSchema,
|
|
31
|
-
_meta:
|
|
31
|
+
_meta: Any | None = None,
|
|
32
32
|
**options: dict[str, Any],
|
|
33
33
|
) -> None:
|
|
34
34
|
# Make sure schema is a valid NodeSchema Node Class
|
|
@@ -48,7 +48,7 @@ class InfrahubArtifactDefinitionMutation(InfrahubMutationMixin, Mutation):
|
|
|
48
48
|
info: GraphQLResolveInfo,
|
|
49
49
|
data: InputObjectType,
|
|
50
50
|
branch: Branch,
|
|
51
|
-
database:
|
|
51
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
52
52
|
) -> tuple[Node, Self]:
|
|
53
53
|
graphql_context: GraphqlContext = info.context
|
|
54
54
|
|
|
@@ -74,8 +74,8 @@ class InfrahubArtifactDefinitionMutation(InfrahubMutationMixin, Mutation):
|
|
|
74
74
|
info: GraphQLResolveInfo,
|
|
75
75
|
data: InputObjectType,
|
|
76
76
|
branch: Branch,
|
|
77
|
-
database:
|
|
78
|
-
node:
|
|
77
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
78
|
+
node: Node | None = None, # noqa: ARG003
|
|
79
79
|
) -> tuple[Node, Self]:
|
|
80
80
|
graphql_context: GraphqlContext = info.context
|
|
81
81
|
|
|
@@ -5,12 +5,12 @@ from typing import TYPE_CHECKING, Any
|
|
|
5
5
|
from graphene import Boolean, InputObjectType, Mutation, String
|
|
6
6
|
|
|
7
7
|
from infrahub.core.account import ObjectPermission
|
|
8
|
-
from infrahub.core.constants import ComputedAttributeKind,
|
|
8
|
+
from infrahub.core.constants import ComputedAttributeKind, PermissionAction, PermissionDecision
|
|
9
9
|
from infrahub.core.manager import NodeManager
|
|
10
10
|
from infrahub.core.registry import registry
|
|
11
11
|
from infrahub.database import retry_db_transaction
|
|
12
12
|
from infrahub.events import EventMeta
|
|
13
|
-
from infrahub.events.node_action import
|
|
13
|
+
from infrahub.events.node_action import NodeUpdatedEvent
|
|
14
14
|
from infrahub.exceptions import NodeNotFoundError, ValidationError
|
|
15
15
|
from infrahub.graphql.context import apply_external_context
|
|
16
16
|
from infrahub.graphql.types.context import ContextInput
|
|
@@ -95,12 +95,11 @@ class UpdateComputedAttribute(Mutation):
|
|
|
95
95
|
log_data = get_log_data()
|
|
96
96
|
request_id = log_data.get("request_id", "")
|
|
97
97
|
|
|
98
|
-
event =
|
|
98
|
+
event = NodeUpdatedEvent(
|
|
99
99
|
kind=node_schema.kind,
|
|
100
100
|
node_id=target_node.get_id(),
|
|
101
|
-
|
|
101
|
+
changelog=target_node.node_changelog.model_dump(),
|
|
102
102
|
fields=[str(data.attribute)],
|
|
103
|
-
action=MutationAction.UPDATED,
|
|
104
103
|
meta=EventMeta(
|
|
105
104
|
context=graphql_context.get_context(),
|
|
106
105
|
initiator_id=WORKER_IDENTITY,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, Any
|
|
1
|
+
from typing import TYPE_CHECKING, Any
|
|
2
2
|
|
|
3
3
|
from graphene import InputObjectType, Mutation
|
|
4
4
|
from graphql import GraphQLResolveInfo
|
|
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
|
|
|
20
20
|
class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
|
|
21
21
|
@classmethod
|
|
22
22
|
def __init_subclass_with_meta__(
|
|
23
|
-
cls, schema: NodeSchema, _meta:
|
|
23
|
+
cls, schema: NodeSchema, _meta: Any | None = None, **options: dict[str, Any]
|
|
24
24
|
) -> None:
|
|
25
25
|
# Make sure schema is a valid NodeSchema Node Class
|
|
26
26
|
if not isinstance(schema, NodeSchema):
|
|
@@ -67,7 +67,7 @@ class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
|
|
|
67
67
|
info: GraphQLResolveInfo,
|
|
68
68
|
data: InputObjectType,
|
|
69
69
|
branch: Branch,
|
|
70
|
-
database:
|
|
70
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
71
71
|
) -> tuple[Node, Self]:
|
|
72
72
|
graphql_context: GraphqlContext = info.context
|
|
73
73
|
|
|
@@ -85,8 +85,8 @@ class InfrahubGraphQLQueryMutation(InfrahubMutationMixin, Mutation):
|
|
|
85
85
|
info: GraphQLResolveInfo,
|
|
86
86
|
data: InputObjectType,
|
|
87
87
|
branch: Branch,
|
|
88
|
-
database:
|
|
89
|
-
node:
|
|
88
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
89
|
+
node: Node | None = None, # noqa: ARG003
|
|
90
90
|
) -> tuple[Node, Self]:
|
|
91
91
|
graphql_context: GraphqlContext = info.context
|
|
92
92
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ipaddress
|
|
2
2
|
from ipaddress import IPv4Interface
|
|
3
|
-
from typing import TYPE_CHECKING, Any
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
5
|
from graphene import InputObjectType, Mutation
|
|
6
6
|
from graphql import GraphQLResolveInfo
|
|
@@ -16,11 +16,11 @@ from infrahub.core.node import Node
|
|
|
16
16
|
from infrahub.core.schema import NodeSchema
|
|
17
17
|
from infrahub.database import InfrahubDatabase, retry_db_transaction
|
|
18
18
|
from infrahub.exceptions import NodeNotFoundError, ValidationError
|
|
19
|
-
from infrahub.graphql.mutations.node_getter.interface import MutationNodeGetterInterface
|
|
20
19
|
from infrahub.lock import InfrahubMultiLock, build_object_lock_name
|
|
21
20
|
from infrahub.log import get_logger
|
|
22
21
|
|
|
23
22
|
from .main import DeleteResult, InfrahubMutationMixin, InfrahubMutationOptions
|
|
23
|
+
from .node_getter.by_default_filter import MutationNodeGetterByDefaultFilter
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
26
|
from infrahub.graphql.initialization import GraphqlContext
|
|
@@ -32,10 +32,10 @@ async def validate_namespace(
|
|
|
32
32
|
db: InfrahubDatabase,
|
|
33
33
|
branch: Branch | str | None,
|
|
34
34
|
data: InputObjectType,
|
|
35
|
-
existing_namespace_id:
|
|
35
|
+
existing_namespace_id: str | None = None,
|
|
36
36
|
) -> str:
|
|
37
37
|
"""Validate or set (if not present) the namespace to pass to the mutation and return its ID."""
|
|
38
|
-
namespace_id:
|
|
38
|
+
namespace_id: str | None = None
|
|
39
39
|
if "ip_namespace" not in data or not data["ip_namespace"]:
|
|
40
40
|
namespace_id = existing_namespace_id or registry.default_ipnamespace
|
|
41
41
|
data["ip_namespace"] = {"id": namespace_id}
|
|
@@ -56,7 +56,7 @@ class InfrahubIPNamespaceMutation(InfrahubMutationMixin, Mutation):
|
|
|
56
56
|
def __init_subclass_with_meta__(
|
|
57
57
|
cls,
|
|
58
58
|
schema: NodeSchema,
|
|
59
|
-
_meta:
|
|
59
|
+
_meta: Any | None = None,
|
|
60
60
|
**options: dict[str, Any],
|
|
61
61
|
) -> None:
|
|
62
62
|
# Make sure schema is a valid NodeSchema Node Class
|
|
@@ -75,7 +75,7 @@ class InfrahubIPNamespaceMutation(InfrahubMutationMixin, Mutation):
|
|
|
75
75
|
info: GraphQLResolveInfo,
|
|
76
76
|
data: InputObjectType,
|
|
77
77
|
branch: Branch,
|
|
78
|
-
):
|
|
78
|
+
) -> DeleteResult:
|
|
79
79
|
if data["id"] == registry.default_ipnamespace:
|
|
80
80
|
raise ValueError("Cannot delete default IPAM namespace")
|
|
81
81
|
|
|
@@ -87,7 +87,7 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
|
|
|
87
87
|
def __init_subclass_with_meta__(
|
|
88
88
|
cls,
|
|
89
89
|
schema: NodeSchema,
|
|
90
|
-
_meta:
|
|
90
|
+
_meta: Any | None = None,
|
|
91
91
|
**options: dict[str, Any],
|
|
92
92
|
) -> None:
|
|
93
93
|
# Make sure schema is a valid NodeSchema Node Class
|
|
@@ -130,7 +130,7 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
|
|
|
130
130
|
info: GraphQLResolveInfo,
|
|
131
131
|
data: InputObjectType,
|
|
132
132
|
branch: Branch,
|
|
133
|
-
database:
|
|
133
|
+
database: InfrahubDatabase | None = None,
|
|
134
134
|
) -> tuple[Node, Self]:
|
|
135
135
|
graphql_context: GraphqlContext = info.context
|
|
136
136
|
db = database or graphql_context.db
|
|
@@ -176,8 +176,8 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
|
|
|
176
176
|
info: GraphQLResolveInfo,
|
|
177
177
|
data: InputObjectType,
|
|
178
178
|
branch: Branch,
|
|
179
|
-
database:
|
|
180
|
-
node:
|
|
179
|
+
database: InfrahubDatabase | None = None,
|
|
180
|
+
node: Node | None = None,
|
|
181
181
|
) -> tuple[Node, Self]:
|
|
182
182
|
graphql_context: GraphqlContext = info.context
|
|
183
183
|
db = database or graphql_context.db
|
|
@@ -192,21 +192,19 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
|
|
|
192
192
|
)
|
|
193
193
|
namespace = await address.ip_namespace.get_peer(db)
|
|
194
194
|
namespace_id = await validate_namespace(db=db, branch=branch, data=data, existing_namespace_id=namespace.id)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
reconciled_address = await cls._mutate_update_object_and_reconcile(
|
|
200
|
-
info=info, data=data, branch=branch, address=address, namespace_id=namespace_id, db=dbt
|
|
201
|
-
)
|
|
202
|
-
else:
|
|
195
|
+
|
|
196
|
+
async with db.start_transaction() as dbt:
|
|
197
|
+
if lock_name := cls._get_lock_name(namespace_id, branch):
|
|
198
|
+
async with InfrahubMultiLock(lock_registry=lock.registry, locks=[lock_name]):
|
|
203
199
|
reconciled_address = await cls._mutate_update_object_and_reconcile(
|
|
204
200
|
info=info, data=data, branch=branch, address=address, namespace_id=namespace_id, db=dbt
|
|
205
201
|
)
|
|
202
|
+
else:
|
|
203
|
+
reconciled_address = await cls._mutate_update_object_and_reconcile(
|
|
204
|
+
info=info, data=data, branch=branch, address=address, namespace_id=namespace_id, db=dbt
|
|
205
|
+
)
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
except ValidationError as exc:
|
|
209
|
-
raise ValueError(str(exc)) from exc
|
|
207
|
+
result = await cls.mutate_update_to_graphql(db=dbt, info=info, obj=reconciled_address)
|
|
210
208
|
|
|
211
209
|
return address, result
|
|
212
210
|
|
|
@@ -216,15 +214,15 @@ class InfrahubIPAddressMutation(InfrahubMutationMixin, Mutation):
|
|
|
216
214
|
info: GraphQLResolveInfo,
|
|
217
215
|
data: InputObjectType,
|
|
218
216
|
branch: Branch,
|
|
219
|
-
|
|
220
|
-
database:
|
|
217
|
+
node_getter_default_filter: MutationNodeGetterByDefaultFilter,
|
|
218
|
+
database: InfrahubDatabase | None = None,
|
|
221
219
|
) -> tuple[Node, Self, bool]:
|
|
222
220
|
graphql_context: GraphqlContext = info.context
|
|
223
221
|
db = database or graphql_context.db
|
|
224
222
|
|
|
225
223
|
await validate_namespace(db=db, branch=branch, data=data)
|
|
226
224
|
prefix, result, created = await super().mutate_upsert(
|
|
227
|
-
info=info, data=data, branch=branch,
|
|
225
|
+
info=info, data=data, branch=branch, node_getter_default_filter=node_getter_default_filter, database=db
|
|
228
226
|
)
|
|
229
227
|
|
|
230
228
|
return prefix, result, created
|
|
@@ -244,7 +242,7 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
244
242
|
def __init_subclass_with_meta__(
|
|
245
243
|
cls,
|
|
246
244
|
schema: NodeSchema,
|
|
247
|
-
_meta:
|
|
245
|
+
_meta: Any | None = None,
|
|
248
246
|
**options: dict[str, Any],
|
|
249
247
|
) -> None:
|
|
250
248
|
# Make sure schema is a valid NodeSchema Node Class
|
|
@@ -258,10 +256,10 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
258
256
|
super().__init_subclass_with_meta__(_meta=_meta, **options)
|
|
259
257
|
|
|
260
258
|
@staticmethod
|
|
261
|
-
def _get_lock_name(namespace_id: str
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
259
|
+
def _get_lock_name(namespace_id: str) -> str | None:
|
|
260
|
+
# IPPrefix has some cardinality-one relationships involved (parent/child/ip_address),
|
|
261
|
+
# so we need to lock on any branch to avoid creating multiple peers for these relationships
|
|
262
|
+
# during concurrent ipam reconciliations.
|
|
265
263
|
return build_object_lock_name(InfrahubKind.IPPREFIX + "_" + namespace_id)
|
|
266
264
|
|
|
267
265
|
@classmethod
|
|
@@ -284,19 +282,15 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
284
282
|
info: GraphQLResolveInfo,
|
|
285
283
|
data: InputObjectType,
|
|
286
284
|
branch: Branch,
|
|
287
|
-
database:
|
|
285
|
+
database: InfrahubDatabase | None = None,
|
|
288
286
|
) -> tuple[Node, Self]:
|
|
289
287
|
graphql_context: GraphqlContext = info.context
|
|
290
288
|
db = database or graphql_context.db
|
|
291
289
|
namespace_id = await validate_namespace(db=db, branch=branch, data=data)
|
|
292
290
|
|
|
293
291
|
async with db.start_transaction() as dbt:
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
reconciled_prefix = await cls._mutate_create_object_and_reconcile(
|
|
297
|
-
data=data, branch=branch, db=dbt, namespace_id=namespace_id
|
|
298
|
-
)
|
|
299
|
-
else:
|
|
292
|
+
lock_name = cls._get_lock_name(namespace_id)
|
|
293
|
+
async with InfrahubMultiLock(lock_registry=lock.registry, locks=[lock_name]):
|
|
300
294
|
reconciled_prefix = await cls._mutate_create_object_and_reconcile(
|
|
301
295
|
data=data, branch=branch, db=dbt, namespace_id=namespace_id
|
|
302
296
|
)
|
|
@@ -327,8 +321,8 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
327
321
|
info: GraphQLResolveInfo,
|
|
328
322
|
data: InputObjectType,
|
|
329
323
|
branch: Branch,
|
|
330
|
-
database:
|
|
331
|
-
node:
|
|
324
|
+
database: InfrahubDatabase | None = None,
|
|
325
|
+
node: Node | None = None,
|
|
332
326
|
) -> tuple[Node, Self]:
|
|
333
327
|
graphql_context: GraphqlContext = info.context
|
|
334
328
|
db = database or graphql_context.db
|
|
@@ -343,20 +337,14 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
343
337
|
)
|
|
344
338
|
namespace = await prefix.ip_namespace.get_peer(db)
|
|
345
339
|
namespace_id = await validate_namespace(db=db, branch=branch, data=data, existing_namespace_id=namespace.id)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
reconciled_prefix = await cls._mutate_update_object_and_reconcile(
|
|
355
|
-
info=info, data=data, prefix=prefix, db=dbt, namespace_id=namespace_id, branch=branch
|
|
356
|
-
)
|
|
357
|
-
result = await cls.mutate_update_to_graphql(db=dbt, info=info, obj=reconciled_prefix)
|
|
358
|
-
except ValidationError as exc:
|
|
359
|
-
raise ValueError(str(exc)) from exc
|
|
340
|
+
|
|
341
|
+
async with db.start_transaction() as dbt:
|
|
342
|
+
lock_name = cls._get_lock_name(namespace_id)
|
|
343
|
+
async with InfrahubMultiLock(lock_registry=lock.registry, locks=[lock_name]):
|
|
344
|
+
reconciled_prefix = await cls._mutate_update_object_and_reconcile(
|
|
345
|
+
info=info, data=data, prefix=prefix, db=dbt, namespace_id=namespace_id, branch=branch
|
|
346
|
+
)
|
|
347
|
+
result = await cls.mutate_update_to_graphql(db=dbt, info=info, obj=reconciled_prefix)
|
|
360
348
|
|
|
361
349
|
return prefix, result
|
|
362
350
|
|
|
@@ -366,15 +354,15 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
366
354
|
info: GraphQLResolveInfo,
|
|
367
355
|
data: InputObjectType,
|
|
368
356
|
branch: Branch,
|
|
369
|
-
|
|
370
|
-
database:
|
|
371
|
-
):
|
|
357
|
+
node_getter_default_filter: MutationNodeGetterByDefaultFilter,
|
|
358
|
+
database: InfrahubDatabase | None = None,
|
|
359
|
+
) -> tuple[Node, Self, bool]:
|
|
372
360
|
graphql_context: GraphqlContext = info.context
|
|
373
361
|
db = database or graphql_context.db
|
|
374
362
|
|
|
375
363
|
await validate_namespace(db=db, branch=branch, data=data)
|
|
376
364
|
prefix, result, created = await super().mutate_upsert(
|
|
377
|
-
info=info, data=data, branch=branch,
|
|
365
|
+
info=info, data=data, branch=branch, node_getter_default_filter=node_getter_default_filter, database=db
|
|
378
366
|
)
|
|
379
367
|
|
|
380
368
|
return prefix, result, created
|
|
@@ -414,21 +402,13 @@ class InfrahubIPPrefixMutation(InfrahubMutationMixin, Mutation):
|
|
|
414
402
|
|
|
415
403
|
namespace_rels = await prefix.ip_namespace.get_relationships(db=db)
|
|
416
404
|
namespace_id = namespace_rels[0].peer_id
|
|
417
|
-
try:
|
|
418
|
-
async with graphql_context.db.start_transaction() as dbt:
|
|
419
|
-
if lock_name := cls._get_lock_name(namespace_id, branch):
|
|
420
|
-
async with InfrahubMultiLock(lock_registry=lock.registry, locks=[lock_name]):
|
|
421
|
-
reconciled_prefix = await cls._reconcile_prefix(
|
|
422
|
-
branch=branch, db=dbt, prefix=prefix, namespace_id=namespace_id, is_delete=True
|
|
423
|
-
)
|
|
424
|
-
else:
|
|
425
|
-
reconciled_prefix = await cls._reconcile_prefix(
|
|
426
|
-
branch=branch, db=dbt, prefix=prefix, namespace_id=namespace_id, is_delete=True
|
|
427
|
-
)
|
|
428
|
-
|
|
429
|
-
except ValidationError as exc:
|
|
430
|
-
raise ValueError(str(exc)) from exc
|
|
431
405
|
|
|
406
|
+
async with graphql_context.db.start_transaction() as dbt:
|
|
407
|
+
lock_name = cls._get_lock_name(namespace_id)
|
|
408
|
+
async with InfrahubMultiLock(lock_registry=lock.registry, locks=[lock_name]):
|
|
409
|
+
reconciled_prefix = await cls._reconcile_prefix(
|
|
410
|
+
branch=branch, db=dbt, prefix=prefix, namespace_id=namespace_id, is_delete=True
|
|
411
|
+
)
|
|
432
412
|
ok = True
|
|
433
413
|
|
|
434
414
|
return DeleteResult(node=reconciled_prefix, mutation=cls(ok=ok))
|