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,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, Any,
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Self
|
|
2
2
|
|
|
3
3
|
from graphene import Boolean, Field, InputObjectType, Mutation, String
|
|
4
4
|
from graphql import GraphQLResolveInfo
|
|
@@ -31,7 +31,7 @@ if TYPE_CHECKING:
|
|
|
31
31
|
|
|
32
32
|
class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
33
33
|
@classmethod
|
|
34
|
-
def __init_subclass_with_meta__(cls, schema: NodeSchema = None, _meta=None, **options):
|
|
34
|
+
def __init_subclass_with_meta__(cls, schema: NodeSchema = None, _meta=None, **options) -> None:
|
|
35
35
|
# Make sure schema is a valid NodeSchema Node Class
|
|
36
36
|
if not isinstance(schema, NodeSchema):
|
|
37
37
|
raise ValueError(f"You need to pass a valid NodeSchema in '{cls.__name__}.Meta', received '{schema}'")
|
|
@@ -49,8 +49,8 @@ class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
|
49
49
|
info: GraphQLResolveInfo,
|
|
50
50
|
data: InputObjectType,
|
|
51
51
|
branch: Branch,
|
|
52
|
-
database:
|
|
53
|
-
):
|
|
52
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
53
|
+
) -> tuple[Node, Self]:
|
|
54
54
|
graphql_context: GraphqlContext = info.context
|
|
55
55
|
|
|
56
56
|
async with graphql_context.db.start_transaction() as dbt:
|
|
@@ -86,9 +86,9 @@ class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
|
86
86
|
info: GraphQLResolveInfo,
|
|
87
87
|
data: InputObjectType,
|
|
88
88
|
branch: Branch,
|
|
89
|
-
database:
|
|
90
|
-
node:
|
|
91
|
-
):
|
|
89
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
90
|
+
node: Node | None = None, # noqa: ARG003
|
|
91
|
+
) -> tuple[Node, Self]:
|
|
92
92
|
graphql_context: GraphqlContext = info.context
|
|
93
93
|
|
|
94
94
|
obj = await NodeManager.get_one_by_id_or_default_filter(
|
|
@@ -8,14 +8,12 @@ from infrahub_sdk.utils import compare_lists
|
|
|
8
8
|
|
|
9
9
|
from infrahub import config
|
|
10
10
|
from infrahub.core.account import GlobalPermission, ObjectPermission
|
|
11
|
-
from infrahub.core.changelog.models import NodeChangelog
|
|
11
|
+
from infrahub.core.changelog.models import NodeChangelog, RelationshipChangelogGetter
|
|
12
12
|
from infrahub.core.constants import (
|
|
13
13
|
InfrahubKind,
|
|
14
|
-
MutationAction,
|
|
15
14
|
PermissionAction,
|
|
16
15
|
PermissionDecision,
|
|
17
16
|
RelationshipCardinality,
|
|
18
|
-
RelationshipHierarchyDirection,
|
|
19
17
|
)
|
|
20
18
|
from infrahub.core.manager import NodeManager
|
|
21
19
|
from infrahub.core.query.node import NodeGetKindQuery
|
|
@@ -24,14 +22,15 @@ from infrahub.core.query.relationship import (
|
|
|
24
22
|
RelationshipPeerData,
|
|
25
23
|
)
|
|
26
24
|
from infrahub.core.relationship import Relationship
|
|
27
|
-
from infrahub.core.schema import NodeSchema
|
|
28
25
|
from infrahub.database import retry_db_transaction
|
|
29
|
-
from infrahub.events import EventMeta
|
|
26
|
+
from infrahub.events import EventMeta
|
|
30
27
|
from infrahub.events.group_action import GroupMemberAddedEvent, GroupMemberRemovedEvent
|
|
31
28
|
from infrahub.events.models import EventNode
|
|
29
|
+
from infrahub.events.node_action import NodeUpdatedEvent
|
|
32
30
|
from infrahub.exceptions import NodeNotFoundError, ValidationError
|
|
33
31
|
from infrahub.graphql.context import apply_external_context
|
|
34
32
|
from infrahub.graphql.types.context import ContextInput
|
|
33
|
+
from infrahub.groups.ancestors import collect_ancestors
|
|
35
34
|
from infrahub.permissions import get_global_permission_for_kind
|
|
36
35
|
|
|
37
36
|
from ..types import RelatedNodeInput
|
|
@@ -119,7 +118,12 @@ class RelationshipAdd(Mutation):
|
|
|
119
118
|
|
|
120
119
|
if config.SETTINGS.broker.enable and graphql_context.background and node_changelog.has_changes:
|
|
121
120
|
if group_event_type == GroupUpdateType.MEMBERS:
|
|
122
|
-
ancestors = await
|
|
121
|
+
ancestors = await collect_ancestors(
|
|
122
|
+
db=graphql_context.db,
|
|
123
|
+
branch=graphql_context.branch,
|
|
124
|
+
node_kind=source.get_schema().kind,
|
|
125
|
+
node_id=source.id,
|
|
126
|
+
)
|
|
123
127
|
group_add_event = GroupMemberAddedEvent(
|
|
124
128
|
node_id=source.id,
|
|
125
129
|
kind=source.get_schema().kind,
|
|
@@ -137,7 +141,9 @@ class RelationshipAdd(Mutation):
|
|
|
137
141
|
node_kind_map = await node_kind_query.get_node_kind_map()
|
|
138
142
|
|
|
139
143
|
for node_id, node_kind in node_kind_map.items():
|
|
140
|
-
ancestors = await
|
|
144
|
+
ancestors = await collect_ancestors(
|
|
145
|
+
db=graphql_context.db, branch=graphql_context.branch, node_kind=node_kind, node_id=node_id
|
|
146
|
+
)
|
|
141
147
|
group_add_event = GroupMemberAddedEvent(
|
|
142
148
|
node_id=node_id,
|
|
143
149
|
kind=node_kind,
|
|
@@ -148,15 +154,33 @@ class RelationshipAdd(Mutation):
|
|
|
148
154
|
graphql_context.background.add_task(graphql_context.active_service.event.send, group_add_event)
|
|
149
155
|
|
|
150
156
|
else:
|
|
151
|
-
|
|
157
|
+
main_event = NodeUpdatedEvent(
|
|
152
158
|
kind=source.get_schema().kind,
|
|
153
159
|
node_id=source.id,
|
|
154
|
-
|
|
155
|
-
action=MutationAction.UPDATED,
|
|
160
|
+
changelog=node_changelog,
|
|
156
161
|
fields=[relationship_name],
|
|
157
162
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
158
163
|
)
|
|
159
|
-
|
|
164
|
+
relationship_changelogs = RelationshipChangelogGetter(
|
|
165
|
+
db=graphql_context.db, branch=graphql_context.branch
|
|
166
|
+
)
|
|
167
|
+
node_changelogs = await relationship_changelogs.get_changelogs(primary_changelog=node_changelog)
|
|
168
|
+
|
|
169
|
+
events = [main_event]
|
|
170
|
+
|
|
171
|
+
for node_changelog in node_changelogs:
|
|
172
|
+
meta = EventMeta.from_parent(parent=main_event)
|
|
173
|
+
event = NodeUpdatedEvent(
|
|
174
|
+
kind=node_changelog.node_kind,
|
|
175
|
+
node_id=node_changelog.node_id,
|
|
176
|
+
changelog=node_changelog,
|
|
177
|
+
fields=node_changelog.updated_fields,
|
|
178
|
+
meta=meta,
|
|
179
|
+
)
|
|
180
|
+
events.append(event)
|
|
181
|
+
|
|
182
|
+
for event in events:
|
|
183
|
+
graphql_context.background.add_task(graphql_context.active_service.event.send, event)
|
|
160
184
|
|
|
161
185
|
return cls(ok=True)
|
|
162
186
|
|
|
@@ -216,7 +240,12 @@ class RelationshipRemove(Mutation):
|
|
|
216
240
|
|
|
217
241
|
if config.SETTINGS.broker.enable and graphql_context.background and node_changelog.has_changes:
|
|
218
242
|
if group_event_type == GroupUpdateType.MEMBERS:
|
|
219
|
-
ancestors = await
|
|
243
|
+
ancestors = await collect_ancestors(
|
|
244
|
+
db=graphql_context.db,
|
|
245
|
+
branch=graphql_context.branch,
|
|
246
|
+
node_kind=source.get_schema().kind,
|
|
247
|
+
node_id=source.id,
|
|
248
|
+
)
|
|
220
249
|
group_remove_event = GroupMemberRemovedEvent(
|
|
221
250
|
node_id=source.id,
|
|
222
251
|
kind=source.get_schema().kind,
|
|
@@ -233,7 +262,9 @@ class RelationshipRemove(Mutation):
|
|
|
233
262
|
node_kind_map = await node_kind_query.get_node_kind_map()
|
|
234
263
|
|
|
235
264
|
for node_id, node_kind in node_kind_map.items():
|
|
236
|
-
ancestors = await
|
|
265
|
+
ancestors = await collect_ancestors(
|
|
266
|
+
db=graphql_context.db, branch=graphql_context.branch, node_kind=node_kind, node_id=node_id
|
|
267
|
+
)
|
|
237
268
|
group_remove_event = GroupMemberRemovedEvent(
|
|
238
269
|
node_id=node_id,
|
|
239
270
|
kind=node_kind,
|
|
@@ -244,15 +275,34 @@ class RelationshipRemove(Mutation):
|
|
|
244
275
|
graphql_context.active_service.event.send, group_remove_event
|
|
245
276
|
)
|
|
246
277
|
else:
|
|
247
|
-
|
|
278
|
+
main_event = NodeUpdatedEvent(
|
|
248
279
|
kind=source.get_schema().kind,
|
|
249
280
|
node_id=source.id,
|
|
250
|
-
|
|
251
|
-
action=MutationAction.UPDATED,
|
|
281
|
+
changelog=node_changelog,
|
|
252
282
|
fields=[relationship_name],
|
|
253
283
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
254
284
|
)
|
|
255
|
-
|
|
285
|
+
|
|
286
|
+
relationship_changelogs = RelationshipChangelogGetter(
|
|
287
|
+
db=graphql_context.db, branch=graphql_context.branch
|
|
288
|
+
)
|
|
289
|
+
node_changelogs = await relationship_changelogs.get_changelogs(primary_changelog=node_changelog)
|
|
290
|
+
|
|
291
|
+
events = [main_event]
|
|
292
|
+
|
|
293
|
+
for node_changelog in node_changelogs:
|
|
294
|
+
meta = EventMeta.from_parent(parent=main_event)
|
|
295
|
+
event = NodeUpdatedEvent(
|
|
296
|
+
kind=node_changelog.node_kind,
|
|
297
|
+
node_id=node_changelog.node_id,
|
|
298
|
+
changelog=node_changelog,
|
|
299
|
+
fields=node_changelog.updated_fields,
|
|
300
|
+
meta=meta,
|
|
301
|
+
)
|
|
302
|
+
events.append(event)
|
|
303
|
+
|
|
304
|
+
for event in events:
|
|
305
|
+
graphql_context.background.add_task(graphql_context.active_service.event.send, event)
|
|
256
306
|
|
|
257
307
|
return cls(ok=True)
|
|
258
308
|
|
|
@@ -356,24 +406,6 @@ async def _validate_peer_types(
|
|
|
356
406
|
)
|
|
357
407
|
|
|
358
408
|
|
|
359
|
-
async def _collect_ancestors(info: GraphQLResolveInfo, node_kind: str, node_id: str) -> list[EventNode]:
|
|
360
|
-
graphql_context: GraphqlContext = info.context
|
|
361
|
-
schema = graphql_context.db.schema.get(name=node_kind, branch=graphql_context.branch)
|
|
362
|
-
|
|
363
|
-
if not isinstance(schema, NodeSchema):
|
|
364
|
-
return []
|
|
365
|
-
|
|
366
|
-
ancestors = await NodeManager.query_hierarchy(
|
|
367
|
-
db=graphql_context.db,
|
|
368
|
-
branch=graphql_context.branch,
|
|
369
|
-
direction=RelationshipHierarchyDirection.ANCESTORS,
|
|
370
|
-
id=node_id,
|
|
371
|
-
node_schema=schema,
|
|
372
|
-
filters={"id": None},
|
|
373
|
-
)
|
|
374
|
-
return [EventNode(id=ancestor.get_id(), kind=ancestor.get_kind()) for ancestor in ancestors.values()]
|
|
375
|
-
|
|
376
|
-
|
|
377
409
|
async def _collect_current_peers(
|
|
378
410
|
info: GraphQLResolveInfo, data: RelationshipNodesInput, source_node: Node
|
|
379
411
|
) -> dict[str, RelationshipPeerData]:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, cast
|
|
5
5
|
|
|
6
6
|
import httpx
|
|
7
7
|
from graphene import Boolean, Field, InputObjectType, Mutation, String
|
|
@@ -45,7 +45,7 @@ log = get_logger()
|
|
|
45
45
|
|
|
46
46
|
class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
|
|
47
47
|
@classmethod
|
|
48
|
-
def __init_subclass_with_meta__(cls, schema:
|
|
48
|
+
def __init_subclass_with_meta__(cls, schema: NodeSchema | None = None, _meta=None, **options) -> None:
|
|
49
49
|
# Make sure schema is a valid NodeSchema Node Class
|
|
50
50
|
if not isinstance(schema, NodeSchema):
|
|
51
51
|
raise ValueError(f"You need to pass a valid NodeSchema in '{cls.__name__}.Meta', received '{schema}'")
|
|
@@ -63,8 +63,8 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
|
|
|
63
63
|
info: GraphQLResolveInfo,
|
|
64
64
|
data: InputObjectType,
|
|
65
65
|
branch: Branch,
|
|
66
|
-
database:
|
|
67
|
-
):
|
|
66
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
67
|
+
) -> tuple[Node, Self]:
|
|
68
68
|
graphql_context: GraphqlContext = info.context
|
|
69
69
|
|
|
70
70
|
cleanup_payload(data)
|
|
@@ -149,9 +149,9 @@ class InfrahubRepositoryMutation(InfrahubMutationMixin, Mutation):
|
|
|
149
149
|
info: GraphQLResolveInfo,
|
|
150
150
|
data: InputObjectType,
|
|
151
151
|
branch: Branch,
|
|
152
|
-
database:
|
|
153
|
-
node:
|
|
154
|
-
):
|
|
152
|
+
database: InfrahubDatabase | None = None, # noqa: ARG003
|
|
153
|
+
node: Node | None = None,
|
|
154
|
+
) -> tuple[Node, Self]:
|
|
155
155
|
graphql_context: GraphqlContext = info.context
|
|
156
156
|
|
|
157
157
|
cleanup_payload(data)
|
|
@@ -219,7 +219,7 @@ def cleanup_payload(data: InputObjectType | dict[str, Any]) -> None:
|
|
|
219
219
|
):
|
|
220
220
|
url = httpx.URL(data["location"]["value"])
|
|
221
221
|
if url.host in config.SETTINGS.git.append_git_suffix:
|
|
222
|
-
data["location"]["value"] = f
|
|
222
|
+
data["location"]["value"] = f"{data['location']['value']}.git"
|
|
223
223
|
|
|
224
224
|
|
|
225
225
|
class ProcessRepository(Mutation):
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
|
-
from graphene import Boolean, Field, InputField, InputObjectType, Int, Mutation, String
|
|
5
|
+
from graphene import Boolean, Field, InputField, InputObjectType, Int, List, Mutation, String
|
|
6
6
|
from graphene.types.generic import GenericScalar
|
|
7
7
|
from typing_extensions import Self
|
|
8
8
|
|
|
@@ -30,7 +30,7 @@ if TYPE_CHECKING:
|
|
|
30
30
|
|
|
31
31
|
class IPPrefixPoolGetResourceInput(InputObjectType):
|
|
32
32
|
id = InputField(String(required=False), description="ID of the pool to allocate from")
|
|
33
|
-
hfid = InputField(String
|
|
33
|
+
hfid = InputField(List(of_type=String, required=False), description="HFID of the pool to allocate from")
|
|
34
34
|
identifier = InputField(String(required=False), description="Identifier for the allocated resource")
|
|
35
35
|
prefix_length = InputField(Int(required=False), description="Size of the prefix to allocate")
|
|
36
36
|
member_type = InputField(String(required=False), description="Type of members for the newly created prefix")
|
|
@@ -40,7 +40,7 @@ class IPPrefixPoolGetResourceInput(InputObjectType):
|
|
|
40
40
|
|
|
41
41
|
class IPAddressPoolGetResourceInput(InputObjectType):
|
|
42
42
|
id = InputField(String(required=False), description="ID of the pool to allocate from")
|
|
43
|
-
hfid = InputField(String
|
|
43
|
+
hfid = InputField(List(of_type=String, required=False), description="HFID of the pool to allocate from")
|
|
44
44
|
identifier = InputField(String(required=False), description="Identifier for the allocated resource")
|
|
45
45
|
prefix_length = InputField(
|
|
46
46
|
Int(required=False), description="Size of the prefix mask to allocate on the new IP address"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Self
|
|
3
|
+
from typing import TYPE_CHECKING, Self
|
|
4
4
|
|
|
5
5
|
from graphene import Boolean, Field, InputObjectType, Mutation, String
|
|
6
6
|
|
|
@@ -267,21 +267,21 @@ class SchemaEnumRemove(Mutation):
|
|
|
267
267
|
return {"ok": True}
|
|
268
268
|
|
|
269
269
|
|
|
270
|
-
def validate_kind_dropdown(kind:
|
|
270
|
+
def validate_kind_dropdown(kind: GenericSchema | NodeSchema, attribute: str) -> None:
|
|
271
271
|
validate_kind(kind=kind, attribute=attribute)
|
|
272
272
|
matching_attribute = [attrib for attrib in kind.attributes if attrib.name == attribute]
|
|
273
273
|
if matching_attribute and matching_attribute[0].kind != "Dropdown":
|
|
274
274
|
raise ValidationError(f"Attribute {attribute} on {kind.kind} is not a Dropdown")
|
|
275
275
|
|
|
276
276
|
|
|
277
|
-
def validate_kind_enum(kind:
|
|
277
|
+
def validate_kind_enum(kind: GenericSchema | NodeSchema, attribute: str) -> None:
|
|
278
278
|
validate_kind(kind=kind, attribute=attribute)
|
|
279
279
|
matching_attribute = [attrib for attrib in kind.attributes if attrib.name == attribute]
|
|
280
280
|
if not matching_attribute[0].enum:
|
|
281
281
|
raise ValidationError(f"Attribute {attribute} on {kind.kind} is not an enum")
|
|
282
282
|
|
|
283
283
|
|
|
284
|
-
def validate_kind(kind:
|
|
284
|
+
def validate_kind(kind: GenericSchema | NodeSchema, attribute: str) -> None:
|
|
285
285
|
if kind.namespace in RESTRICTED_NAMESPACES:
|
|
286
286
|
raise ValidationError(f"Operation not allowed for {kind.kind} in restricted namespace {kind.namespace}")
|
|
287
287
|
if attribute not in kind.attribute_names:
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, cast
|
|
5
|
+
|
|
6
|
+
from graphene import InputObjectType, Mutation
|
|
7
|
+
|
|
8
|
+
from infrahub.core.manager import NodeManager
|
|
9
|
+
from infrahub.core.protocols import CoreWebhook
|
|
10
|
+
from infrahub.core.schema import NodeSchema
|
|
11
|
+
from infrahub.database import retry_db_transaction
|
|
12
|
+
from infrahub.events.utils import get_all_infrahub_node_kind_events
|
|
13
|
+
from infrahub.exceptions import ValidationError
|
|
14
|
+
from infrahub.log import get_logger
|
|
15
|
+
|
|
16
|
+
from .main import InfrahubMutationMixin, InfrahubMutationOptions
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from graphql import GraphQLResolveInfo
|
|
20
|
+
|
|
21
|
+
from infrahub.core.branch import Branch
|
|
22
|
+
from infrahub.core.node import Node
|
|
23
|
+
from infrahub.database import InfrahubDatabase
|
|
24
|
+
from infrahub.graphql.initialization import GraphqlContext
|
|
25
|
+
|
|
26
|
+
log = get_logger()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class StringValue:
|
|
31
|
+
value: str
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class WebhookCreate:
|
|
36
|
+
event_type: StringValue | None = field(default=None)
|
|
37
|
+
node_kind: StringValue | None = field(default=None)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class WebhookUpdate(WebhookCreate):
|
|
41
|
+
id: str | None = field(default=None)
|
|
42
|
+
hfid: list[str] | None = field(default=None)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InfrahubWebhookMutation(InfrahubMutationMixin, Mutation):
|
|
46
|
+
_meta: InfrahubMutationOptions
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def __init_subclass_with_meta__(
|
|
50
|
+
cls, schema: NodeSchema | None = None, _meta: InfrahubMutationOptions | None = None, **options: dict[str, Any]
|
|
51
|
+
) -> None:
|
|
52
|
+
# Make sure schema is a valid NodeSchema Node Class
|
|
53
|
+
if not isinstance(schema, NodeSchema):
|
|
54
|
+
raise ValueError(f"You need to pass a valid NodeSchema in '{cls.__name__}.Meta', received '{schema}'")
|
|
55
|
+
|
|
56
|
+
if not _meta:
|
|
57
|
+
_meta = InfrahubMutationOptions(cls)
|
|
58
|
+
|
|
59
|
+
_meta.schema = schema
|
|
60
|
+
|
|
61
|
+
super().__init_subclass_with_meta__(_meta=_meta, **options)
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
async def mutate_create(
|
|
65
|
+
cls,
|
|
66
|
+
info: GraphQLResolveInfo,
|
|
67
|
+
data: InputObjectType,
|
|
68
|
+
branch: Branch,
|
|
69
|
+
database: InfrahubDatabase | None = None,
|
|
70
|
+
) -> tuple[Node, Self]:
|
|
71
|
+
graphql_context: GraphqlContext = info.context
|
|
72
|
+
|
|
73
|
+
input_data = cast("WebhookCreate", data)
|
|
74
|
+
|
|
75
|
+
_validate_input(graphql_context=graphql_context, branch=branch, input_data=input_data)
|
|
76
|
+
|
|
77
|
+
obj, result = await super().mutate_create(info=info, data=data, branch=branch, database=database)
|
|
78
|
+
|
|
79
|
+
return obj, result
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
@retry_db_transaction(name="object_update")
|
|
83
|
+
async def mutate_update(
|
|
84
|
+
cls,
|
|
85
|
+
info: GraphQLResolveInfo,
|
|
86
|
+
data: InputObjectType,
|
|
87
|
+
branch: Branch,
|
|
88
|
+
database: InfrahubDatabase | None = None,
|
|
89
|
+
node: Node | None = None,
|
|
90
|
+
) -> tuple[Node, Self]:
|
|
91
|
+
graphql_context: GraphqlContext = info.context
|
|
92
|
+
|
|
93
|
+
db = database or graphql_context.db
|
|
94
|
+
|
|
95
|
+
input_data = cast("WebhookUpdate", data)
|
|
96
|
+
|
|
97
|
+
_validate_input(graphql_context=graphql_context, branch=branch, input_data=input_data)
|
|
98
|
+
|
|
99
|
+
obj = node or await NodeManager.find_object(
|
|
100
|
+
db=db,
|
|
101
|
+
kind=cls._meta.active_schema.kind,
|
|
102
|
+
id=input_data.id,
|
|
103
|
+
hfid=input_data.hfid,
|
|
104
|
+
branch=branch,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
webhook = cast(CoreWebhook, obj)
|
|
108
|
+
|
|
109
|
+
event_type = input_data.event_type.value if input_data.event_type else webhook.event_type.value.value
|
|
110
|
+
node_kind = input_data.node_kind.value if input_data.node_kind else webhook.node_kind.value
|
|
111
|
+
|
|
112
|
+
if event_type and node_kind:
|
|
113
|
+
updated_data = WebhookUpdate(
|
|
114
|
+
event_type=StringValue(value=event_type), node_kind=StringValue(value=node_kind)
|
|
115
|
+
)
|
|
116
|
+
_validate_input(graphql_context=graphql_context, branch=branch, input_data=updated_data)
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
obj, result = await cls._call_mutate_update(info=info, data=data, db=db, branch=branch, obj=obj)
|
|
120
|
+
except ValidationError as exc:
|
|
121
|
+
raise ValueError(str(exc)) from exc
|
|
122
|
+
|
|
123
|
+
return obj, result
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _validate_input(graphql_context: GraphqlContext, branch: Branch, input_data: WebhookCreate) -> None:
|
|
127
|
+
if input_data.node_kind:
|
|
128
|
+
# Validate that the requested node_kind exists, will raise an error if not
|
|
129
|
+
graphql_context.db.schema.get(name=input_data.node_kind.value, branch=branch, duplicate=False)
|
|
130
|
+
|
|
131
|
+
if input_data.event_type:
|
|
132
|
+
# If the event type is not set then all events are applicable, this will mean that some events
|
|
133
|
+
# would be filtered out, as they won't match the node.
|
|
134
|
+
if input_data.event_type.value not in get_all_infrahub_node_kind_events():
|
|
135
|
+
raise ValidationError(
|
|
136
|
+
input_value=f"Defining a node_kind is not valid for {input_data.event_type.value} events"
|
|
137
|
+
)
|
infrahub/graphql/parser.py
CHANGED
|
@@ -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
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from graphql.language import (
|
|
7
7
|
DirectiveNode,
|
|
@@ -172,13 +172,13 @@ class GraphQLExtractor:
|
|
|
172
172
|
return fields
|
|
173
173
|
|
|
174
174
|
async def extract_fields(
|
|
175
|
-
self, selection_set:
|
|
176
|
-
) ->
|
|
175
|
+
self, selection_set: SelectionSetNode | None, path: str = "/"
|
|
176
|
+
) -> dict[str, dict | None] | None:
|
|
177
177
|
"""Extract fields and apply Directives"""
|
|
178
178
|
if not selection_set:
|
|
179
179
|
return None
|
|
180
180
|
|
|
181
|
-
fields: dict[str,
|
|
181
|
+
fields: dict[str, dict | None] = {}
|
|
182
182
|
for node in selection_set.selections:
|
|
183
183
|
sub_selection_set = getattr(node, "selection_set", None)
|
|
184
184
|
if isinstance(node, FieldNode):
|
|
@@ -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 Argument, Boolean, DateTime, Field, InputObjectType, Int, List, NonNull, ObjectType, String
|
|
6
6
|
from graphene import Enum as GrapheneEnum
|
|
@@ -324,7 +324,7 @@ class DiffTreeResolver:
|
|
|
324
324
|
|
|
325
325
|
async def to_graphql(
|
|
326
326
|
self, fields: dict[str, dict], diff_object: Any | None
|
|
327
|
-
) ->
|
|
327
|
+
) -> list[dict[str, Any]] | dict[str, Any] | None:
|
|
328
328
|
if diff_object is None:
|
|
329
329
|
return None
|
|
330
330
|
if isinstance(diff_object, list):
|
|
@@ -387,7 +387,7 @@ class DiffTreeResolver:
|
|
|
387
387
|
root_node_uuids: list[str] | None = None,
|
|
388
388
|
limit: int | None = None,
|
|
389
389
|
offset: int | None = None,
|
|
390
|
-
) ->
|
|
390
|
+
) -> list[dict[str, Any]] | dict[str, Any] | None:
|
|
391
391
|
component_registry = get_component_registry()
|
|
392
392
|
graphql_context: GraphqlContext = info.context
|
|
393
393
|
base_branch = await registry.get_branch(db=graphql_context.db, branch=registry.default_branch)
|
|
@@ -459,7 +459,7 @@ class DiffTreeResolver:
|
|
|
459
459
|
from_time: datetime | None = None,
|
|
460
460
|
to_time: datetime | None = None,
|
|
461
461
|
filters: dict | None = None,
|
|
462
|
-
) ->
|
|
462
|
+
) -> list[dict[str, Any]] | dict[str, Any] | None:
|
|
463
463
|
component_registry = get_component_registry()
|
|
464
464
|
graphql_context: GraphqlContext = info.context
|
|
465
465
|
base_branch = await registry.get_branch(db=graphql_context.db, branch=registry.default_branch)
|
infrahub/graphql/queries/ipam.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ipaddress
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from graphene import Field, Int, ObjectType, String
|
|
7
7
|
from netaddr import IPSet
|
|
@@ -27,7 +27,7 @@ class IPAddressGetNextAvailable(ObjectType):
|
|
|
27
27
|
root: dict, # noqa: ARG004
|
|
28
28
|
info: GraphQLResolveInfo,
|
|
29
29
|
prefix_id: str,
|
|
30
|
-
prefix_length:
|
|
30
|
+
prefix_length: int | None = None,
|
|
31
31
|
) -> dict[str, str]:
|
|
32
32
|
graphql_context: GraphqlContext = info.context
|
|
33
33
|
|
|
@@ -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 Field, Int, List, NonNull, ObjectType, String
|
|
6
6
|
from infrahub_sdk.utils import extract_fields_first_node
|
|
@@ -25,7 +25,7 @@ class Relationships(ObjectType):
|
|
|
25
25
|
ids: list[str],
|
|
26
26
|
limit: int = 10,
|
|
27
27
|
offset: int = 0,
|
|
28
|
-
excluded_namespaces:
|
|
28
|
+
excluded_namespaces: list[str] | None = None,
|
|
29
29
|
) -> dict[str, Any]:
|
|
30
30
|
graphql_context: GraphqlContext = info.context
|
|
31
31
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ipaddress
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
5
|
|
|
6
6
|
from graphene import Boolean, Field, Int, List, NonNull, ObjectType, String
|
|
7
7
|
from infrahub_sdk.utils import extract_fields_first_node, is_valid_uuid
|
|
@@ -110,7 +110,7 @@ async def search_resolver(
|
|
|
110
110
|
fields = await extract_fields_first_node(info)
|
|
111
111
|
|
|
112
112
|
if is_valid_uuid(q):
|
|
113
|
-
matching:
|
|
113
|
+
matching: CoreNode | None = await NodeManager.get_one(
|
|
114
114
|
db=graphql_context.db, branch=graphql_context.branch, at=graphql_context.at, id=q
|
|
115
115
|
)
|
|
116
116
|
if matching:
|