infrahub-server 1.2.0rc0__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/api/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +5 -3
- infrahub/artifacts/tasks.py +3 -5
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +240 -12
- infrahub/computed_attribute/tasks.py +77 -441
- infrahub/computed_attribute/triggers.py +13 -47
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +58 -58
- infrahub/core/branch/tasks.py +74 -22
- infrahub/core/changelog/diff.py +95 -36
- infrahub/core/changelog/models.py +217 -43
- infrahub/core/constants/__init__.py +28 -0
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constants/schema.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/enricher/cardinality_one.py +5 -0
- infrahub/core/diff/enricher/hierarchy.py +17 -4
- infrahub/core/diff/enricher/labels.py +5 -0
- infrahub/core/diff/enricher/path_identifier.py +4 -0
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +32 -9
- infrahub/core/diff/parent_node_adder.py +78 -0
- infrahub/core/diff/payload_builder.py +13 -2
- infrahub/core/diff/query/filters.py +2 -2
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query/save.py +188 -182
- infrahub/core/diff/query/summary_counts_enricher.py +51 -4
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/diff/repository/deserializer.py +8 -3
- infrahub/core/diff/repository/repository.py +156 -38
- infrahub/core/diff/tasks.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/index.py +3 -0
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +36 -36
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +12 -3
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +43 -26
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/node_remove.py +26 -12
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +43 -39
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +7 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +228 -40
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +51 -59
- infrahub/core/schema/attribute_schema.py +16 -8
- infrahub/core/schema/basenode_schema.py +105 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +147 -0
- infrahub/core/schema/definitions/core/account.py +171 -0
- infrahub/core/schema/definitions/core/artifact.py +136 -0
- infrahub/core/schema/definitions/core/builtin.py +24 -0
- infrahub/core/schema/definitions/core/check.py +68 -0
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +100 -0
- infrahub/core/schema/definitions/core/graphql_query.py +79 -0
- infrahub/core/schema/definitions/core/group.py +108 -0
- infrahub/core/schema/definitions/core/ipam.py +193 -0
- infrahub/core/schema/definitions/core/lineage.py +19 -0
- infrahub/core/schema/definitions/core/menu.py +48 -0
- infrahub/core/schema/definitions/core/permission.py +163 -0
- infrahub/core/schema/definitions/core/profile.py +18 -0
- infrahub/core/schema/definitions/core/propose_change.py +97 -0
- infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
- infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
- infrahub/core/schema/definitions/core/repository.py +286 -0
- infrahub/core/schema/definitions/core/resource_pool.py +170 -0
- infrahub/core/schema/definitions/core/template.py +27 -0
- infrahub/core/schema/definitions/core/transform.py +96 -0
- infrahub/core/schema/definitions/core/webhook.py +134 -0
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +14 -6
- infrahub/core/schema/schema_branch.py +292 -144
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/timestamp.py +3 -3
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +27 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/builder/diff/deserializer.py +3 -1
- infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
- infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +64 -0
- infrahub/events/branch_action.py +33 -22
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +51 -21
- infrahub/events/models.py +18 -19
- infrahub/events/node_action.py +88 -37
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +32 -24
- infrahub/generators/models.py +2 -3
- infrahub/generators/tasks.py +24 -4
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +48 -24
- infrahub/git/models.py +101 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +408 -6
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +39 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +17 -19
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/branch.py +26 -1
- infrahub/graphql/mutations/computed_attribute.py +9 -5
- infrahub/graphql/mutations/diff.py +23 -11
- infrahub/graphql/mutations/diff_conflict.py +5 -0
- infrahub/graphql/mutations/generator.py +83 -0
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +54 -74
- infrahub/graphql/mutations/main.py +195 -132
- infrahub/graphql/mutations/menu.py +7 -7
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +93 -19
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +19 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/permissions.py +1 -10
- infrahub/graphql/queries/diff/tree.py +19 -14
- infrahub/graphql/queries/event.py +5 -2
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/context.py +12 -0
- infrahub/graphql/types/event.py +84 -17
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/lock.py +20 -20
- infrahub/menu/constants.py +0 -1
- infrahub/menu/generator.py +9 -21
- infrahub/menu/menu.py +17 -38
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/__init__.py +11 -13
- infrahub/message_bus/messages/__init__.py +1 -21
- infrahub/message_bus/messages/check_generator_run.py +3 -3
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/messages/send_echo_request.py +1 -1
- infrahub/message_bus/operations/__init__.py +1 -10
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/event/worker.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -2
- infrahub/message_bus/operations/requests/generator_definition.py +21 -23
- infrahub/message_bus/operations/requests/proposed_change.py +14 -10
- infrahub/permissions/globals.py +15 -0
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/models.py +3 -0
- infrahub/proposed_change/tasks.py +58 -45
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +2 -3
- infrahub/services/__init__.py +2 -2
- infrahub/services/adapters/cache/__init__.py +4 -6
- infrahub/services/adapters/cache/nats.py +4 -5
- infrahub/services/adapters/cache/redis.py +3 -7
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/services/adapters/message_bus/__init__.py +3 -3
- infrahub/services/adapters/message_bus/local.py +2 -2
- infrahub/services/adapters/message_bus/nats.py +4 -4
- infrahub/services/adapters/message_bus/rabbitmq.py +4 -4
- infrahub/services/adapters/workflow/local.py +2 -2
- infrahub/services/component.py +5 -5
- infrahub/services/protocols.py +7 -7
- infrahub/services/scheduler.py +1 -3
- infrahub/task_manager/event.py +102 -9
- infrahub/task_manager/models.py +27 -7
- infrahub/tasks/artifact.py +7 -6
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +4 -6
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +54 -5
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -84
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +176 -44
- infrahub/webhook/tasks.py +154 -155
- infrahub/webhook/triggers.py +31 -7
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +86 -35
- infrahub/workflows/initialization.py +8 -2
- infrahub/workflows/models.py +27 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +35 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/cli_commands.py +5 -1
- infrahub_sdk/ctl/utils.py +0 -16
- infrahub_sdk/exceptions.py +12 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +71 -22
- infrahub_sdk/protocols.py +21 -8
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +11 -0
- infrahub_sdk/task/constants.py +3 -0
- infrahub_sdk/task/exceptions.py +25 -0
- infrahub_sdk/task/manager.py +551 -0
- infrahub_sdk/task/models.py +74 -0
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +142 -33
- infrahub_sdk/utils.py +29 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +8 -6
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +349 -293
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/core/schema/definitions/core.py +0 -2286
- infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
- infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
- infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/messages/request_repository_checks.py +0 -12
- infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
- infrahub/message_bus/operations/check/repository.py +0 -293
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/message_bus/operations/requests/repository.py +0 -133
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
|
@@ -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: ...
|
|
@@ -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,10 +8,9 @@ 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,
|
|
@@ -24,10 +23,14 @@ from infrahub.core.query.relationship import (
|
|
|
24
23
|
)
|
|
25
24
|
from infrahub.core.relationship import Relationship
|
|
26
25
|
from infrahub.database import retry_db_transaction
|
|
27
|
-
from infrahub.events import EventMeta
|
|
26
|
+
from infrahub.events import EventMeta
|
|
28
27
|
from infrahub.events.group_action import GroupMemberAddedEvent, GroupMemberRemovedEvent
|
|
29
28
|
from infrahub.events.models import EventNode
|
|
29
|
+
from infrahub.events.node_action import NodeUpdatedEvent
|
|
30
30
|
from infrahub.exceptions import NodeNotFoundError, ValidationError
|
|
31
|
+
from infrahub.graphql.context import apply_external_context
|
|
32
|
+
from infrahub.graphql.types.context import ContextInput
|
|
33
|
+
from infrahub.groups.ancestors import collect_ancestors
|
|
31
34
|
from infrahub.permissions import get_global_permission_for_kind
|
|
32
35
|
|
|
33
36
|
from ..types import RelatedNodeInput
|
|
@@ -62,6 +65,7 @@ class RelationshipNodesInput(InputObjectType):
|
|
|
62
65
|
class RelationshipAdd(Mutation):
|
|
63
66
|
class Arguments:
|
|
64
67
|
data = RelationshipNodesInput(required=True)
|
|
68
|
+
context = ContextInput(required=False)
|
|
65
69
|
|
|
66
70
|
ok = Boolean()
|
|
67
71
|
|
|
@@ -72,6 +76,7 @@ class RelationshipAdd(Mutation):
|
|
|
72
76
|
root: dict, # noqa: ARG003
|
|
73
77
|
info: GraphQLResolveInfo,
|
|
74
78
|
data: RelationshipNodesInput,
|
|
79
|
+
context: ContextInput | None = None,
|
|
75
80
|
) -> Self:
|
|
76
81
|
graphql_context: GraphqlContext = info.context
|
|
77
82
|
relationship_name = str(data.name)
|
|
@@ -81,6 +86,9 @@ class RelationshipAdd(Mutation):
|
|
|
81
86
|
await _validate_permissions(info=info, source_node=source, peers=nodes)
|
|
82
87
|
await _validate_peer_types(info=info, data=data, source_node=source, peers=nodes)
|
|
83
88
|
|
|
89
|
+
# This has to be done after validating the permissions
|
|
90
|
+
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
91
|
+
|
|
84
92
|
rel_schema = source.get_schema().get_relationship(name=relationship_name)
|
|
85
93
|
display_label: str = await source.render_display_label(db=graphql_context.db)
|
|
86
94
|
node_changelog = NodeChangelog(
|
|
@@ -89,6 +97,10 @@ class RelationshipAdd(Mutation):
|
|
|
89
97
|
|
|
90
98
|
existing_peers = await _collect_current_peers(info=info, data=data, source_node=source)
|
|
91
99
|
|
|
100
|
+
group_event_type = _get_group_event_type(
|
|
101
|
+
node=source, relationship_schema=rel_schema, relationship_name=relationship_name
|
|
102
|
+
)
|
|
103
|
+
|
|
92
104
|
async with graphql_context.db.start_transaction() as db:
|
|
93
105
|
peers: list[EventNode] = []
|
|
94
106
|
for node_data in data.get("nodes"):
|
|
@@ -99,19 +111,24 @@ class RelationshipAdd(Mutation):
|
|
|
99
111
|
await rel.resolve(db=db)
|
|
100
112
|
# Save it only if it does not exist
|
|
101
113
|
if rel.get_peer_id() not in existing_peers.keys():
|
|
102
|
-
|
|
114
|
+
if group_event_type != GroupUpdateType.NONE:
|
|
115
|
+
peers.append(EventNode(id=rel.get_peer_id(), kind=nodes[rel.get_peer_id()].get_kind()))
|
|
103
116
|
node_changelog.create_relationship(relationship=rel)
|
|
104
117
|
await rel.save(db=db)
|
|
105
118
|
|
|
106
119
|
if config.SETTINGS.broker.enable and graphql_context.background and node_changelog.has_changes:
|
|
107
|
-
group_event_type = _get_group_event_type(
|
|
108
|
-
node=source, relationship_schema=rel_schema, relationship_name=relationship_name
|
|
109
|
-
)
|
|
110
120
|
if group_event_type == GroupUpdateType.MEMBERS:
|
|
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
|
+
)
|
|
111
127
|
group_add_event = GroupMemberAddedEvent(
|
|
112
128
|
node_id=source.id,
|
|
113
129
|
kind=source.get_schema().kind,
|
|
114
130
|
members=peers,
|
|
131
|
+
ancestors=ancestors,
|
|
115
132
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
116
133
|
)
|
|
117
134
|
graphql_context.background.add_task(graphql_context.active_service.event.send, group_add_event)
|
|
@@ -124,24 +141,46 @@ class RelationshipAdd(Mutation):
|
|
|
124
141
|
node_kind_map = await node_kind_query.get_node_kind_map()
|
|
125
142
|
|
|
126
143
|
for node_id, node_kind in node_kind_map.items():
|
|
144
|
+
ancestors = await collect_ancestors(
|
|
145
|
+
db=graphql_context.db, branch=graphql_context.branch, node_kind=node_kind, node_id=node_id
|
|
146
|
+
)
|
|
127
147
|
group_add_event = GroupMemberAddedEvent(
|
|
128
148
|
node_id=node_id,
|
|
129
149
|
kind=node_kind,
|
|
150
|
+
ancestors=ancestors,
|
|
130
151
|
members=[EventNode(id=source.get_id(), kind=source.get_kind())],
|
|
131
152
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
132
153
|
)
|
|
133
154
|
graphql_context.background.add_task(graphql_context.active_service.event.send, group_add_event)
|
|
134
155
|
|
|
135
156
|
else:
|
|
136
|
-
|
|
157
|
+
main_event = NodeUpdatedEvent(
|
|
137
158
|
kind=source.get_schema().kind,
|
|
138
159
|
node_id=source.id,
|
|
139
|
-
|
|
140
|
-
action=MutationAction.UPDATED,
|
|
160
|
+
changelog=node_changelog,
|
|
141
161
|
fields=[relationship_name],
|
|
142
162
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
143
163
|
)
|
|
144
|
-
|
|
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)
|
|
145
184
|
|
|
146
185
|
return cls(ok=True)
|
|
147
186
|
|
|
@@ -149,6 +188,7 @@ class RelationshipAdd(Mutation):
|
|
|
149
188
|
class RelationshipRemove(Mutation):
|
|
150
189
|
class Arguments:
|
|
151
190
|
data = RelationshipNodesInput(required=True)
|
|
191
|
+
context = ContextInput(required=False)
|
|
152
192
|
|
|
153
193
|
ok = Boolean()
|
|
154
194
|
|
|
@@ -159,6 +199,7 @@ class RelationshipRemove(Mutation):
|
|
|
159
199
|
root: dict, # noqa: ARG003
|
|
160
200
|
info: GraphQLResolveInfo,
|
|
161
201
|
data: RelationshipNodesInput,
|
|
202
|
+
context: ContextInput | None = None,
|
|
162
203
|
) -> Self:
|
|
163
204
|
graphql_context: GraphqlContext = info.context
|
|
164
205
|
relationship_name = str(data.name)
|
|
@@ -168,6 +209,9 @@ class RelationshipRemove(Mutation):
|
|
|
168
209
|
await _validate_permissions(info=info, source_node=source, peers=nodes)
|
|
169
210
|
await _validate_peer_types(info=info, data=data, source_node=source, peers=nodes)
|
|
170
211
|
|
|
212
|
+
# This has to be done after validating the permissions
|
|
213
|
+
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
214
|
+
|
|
171
215
|
rel_schema = source.get_schema().get_relationship(name=relationship_name)
|
|
172
216
|
display_label: str = await source.render_display_label(db=graphql_context.db)
|
|
173
217
|
node_changelog = NodeChangelog(
|
|
@@ -175,6 +219,9 @@ class RelationshipRemove(Mutation):
|
|
|
175
219
|
)
|
|
176
220
|
|
|
177
221
|
existing_peers = await _collect_current_peers(info=info, data=data, source_node=source)
|
|
222
|
+
group_event_type = _get_group_event_type(
|
|
223
|
+
node=source, relationship_schema=rel_schema, relationship_name=relationship_name
|
|
224
|
+
)
|
|
178
225
|
|
|
179
226
|
async with graphql_context.db.start_transaction() as db:
|
|
180
227
|
peers: list[EventNode] = []
|
|
@@ -186,19 +233,24 @@ class RelationshipRemove(Mutation):
|
|
|
186
233
|
# it would be more query efficient
|
|
187
234
|
rel = Relationship(schema=rel_schema, branch=graphql_context.branch, node=source)
|
|
188
235
|
await rel.load(db=db, data=existing_peers[node_data.get("id")])
|
|
189
|
-
|
|
236
|
+
if group_event_type != GroupUpdateType.NONE:
|
|
237
|
+
peers.append(EventNode(id=rel.get_peer_id(), kind=nodes[rel.get_peer_id()].get_kind()))
|
|
190
238
|
node_changelog.delete_relationship(relationship=rel)
|
|
191
239
|
await rel.delete(db=db)
|
|
192
240
|
|
|
193
241
|
if config.SETTINGS.broker.enable and graphql_context.background and node_changelog.has_changes:
|
|
194
|
-
group_event_type = _get_group_event_type(
|
|
195
|
-
node=source, relationship_schema=rel_schema, relationship_name=relationship_name
|
|
196
|
-
)
|
|
197
242
|
if group_event_type == GroupUpdateType.MEMBERS:
|
|
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
|
+
)
|
|
198
249
|
group_remove_event = GroupMemberRemovedEvent(
|
|
199
250
|
node_id=source.id,
|
|
200
251
|
kind=source.get_schema().kind,
|
|
201
252
|
members=peers,
|
|
253
|
+
ancestors=ancestors,
|
|
202
254
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
203
255
|
)
|
|
204
256
|
graphql_context.background.add_task(graphql_context.active_service.event.send, group_remove_event)
|
|
@@ -210,6 +262,9 @@ class RelationshipRemove(Mutation):
|
|
|
210
262
|
node_kind_map = await node_kind_query.get_node_kind_map()
|
|
211
263
|
|
|
212
264
|
for node_id, node_kind in node_kind_map.items():
|
|
265
|
+
ancestors = await collect_ancestors(
|
|
266
|
+
db=graphql_context.db, branch=graphql_context.branch, node_kind=node_kind, node_id=node_id
|
|
267
|
+
)
|
|
213
268
|
group_remove_event = GroupMemberRemovedEvent(
|
|
214
269
|
node_id=node_id,
|
|
215
270
|
kind=node_kind,
|
|
@@ -220,15 +275,34 @@ class RelationshipRemove(Mutation):
|
|
|
220
275
|
graphql_context.active_service.event.send, group_remove_event
|
|
221
276
|
)
|
|
222
277
|
else:
|
|
223
|
-
|
|
278
|
+
main_event = NodeUpdatedEvent(
|
|
224
279
|
kind=source.get_schema().kind,
|
|
225
280
|
node_id=source.id,
|
|
226
|
-
|
|
227
|
-
action=MutationAction.UPDATED,
|
|
281
|
+
changelog=node_changelog,
|
|
228
282
|
fields=[relationship_name],
|
|
229
283
|
meta=EventMeta(branch=graphql_context.branch, context=graphql_context.get_context()),
|
|
230
284
|
)
|
|
231
|
-
|
|
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)
|
|
232
306
|
|
|
233
307
|
return cls(ok=True)
|
|
234
308
|
|
|
@@ -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
|
|
|
@@ -13,6 +13,8 @@ from infrahub.database import InfrahubDatabase, retry_db_transaction
|
|
|
13
13
|
from infrahub.events import EventMeta
|
|
14
14
|
from infrahub.events.schema_action import SchemaUpdatedEvent
|
|
15
15
|
from infrahub.exceptions import ValidationError
|
|
16
|
+
from infrahub.graphql.context import apply_external_context
|
|
17
|
+
from infrahub.graphql.types.context import ContextInput
|
|
16
18
|
from infrahub.log import get_log_data, get_logger
|
|
17
19
|
from infrahub.worker import WORKER_IDENTITY
|
|
18
20
|
|
|
@@ -51,6 +53,7 @@ class SchemaDropdownAddInput(SchemaDropdownRemoveInput):
|
|
|
51
53
|
class SchemaDropdownAdd(Mutation):
|
|
52
54
|
class Arguments:
|
|
53
55
|
data = SchemaDropdownAddInput(required=True)
|
|
56
|
+
context = ContextInput(required=False)
|
|
54
57
|
|
|
55
58
|
ok = Boolean()
|
|
56
59
|
object = Field(DropdownFields)
|
|
@@ -62,9 +65,12 @@ class SchemaDropdownAdd(Mutation):
|
|
|
62
65
|
root: dict, # noqa: ARG003
|
|
63
66
|
info: GraphQLResolveInfo,
|
|
64
67
|
data: SchemaDropdownAddInput,
|
|
68
|
+
context: ContextInput | None = None,
|
|
65
69
|
) -> Self:
|
|
66
70
|
graphql_context: GraphqlContext = info.context
|
|
67
71
|
|
|
72
|
+
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
73
|
+
|
|
68
74
|
kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
|
|
69
75
|
attribute = str(data.attribute)
|
|
70
76
|
validate_kind_dropdown(kind=kind, attribute=attribute)
|
|
@@ -109,6 +115,7 @@ class SchemaDropdownAdd(Mutation):
|
|
|
109
115
|
class SchemaDropdownRemove(Mutation):
|
|
110
116
|
class Arguments:
|
|
111
117
|
data = SchemaDropdownRemoveInput(required=True)
|
|
118
|
+
context = ContextInput(required=False)
|
|
112
119
|
|
|
113
120
|
ok = Boolean()
|
|
114
121
|
|
|
@@ -119,10 +126,12 @@ class SchemaDropdownRemove(Mutation):
|
|
|
119
126
|
root: dict, # noqa: ARG003
|
|
120
127
|
info: GraphQLResolveInfo,
|
|
121
128
|
data: SchemaDropdownRemoveInput,
|
|
129
|
+
context: ContextInput | None = None,
|
|
122
130
|
) -> dict[str, bool]:
|
|
123
131
|
graphql_context: GraphqlContext = info.context
|
|
124
132
|
|
|
125
133
|
kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
|
|
134
|
+
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
126
135
|
|
|
127
136
|
attribute = str(data.attribute)
|
|
128
137
|
validate_kind_dropdown(kind=kind, attribute=attribute)
|
|
@@ -161,6 +170,7 @@ class SchemaDropdownRemove(Mutation):
|
|
|
161
170
|
class SchemaEnumAdd(Mutation):
|
|
162
171
|
class Arguments:
|
|
163
172
|
data = SchemaEnumInput(required=True)
|
|
173
|
+
context = ContextInput(required=False)
|
|
164
174
|
|
|
165
175
|
ok = Boolean()
|
|
166
176
|
|
|
@@ -171,10 +181,12 @@ class SchemaEnumAdd(Mutation):
|
|
|
171
181
|
root: dict, # noqa: ARG003
|
|
172
182
|
info: GraphQLResolveInfo,
|
|
173
183
|
data: SchemaEnumInput,
|
|
184
|
+
context: ContextInput | None = None,
|
|
174
185
|
) -> dict[str, bool]:
|
|
175
186
|
graphql_context: GraphqlContext = info.context
|
|
176
187
|
|
|
177
188
|
kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
|
|
189
|
+
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
178
190
|
|
|
179
191
|
attribute = str(data.attribute)
|
|
180
192
|
enum = str(data.enum)
|
|
@@ -203,6 +215,7 @@ class SchemaEnumAdd(Mutation):
|
|
|
203
215
|
class SchemaEnumRemove(Mutation):
|
|
204
216
|
class Arguments:
|
|
205
217
|
data = SchemaEnumInput(required=True)
|
|
218
|
+
context = ContextInput(required=False)
|
|
206
219
|
|
|
207
220
|
ok = Boolean()
|
|
208
221
|
|
|
@@ -213,10 +226,12 @@ class SchemaEnumRemove(Mutation):
|
|
|
213
226
|
root: dict, # noqa: ARG003
|
|
214
227
|
info: GraphQLResolveInfo,
|
|
215
228
|
data: SchemaEnumInput,
|
|
229
|
+
context: ContextInput | None = None,
|
|
216
230
|
) -> dict[str, bool]:
|
|
217
231
|
graphql_context: GraphqlContext = info.context
|
|
218
232
|
|
|
219
233
|
kind = graphql_context.db.schema.get(name=str(data.kind), branch=graphql_context.branch.name)
|
|
234
|
+
await apply_external_context(graphql_context=graphql_context, context_input=context)
|
|
220
235
|
|
|
221
236
|
attribute = str(data.attribute)
|
|
222
237
|
enum = str(data.enum)
|
|
@@ -252,21 +267,21 @@ class SchemaEnumRemove(Mutation):
|
|
|
252
267
|
return {"ok": True}
|
|
253
268
|
|
|
254
269
|
|
|
255
|
-
def validate_kind_dropdown(kind:
|
|
270
|
+
def validate_kind_dropdown(kind: GenericSchema | NodeSchema, attribute: str) -> None:
|
|
256
271
|
validate_kind(kind=kind, attribute=attribute)
|
|
257
272
|
matching_attribute = [attrib for attrib in kind.attributes if attrib.name == attribute]
|
|
258
273
|
if matching_attribute and matching_attribute[0].kind != "Dropdown":
|
|
259
274
|
raise ValidationError(f"Attribute {attribute} on {kind.kind} is not a Dropdown")
|
|
260
275
|
|
|
261
276
|
|
|
262
|
-
def validate_kind_enum(kind:
|
|
277
|
+
def validate_kind_enum(kind: GenericSchema | NodeSchema, attribute: str) -> None:
|
|
263
278
|
validate_kind(kind=kind, attribute=attribute)
|
|
264
279
|
matching_attribute = [attrib for attrib in kind.attributes if attrib.name == attribute]
|
|
265
280
|
if not matching_attribute[0].enum:
|
|
266
281
|
raise ValidationError(f"Attribute {attribute} on {kind.kind} is not an enum")
|
|
267
282
|
|
|
268
283
|
|
|
269
|
-
def validate_kind(kind:
|
|
284
|
+
def validate_kind(kind: GenericSchema | NodeSchema, attribute: str) -> None:
|
|
270
285
|
if kind.namespace in RESTRICTED_NAMESPACES:
|
|
271
286
|
raise ValidationError(f"Operation not allowed for {kind.kind} in restricted namespace {kind.namespace}")
|
|
272
287
|
if attribute not in kind.attribute_names:
|