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,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Mapping
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Mapping
|
|
5
5
|
|
|
6
6
|
from graphene import InputObjectType, Mutation
|
|
7
7
|
from graphene.types.mutation import MutationOptions
|
|
@@ -10,7 +10,6 @@ from typing_extensions import Self
|
|
|
10
10
|
|
|
11
11
|
from infrahub import config, lock
|
|
12
12
|
from infrahub.core import registry
|
|
13
|
-
from infrahub.core.changelog.models import RelationshipChangelogGetter
|
|
14
13
|
from infrahub.core.constants import InfrahubKind, MutationAction, RelationshipCardinality, RelationshipKind
|
|
15
14
|
from infrahub.core.constraint.node.runner import NodeConstraintRunner
|
|
16
15
|
from infrahub.core.manager import NodeManager
|
|
@@ -22,16 +21,13 @@ from infrahub.core.schema.template_schema import TemplateSchema
|
|
|
22
21
|
from infrahub.core.timestamp import Timestamp
|
|
23
22
|
from infrahub.database import retry_db_transaction
|
|
24
23
|
from infrahub.dependencies.registry import get_component_registry
|
|
25
|
-
from infrahub.events import
|
|
26
|
-
from infrahub.exceptions import
|
|
24
|
+
from infrahub.events.generator import generate_node_mutation_events
|
|
25
|
+
from infrahub.exceptions import HFIDViolatedError, InitializationError
|
|
27
26
|
from infrahub.graphql.context import apply_external_context
|
|
28
27
|
from infrahub.lock import InfrahubMultiLock, build_object_lock_name
|
|
29
28
|
from infrahub.log import get_log_data, get_logger
|
|
30
|
-
from infrahub.worker import WORKER_IDENTITY
|
|
31
29
|
|
|
32
30
|
from .node_getter.by_default_filter import MutationNodeGetterByDefaultFilter
|
|
33
|
-
from .node_getter.by_hfid import MutationNodeGetterByHfid
|
|
34
|
-
from .node_getter.by_id import MutationNodeGetterById
|
|
35
31
|
|
|
36
32
|
if TYPE_CHECKING:
|
|
37
33
|
from graphql import GraphQLResolveInfo
|
|
@@ -44,7 +40,6 @@ if TYPE_CHECKING:
|
|
|
44
40
|
from infrahub.graphql.types.context import ContextInput
|
|
45
41
|
|
|
46
42
|
from ..initialization import GraphqlContext
|
|
47
|
-
from .node_getter.interface import MutationNodeGetterInterface
|
|
48
43
|
|
|
49
44
|
|
|
50
45
|
log = get_logger()
|
|
@@ -63,10 +58,18 @@ class DeleteResult:
|
|
|
63
58
|
# Infrahub GraphQLType
|
|
64
59
|
# ------------------------------------------
|
|
65
60
|
class InfrahubMutationOptions(MutationOptions):
|
|
66
|
-
schema:
|
|
61
|
+
schema: MainSchemaTypes | None = None
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def active_schema(self) -> MainSchemaTypes:
|
|
65
|
+
if self.schema:
|
|
66
|
+
return self.schema
|
|
67
|
+
raise InitializationError("This class is not initialized with a schema")
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
class InfrahubMutationMixin:
|
|
71
|
+
_meta: InfrahubMutationOptions
|
|
72
|
+
|
|
70
73
|
@classmethod
|
|
71
74
|
async def mutate(
|
|
72
75
|
cls,
|
|
@@ -74,9 +77,8 @@ class InfrahubMutationMixin:
|
|
|
74
77
|
info: GraphQLResolveInfo,
|
|
75
78
|
data: InputObjectType,
|
|
76
79
|
context: ContextInput | None = None,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
):
|
|
80
|
+
**kwargs: dict[str, Any],
|
|
81
|
+
) -> Self:
|
|
80
82
|
graphql_context: GraphqlContext = info.context
|
|
81
83
|
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
82
84
|
|
|
@@ -86,20 +88,22 @@ class InfrahubMutationMixin:
|
|
|
86
88
|
deleted_nodes: list[Node] = []
|
|
87
89
|
|
|
88
90
|
if "Create" in cls.__name__:
|
|
89
|
-
obj, mutation = await cls.mutate_create(info=info, branch=graphql_context.branch, data=data
|
|
91
|
+
obj, mutation = await cls.mutate_create(info=info, branch=graphql_context.branch, data=data)
|
|
90
92
|
action = MutationAction.CREATED
|
|
91
93
|
elif "Update" in cls.__name__:
|
|
92
94
|
obj, mutation = await cls.mutate_update(info=info, branch=graphql_context.branch, data=data, **kwargs)
|
|
93
95
|
action = MutationAction.UPDATED
|
|
94
96
|
elif "Upsert" in cls.__name__:
|
|
95
97
|
node_manager = NodeManager()
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
MutationNodeGetterByDefaultFilter(db=graphql_context.db, node_manager=node_manager),
|
|
100
|
-
]
|
|
98
|
+
node_getter_default_filter = MutationNodeGetterByDefaultFilter(
|
|
99
|
+
db=graphql_context.db, node_manager=node_manager
|
|
100
|
+
)
|
|
101
101
|
obj, mutation, created = await cls.mutate_upsert(
|
|
102
|
-
info=info,
|
|
102
|
+
info=info,
|
|
103
|
+
branch=graphql_context.branch,
|
|
104
|
+
data=data,
|
|
105
|
+
node_getter_default_filter=node_getter_default_filter,
|
|
106
|
+
**kwargs,
|
|
103
107
|
)
|
|
104
108
|
if created:
|
|
105
109
|
action = MutationAction.CREATED
|
|
@@ -124,57 +128,15 @@ class InfrahubMutationMixin:
|
|
|
124
128
|
log_data = get_log_data()
|
|
125
129
|
request_id = log_data.get("request_id", "")
|
|
126
130
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
meta = EventMeta(
|
|
132
|
-
account_id=account_id,
|
|
133
|
-
initiator_id=WORKER_IDENTITY,
|
|
134
|
-
request_id=request_id,
|
|
131
|
+
events = await generate_node_mutation_events(
|
|
132
|
+
node=obj,
|
|
133
|
+
deleted_nodes=deleted_nodes,
|
|
134
|
+
db=graphql_context.db,
|
|
135
135
|
branch=graphql_context.branch,
|
|
136
136
|
context=graphql_context.get_context(),
|
|
137
|
-
|
|
138
|
-
main_event = NodeMutatedEvent(
|
|
139
|
-
kind=obj._schema.kind,
|
|
140
|
-
node_id=obj.id,
|
|
141
|
-
data=obj.node_changelog,
|
|
137
|
+
request_id=request_id,
|
|
142
138
|
action=action,
|
|
143
|
-
fields=_get_data_fields(data),
|
|
144
|
-
meta=meta,
|
|
145
139
|
)
|
|
146
|
-
relationship_changelogs = RelationshipChangelogGetter(db=graphql_context.db, branch=graphql_context.branch)
|
|
147
|
-
node_changelogs = await relationship_changelogs.get_changelogs(primary_changelog=obj.node_changelog)
|
|
148
|
-
|
|
149
|
-
events = [main_event]
|
|
150
|
-
|
|
151
|
-
deleted_changelogs = [node.node_changelog for node in deleted_nodes if node.id != obj.id]
|
|
152
|
-
deleted_ids = {node.node_id for node in deleted_changelogs}
|
|
153
|
-
|
|
154
|
-
for node_changelog in deleted_changelogs:
|
|
155
|
-
meta = EventMeta.from_parent(parent=main_event)
|
|
156
|
-
event = NodeMutatedEvent(
|
|
157
|
-
kind=node_changelog.node_kind,
|
|
158
|
-
node_id=node_changelog.node_id,
|
|
159
|
-
data=node_changelog,
|
|
160
|
-
action=MutationAction.DELETED,
|
|
161
|
-
fields=node_changelog.updated_fields,
|
|
162
|
-
meta=meta,
|
|
163
|
-
)
|
|
164
|
-
events.append(event)
|
|
165
|
-
|
|
166
|
-
for node_changelog in node_changelogs:
|
|
167
|
-
if node_changelog.node_id not in deleted_ids:
|
|
168
|
-
meta = EventMeta.from_parent(parent=main_event)
|
|
169
|
-
event = NodeMutatedEvent(
|
|
170
|
-
kind=node_changelog.node_kind,
|
|
171
|
-
node_id=node_changelog.node_id,
|
|
172
|
-
data=node_changelog,
|
|
173
|
-
action=MutationAction.UPDATED,
|
|
174
|
-
fields=node_changelog.updated_fields,
|
|
175
|
-
meta=meta,
|
|
176
|
-
)
|
|
177
|
-
events.append(event)
|
|
178
140
|
|
|
179
141
|
for event in events:
|
|
180
142
|
graphql_context.background.add_task(graphql_context.active_service.event.send, event)
|
|
@@ -190,7 +152,7 @@ class InfrahubMutationMixin:
|
|
|
190
152
|
|
|
191
153
|
@classmethod
|
|
192
154
|
async def _refresh_for_profile_update(
|
|
193
|
-
cls, db: InfrahubDatabase, branch: Branch, obj: Node, previous_profile_ids:
|
|
155
|
+
cls, db: InfrahubDatabase, branch: Branch, obj: Node, previous_profile_ids: set[str] | None = None
|
|
194
156
|
) -> Node:
|
|
195
157
|
if not hasattr(obj, "profiles"):
|
|
196
158
|
return obj
|
|
@@ -198,7 +160,7 @@ class InfrahubMutationMixin:
|
|
|
198
160
|
if previous_profile_ids is None or previous_profile_ids != current_profile_ids:
|
|
199
161
|
refreshed_node = await NodeManager.get_one_by_id_or_default_filter(
|
|
200
162
|
db=db,
|
|
201
|
-
kind=cls._meta.
|
|
163
|
+
kind=cls._meta.active_schema.kind,
|
|
202
164
|
id=obj.get_id(),
|
|
203
165
|
branch=branch,
|
|
204
166
|
include_owner=True,
|
|
@@ -209,13 +171,13 @@ class InfrahubMutationMixin:
|
|
|
209
171
|
return obj
|
|
210
172
|
|
|
211
173
|
@classmethod
|
|
212
|
-
async def _call_mutate_create_object(cls, data: InputObjectType, db: InfrahubDatabase, branch: Branch):
|
|
174
|
+
async def _call_mutate_create_object(cls, data: InputObjectType, db: InfrahubDatabase, branch: Branch) -> Node:
|
|
213
175
|
"""
|
|
214
176
|
Wrapper around mutate_create_object to potentially activate locking.
|
|
215
177
|
"""
|
|
216
178
|
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
217
179
|
lock_names = _get_kind_lock_names_on_object_mutation(
|
|
218
|
-
kind=cls._meta.
|
|
180
|
+
kind=cls._meta.active_schema.kind, branch=branch, schema_branch=schema_branch
|
|
219
181
|
)
|
|
220
182
|
if lock_names:
|
|
221
183
|
async with InfrahubMultiLock(lock_registry=lock.registry, locks=lock_names):
|
|
@@ -288,8 +250,13 @@ class InfrahubMutationMixin:
|
|
|
288
250
|
if not template_relationship_peers:
|
|
289
251
|
continue
|
|
290
252
|
|
|
291
|
-
obj_peer_schema = relationship.get_peer_schema(db=db, branch=branch)
|
|
292
253
|
for template_relationship_peer in template_relationship_peers.values():
|
|
254
|
+
# We retrieve peer schema for each peer in case we are processing a relationship which is based on a generic
|
|
255
|
+
obj_peer_schema = registry.schema.get_node_schema(
|
|
256
|
+
name=template_relationship_peer.get_schema().kind.removeprefix("Template"),
|
|
257
|
+
branch=branch,
|
|
258
|
+
duplicate=False,
|
|
259
|
+
)
|
|
293
260
|
obj_peer_data = await cls._extract_peer_data(
|
|
294
261
|
db=db,
|
|
295
262
|
template_peer=template_relationship_peer,
|
|
@@ -298,7 +265,7 @@ class InfrahubMutationMixin:
|
|
|
298
265
|
current_template=template,
|
|
299
266
|
)
|
|
300
267
|
|
|
301
|
-
obj_peer = await Node.init(schema=obj_peer_schema, db=db)
|
|
268
|
+
obj_peer = await Node.init(schema=obj_peer_schema, db=db, branch=branch)
|
|
302
269
|
await obj_peer.new(db=db, **obj_peer_data)
|
|
303
270
|
await constraint_runner.check(node=obj_peer, field_filters=list(obj_peer_data))
|
|
304
271
|
await obj_peer.save(db=db)
|
|
@@ -318,7 +285,7 @@ class InfrahubMutationMixin:
|
|
|
318
285
|
info: GraphQLResolveInfo,
|
|
319
286
|
data: InputObjectType,
|
|
320
287
|
branch: Branch,
|
|
321
|
-
database:
|
|
288
|
+
database: InfrahubDatabase | None = None,
|
|
322
289
|
) -> tuple[Node, Self]:
|
|
323
290
|
graphql_context: GraphqlContext = info.context
|
|
324
291
|
db = database or graphql_context.db
|
|
@@ -339,44 +306,41 @@ class InfrahubMutationMixin:
|
|
|
339
306
|
NodeConstraintRunner, db=db.start_session(), branch=branch
|
|
340
307
|
)
|
|
341
308
|
node_class = Node
|
|
342
|
-
if cls._meta.
|
|
343
|
-
node_class = registry.node[cls._meta.
|
|
309
|
+
if cls._meta.active_schema.kind in registry.node:
|
|
310
|
+
node_class = registry.node[cls._meta.active_schema.kind]
|
|
344
311
|
|
|
345
312
|
fields_to_validate = list(data)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
313
|
+
if db.is_transaction:
|
|
314
|
+
obj = await node_class.init(db=db, schema=cls._meta.schema, branch=branch)
|
|
315
|
+
await obj.new(db=db, **data)
|
|
316
|
+
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
317
|
+
await obj.save(db=db)
|
|
318
|
+
|
|
319
|
+
object_template = await obj.get_object_template(db=db)
|
|
320
|
+
if object_template:
|
|
321
|
+
await cls._handle_template_relationships(
|
|
322
|
+
db=db,
|
|
323
|
+
branch=branch,
|
|
324
|
+
template=object_template,
|
|
325
|
+
obj=obj,
|
|
326
|
+
data=data,
|
|
327
|
+
)
|
|
328
|
+
else:
|
|
329
|
+
async with db.start_transaction() as dbt:
|
|
330
|
+
obj = await node_class.init(db=dbt, schema=cls._meta.schema, branch=branch)
|
|
331
|
+
await obj.new(db=dbt, **data)
|
|
350
332
|
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
351
|
-
await obj.save(db=
|
|
333
|
+
await obj.save(db=dbt)
|
|
352
334
|
|
|
353
|
-
object_template = await obj.get_object_template(db=
|
|
335
|
+
object_template = await obj.get_object_template(db=dbt)
|
|
354
336
|
if object_template:
|
|
355
337
|
await cls._handle_template_relationships(
|
|
356
|
-
db=
|
|
338
|
+
db=dbt,
|
|
357
339
|
branch=branch,
|
|
358
340
|
template=object_template,
|
|
359
341
|
obj=obj,
|
|
360
342
|
data=data,
|
|
361
343
|
)
|
|
362
|
-
else:
|
|
363
|
-
async with db.start_transaction() as dbt:
|
|
364
|
-
obj = await node_class.init(db=dbt, schema=cls._meta.schema, branch=branch)
|
|
365
|
-
await obj.new(db=dbt, **data)
|
|
366
|
-
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
367
|
-
await obj.save(db=dbt)
|
|
368
|
-
|
|
369
|
-
object_template = await obj.get_object_template(db=dbt)
|
|
370
|
-
if object_template:
|
|
371
|
-
await cls._handle_template_relationships(
|
|
372
|
-
db=dbt,
|
|
373
|
-
branch=branch,
|
|
374
|
-
template=object_template,
|
|
375
|
-
obj=obj,
|
|
376
|
-
data=data,
|
|
377
|
-
)
|
|
378
|
-
except ValidationError as exc:
|
|
379
|
-
raise ValidationError(input_value=str(exc)) from exc
|
|
380
344
|
|
|
381
345
|
if await cls._get_profile_ids(db=db, obj=obj):
|
|
382
346
|
obj = await cls._refresh_for_profile_update(db=db, branch=branch, obj=obj)
|
|
@@ -386,7 +350,7 @@ class InfrahubMutationMixin:
|
|
|
386
350
|
@classmethod
|
|
387
351
|
async def mutate_create_to_graphql(cls, info: GraphQLResolveInfo, db: InfrahubDatabase, obj: Node) -> Self:
|
|
388
352
|
fields = await extract_fields(info.field_nodes[0].selection_set)
|
|
389
|
-
result = {"ok": True}
|
|
353
|
+
result: dict[str, Any] = {"ok": True}
|
|
390
354
|
if "object" in fields:
|
|
391
355
|
result["object"] = await obj.to_graphql(db=db, fields=fields.get("object", {}))
|
|
392
356
|
return cls(**result)
|
|
@@ -399,6 +363,7 @@ class InfrahubMutationMixin:
|
|
|
399
363
|
branch: Branch,
|
|
400
364
|
db: InfrahubDatabase,
|
|
401
365
|
obj: Node,
|
|
366
|
+
run_constraint_checks: bool = True,
|
|
402
367
|
) -> tuple[Node, Self]:
|
|
403
368
|
"""
|
|
404
369
|
Wrapper around mutate_update to potentially activate locking and call it within a database transaction.
|
|
@@ -406,24 +371,37 @@ class InfrahubMutationMixin:
|
|
|
406
371
|
|
|
407
372
|
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
408
373
|
lock_names = _get_kind_lock_names_on_object_mutation(
|
|
409
|
-
kind=cls._meta.
|
|
374
|
+
kind=cls._meta.active_schema.kind, branch=branch, schema_branch=schema_branch
|
|
410
375
|
)
|
|
411
376
|
|
|
412
377
|
if db.is_transaction:
|
|
413
378
|
if lock_names:
|
|
414
379
|
async with InfrahubMultiLock(lock_registry=lock.registry, locks=lock_names):
|
|
415
|
-
obj = await cls.mutate_update_object(
|
|
380
|
+
obj = await cls.mutate_update_object(
|
|
381
|
+
db=db, info=info, data=data, branch=branch, obj=obj, run_constraint_checks=run_constraint_checks
|
|
382
|
+
)
|
|
416
383
|
else:
|
|
417
|
-
obj = await cls.mutate_update_object(
|
|
384
|
+
obj = await cls.mutate_update_object(
|
|
385
|
+
db=db, info=info, data=data, branch=branch, obj=obj, run_constraint_checks=run_constraint_checks
|
|
386
|
+
)
|
|
418
387
|
result = await cls.mutate_update_to_graphql(db=db, info=info, obj=obj)
|
|
419
388
|
return obj, result
|
|
420
389
|
|
|
421
390
|
async with db.start_transaction() as dbt:
|
|
422
391
|
if lock_names:
|
|
423
392
|
async with InfrahubMultiLock(lock_registry=lock.registry, locks=lock_names):
|
|
424
|
-
obj = await cls.mutate_update_object(
|
|
393
|
+
obj = await cls.mutate_update_object(
|
|
394
|
+
db=dbt,
|
|
395
|
+
info=info,
|
|
396
|
+
data=data,
|
|
397
|
+
branch=branch,
|
|
398
|
+
obj=obj,
|
|
399
|
+
run_constraint_checks=run_constraint_checks,
|
|
400
|
+
)
|
|
425
401
|
else:
|
|
426
|
-
obj = await cls.mutate_update_object(
|
|
402
|
+
obj = await cls.mutate_update_object(
|
|
403
|
+
db=dbt, info=info, data=data, branch=branch, obj=obj, run_constraint_checks=run_constraint_checks
|
|
404
|
+
)
|
|
427
405
|
result = await cls.mutate_update_to_graphql(db=dbt, info=info, obj=obj)
|
|
428
406
|
return obj, result
|
|
429
407
|
|
|
@@ -434,20 +412,17 @@ class InfrahubMutationMixin:
|
|
|
434
412
|
info: GraphQLResolveInfo,
|
|
435
413
|
data: InputObjectType,
|
|
436
414
|
branch: Branch,
|
|
437
|
-
database:
|
|
438
|
-
node:
|
|
415
|
+
database: InfrahubDatabase | None = None,
|
|
416
|
+
node: Node | None = None,
|
|
439
417
|
) -> tuple[Node, Self]:
|
|
440
418
|
graphql_context: GraphqlContext = info.context
|
|
441
419
|
db = database or graphql_context.db
|
|
442
420
|
|
|
443
421
|
obj = node or await NodeManager.find_object(
|
|
444
|
-
db=db, kind=cls._meta.
|
|
422
|
+
db=db, kind=cls._meta.active_schema.kind, id=data.get("id"), hfid=data.get("hfid"), branch=branch
|
|
445
423
|
)
|
|
446
424
|
|
|
447
|
-
|
|
448
|
-
obj, result = await cls._call_mutate_update(info=info, data=data, db=db, branch=branch, obj=obj)
|
|
449
|
-
except ValidationError as exc:
|
|
450
|
-
raise ValueError(str(exc)) from exc
|
|
425
|
+
obj, result = await cls._call_mutate_update(info=info, data=data, db=db, branch=branch, obj=obj)
|
|
451
426
|
|
|
452
427
|
return obj, result
|
|
453
428
|
|
|
@@ -459,6 +434,7 @@ class InfrahubMutationMixin:
|
|
|
459
434
|
data: InputObjectType,
|
|
460
435
|
branch: Branch,
|
|
461
436
|
obj: Node,
|
|
437
|
+
run_constraint_checks: bool = True,
|
|
462
438
|
) -> Node:
|
|
463
439
|
component_registry = get_component_registry()
|
|
464
440
|
node_constraint_runner = await component_registry.get_component(NodeConstraintRunner, db=db, branch=branch)
|
|
@@ -466,7 +442,8 @@ class InfrahubMutationMixin:
|
|
|
466
442
|
before_mutate_profile_ids = await cls._get_profile_ids(db=db, obj=obj)
|
|
467
443
|
await obj.from_graphql(db=db, data=data)
|
|
468
444
|
fields_to_validate = list(data)
|
|
469
|
-
|
|
445
|
+
if run_constraint_checks:
|
|
446
|
+
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
470
447
|
|
|
471
448
|
fields = list(data.keys())
|
|
472
449
|
for field_to_remove in ("id", "hfid"):
|
|
@@ -489,7 +466,7 @@ class InfrahubMutationMixin:
|
|
|
489
466
|
) -> Self:
|
|
490
467
|
fields_object = await extract_fields(info.field_nodes[0].selection_set)
|
|
491
468
|
fields_object = fields_object.get("object", {})
|
|
492
|
-
result = {"ok": True}
|
|
469
|
+
result: dict[str, Any] = {"ok": True}
|
|
493
470
|
if fields_object:
|
|
494
471
|
result["object"] = await obj.to_graphql(db=db, fields=fields_object)
|
|
495
472
|
return cls(**result)
|
|
@@ -501,31 +478,76 @@ class InfrahubMutationMixin:
|
|
|
501
478
|
info: GraphQLResolveInfo,
|
|
502
479
|
data: InputObjectType,
|
|
503
480
|
branch: Branch,
|
|
504
|
-
|
|
505
|
-
database:
|
|
481
|
+
node_getter_default_filter: MutationNodeGetterByDefaultFilter,
|
|
482
|
+
database: InfrahubDatabase | None = None,
|
|
506
483
|
) -> tuple[Node, Self, bool]:
|
|
507
|
-
|
|
484
|
+
"""
|
|
485
|
+
First, check whether payload contains data identifying the node, such as id, hfid, or relevant fields for
|
|
486
|
+
default_filter. If not, we will try to create the node, but this creation might fail if payload contains
|
|
487
|
+
hfid fields (not `hfid` field itself) that would match an existing node in the database. In that case,
|
|
488
|
+
we would update the node without rerunning uniqueness constraint.
|
|
489
|
+
"""
|
|
490
|
+
|
|
491
|
+
schema_name = cls._meta.active_schema.kind
|
|
508
492
|
|
|
509
493
|
graphql_context: GraphqlContext = info.context
|
|
510
494
|
db = database or graphql_context.db
|
|
511
|
-
|
|
512
|
-
node_schema = db.schema.get(name=schema_name, branch=branch)
|
|
513
|
-
|
|
495
|
+
dict_data = dict(data)
|
|
514
496
|
node = None
|
|
515
|
-
|
|
516
|
-
node = await getter.get_node(node_schema=node_schema, data=data, branch=branch)
|
|
517
|
-
if node:
|
|
518
|
-
break
|
|
497
|
+
run_constraint_checks = True
|
|
519
498
|
|
|
520
|
-
if
|
|
521
|
-
|
|
499
|
+
if "id" in dict_data:
|
|
500
|
+
node = await NodeManager.get_one(
|
|
501
|
+
db=db, id=dict_data["id"], kind=schema_name, branch=branch, raise_on_error=True
|
|
502
|
+
)
|
|
503
|
+
updated_obj, mutation = await cls._call_mutate_update(
|
|
504
|
+
info=info,
|
|
505
|
+
data=data,
|
|
506
|
+
db=db,
|
|
507
|
+
branch=branch,
|
|
508
|
+
obj=node,
|
|
509
|
+
run_constraint_checks=run_constraint_checks,
|
|
510
|
+
)
|
|
522
511
|
return updated_obj, mutation, False
|
|
523
|
-
|
|
524
|
-
|
|
512
|
+
|
|
513
|
+
if cls._meta.active_schema.default_filter is not None:
|
|
514
|
+
node = await node_getter_default_filter.get_node(
|
|
515
|
+
node_schema=cls._meta.active_schema, data=data, branch=branch
|
|
516
|
+
)
|
|
517
|
+
|
|
525
518
|
if "hfid" in data:
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
519
|
+
node = await NodeManager.get_one_by_hfid(db=db, hfid=dict_data["hfid"], kind=schema_name, branch=branch)
|
|
520
|
+
|
|
521
|
+
if node is not None:
|
|
522
|
+
updated_obj, mutation = await cls._call_mutate_update(
|
|
523
|
+
info=info,
|
|
524
|
+
data=data,
|
|
525
|
+
db=db,
|
|
526
|
+
branch=branch,
|
|
527
|
+
obj=node,
|
|
528
|
+
run_constraint_checks=run_constraint_checks,
|
|
529
|
+
)
|
|
530
|
+
return updated_obj, mutation, False
|
|
531
|
+
|
|
532
|
+
try:
|
|
533
|
+
dict_data.pop("hfid", "unused") # `hfid` is invalid for creation.
|
|
534
|
+
created_obj, mutation = await cls.mutate_create(info=info, data=dict_data, branch=branch)
|
|
535
|
+
return created_obj, mutation, True
|
|
536
|
+
except HFIDViolatedError as exc:
|
|
537
|
+
# Only the HFID constraint has been violated, it means the node exists and we can update without rerunning constraints
|
|
538
|
+
if len(exc.matching_nodes_ids) > 1:
|
|
539
|
+
raise RuntimeError(f"Multiple {schema_name} nodes have the same hfid (database corrupted)") from exc
|
|
540
|
+
node_id = list(exc.matching_nodes_ids)[0]
|
|
541
|
+
node = await NodeManager.get_one(db=db, id=node_id, kind=schema_name, branch=branch, raise_on_error=True)
|
|
542
|
+
updated_obj, mutation = await cls._call_mutate_update(
|
|
543
|
+
info=info,
|
|
544
|
+
data=data,
|
|
545
|
+
db=db,
|
|
546
|
+
branch=branch,
|
|
547
|
+
obj=node,
|
|
548
|
+
run_constraint_checks=run_constraint_checks,
|
|
549
|
+
)
|
|
550
|
+
return updated_obj, mutation, False
|
|
529
551
|
|
|
530
552
|
@classmethod
|
|
531
553
|
@retry_db_transaction(name="object_delete")
|
|
@@ -538,14 +560,15 @@ class InfrahubMutationMixin:
|
|
|
538
560
|
graphql_context: GraphqlContext = info.context
|
|
539
561
|
|
|
540
562
|
obj = await NodeManager.find_object(
|
|
541
|
-
db=graphql_context.db,
|
|
563
|
+
db=graphql_context.db,
|
|
564
|
+
kind=cls._meta.active_schema.kind,
|
|
565
|
+
id=data.get("id"),
|
|
566
|
+
hfid=data.get("hfid"),
|
|
567
|
+
branch=branch,
|
|
542
568
|
)
|
|
543
569
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
deleted = await NodeManager.delete(db=db, branch=branch, nodes=[obj])
|
|
547
|
-
except ValidationError as exc:
|
|
548
|
-
raise ValueError(str(exc)) from exc
|
|
570
|
+
async with graphql_context.db.start_transaction() as db:
|
|
571
|
+
deleted = await NodeManager.delete(db=db, branch=branch, nodes=[obj])
|
|
549
572
|
|
|
550
573
|
deleted_str = ", ".join([f"{d.get_kind()}({d.get_id()})" for d in deleted])
|
|
551
574
|
log.info(f"nodes deleted: {deleted_str}")
|
|
@@ -559,9 +582,9 @@ class InfrahubMutation(InfrahubMutationMixin, Mutation):
|
|
|
559
582
|
@classmethod
|
|
560
583
|
def __init_subclass_with_meta__(
|
|
561
584
|
cls,
|
|
562
|
-
schema:
|
|
563
|
-
_meta=None,
|
|
564
|
-
**options,
|
|
585
|
+
schema: NodeSchema | GenericSchema | ProfileSchema | TemplateSchema | None = None,
|
|
586
|
+
_meta: InfrahubMutationOptions | None = None,
|
|
587
|
+
**options: dict[str, Any],
|
|
565
588
|
) -> None:
|
|
566
589
|
# Make sure schema is a valid NodeSchema Node Class
|
|
567
590
|
if not isinstance(schema, NodeSchema | GenericSchema | ProfileSchema | TemplateSchema):
|
|
@@ -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
|
|
@@ -35,7 +35,7 @@ def validate_namespace(data: InputObjectType) -> None:
|
|
|
35
35
|
class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
36
36
|
@classmethod
|
|
37
37
|
def __init_subclass_with_meta__(
|
|
38
|
-
cls, schema: NodeSchema, _meta:
|
|
38
|
+
cls, schema: NodeSchema, _meta: Any | None = None, **options: dict[str, Any]
|
|
39
39
|
) -> None:
|
|
40
40
|
# Make sure schema is a valid NodeSchema Node Class
|
|
41
41
|
if not isinstance(schema, NodeSchema):
|
|
@@ -53,7 +53,7 @@ class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
|
53
53
|
info: GraphQLResolveInfo,
|
|
54
54
|
data: InputObjectType,
|
|
55
55
|
branch: Branch,
|
|
56
|
-
database:
|
|
56
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
57
57
|
) -> tuple[Node, Self]:
|
|
58
58
|
validate_namespace(data=data)
|
|
59
59
|
|
|
@@ -67,8 +67,8 @@ class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
|
67
67
|
info: GraphQLResolveInfo,
|
|
68
68
|
data: InputObjectType,
|
|
69
69
|
branch: Branch,
|
|
70
|
-
database:
|
|
71
|
-
node:
|
|
70
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
71
|
+
node: Node | None = None, # noqa: ARG003
|
|
72
72
|
) -> tuple[Node, Self]:
|
|
73
73
|
graphql_context: GraphqlContext = info.context
|
|
74
74
|
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from pydantic import BaseModel
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
class BranchCreateModel(BaseModel):
|
|
7
5
|
name: str
|
|
8
|
-
id:
|
|
6
|
+
id: str | None = None
|
|
9
7
|
description: str = ""
|
|
10
8
|
origin_branch: str = "main"
|
|
11
|
-
branched_from:
|
|
9
|
+
branched_from: str | None = None
|
|
12
10
|
sync_with_git: bool = True
|
|
13
11
|
is_isolated: bool = True
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from copy import copy
|
|
2
2
|
|
|
3
3
|
from graphene import InputObjectType
|
|
4
4
|
|
|
@@ -21,21 +21,21 @@ class MutationNodeGetterByDefaultFilter(MutationNodeGetterInterface):
|
|
|
21
21
|
node_schema: MainSchemaTypes,
|
|
22
22
|
data: InputObjectType,
|
|
23
23
|
branch: Branch,
|
|
24
|
-
) ->
|
|
25
|
-
node = None
|
|
26
|
-
default_filter_value = None
|
|
24
|
+
) -> Node | None:
|
|
27
25
|
if not node_schema.default_filter:
|
|
28
|
-
return
|
|
29
|
-
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
data = copy(data)
|
|
30
29
|
|
|
31
30
|
for filter_key in node_schema.default_filter.split("__"):
|
|
32
|
-
if filter_key not in
|
|
31
|
+
if filter_key not in data:
|
|
33
32
|
break
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
data = data[filter_key]
|
|
34
|
+
|
|
35
|
+
default_filter_value = data
|
|
36
36
|
|
|
37
37
|
if not default_filter_value:
|
|
38
|
-
return
|
|
38
|
+
return None
|
|
39
39
|
|
|
40
40
|
return await self.node_manager.get_one_by_default_filter(
|
|
41
41
|
db=self.db,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from graphene import InputObjectType
|
|
4
2
|
|
|
5
3
|
from infrahub.core.branch import Branch
|
|
@@ -22,7 +20,7 @@ class MutationNodeGetterByHfid(MutationNodeGetterInterface):
|
|
|
22
20
|
node_schema: MainSchemaTypes,
|
|
23
21
|
data: InputObjectType,
|
|
24
22
|
branch: Branch,
|
|
25
|
-
) ->
|
|
23
|
+
) -> Node | None:
|
|
26
24
|
if not node_schema.human_friendly_id:
|
|
27
25
|
return None
|
|
28
26
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from graphene import InputObjectType
|
|
4
2
|
|
|
5
3
|
from infrahub.core.branch import Branch
|
|
@@ -21,7 +19,7 @@ class MutationNodeGetterById(MutationNodeGetterInterface):
|
|
|
21
19
|
node_schema: MainSchemaTypes,
|
|
22
20
|
data: InputObjectType,
|
|
23
21
|
branch: Branch,
|
|
24
|
-
) ->
|
|
22
|
+
) -> Node | None:
|
|
25
23
|
node = None
|
|
26
24
|
if "id" not in data:
|
|
27
25
|
return node
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
from graphene import InputObjectType
|
|
5
4
|
|
|
@@ -15,4 +14,4 @@ class MutationNodeGetterInterface(ABC):
|
|
|
15
14
|
node_schema: MainSchemaTypes,
|
|
16
15
|
data: InputObjectType,
|
|
17
16
|
branch: Branch,
|
|
18
|
-
) ->
|
|
17
|
+
) -> Node | None: ...
|