infrahub-server 1.1.6__py3-none-any.whl → 1.2.0rc0__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/artifact.py +16 -4
- infrahub/api/dependencies.py +8 -0
- infrahub/api/oauth2.py +0 -1
- infrahub/api/oidc.py +0 -1
- infrahub/api/query.py +18 -7
- infrahub/api/schema.py +32 -6
- infrahub/api/transformation.py +12 -5
- infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +2 -4
- infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
- infrahub/cli/__init__.py +0 -2
- infrahub/cli/db.py +6 -7
- infrahub/cli/events.py +8 -3
- infrahub/cli/git_agent.py +9 -7
- infrahub/cli/tasks.py +4 -6
- infrahub/computed_attribute/tasks.py +63 -17
- infrahub/computed_attribute/triggers.py +90 -0
- infrahub/config.py +1 -1
- infrahub/context.py +39 -0
- infrahub/core/account.py +5 -8
- infrahub/core/attribute.py +53 -21
- infrahub/core/branch/models.py +4 -4
- infrahub/core/branch/tasks.py +89 -130
- infrahub/core/changelog/__init__.py +0 -0
- infrahub/core/changelog/diff.py +232 -0
- infrahub/core/changelog/models.py +488 -0
- infrahub/core/constants/__init__.py +19 -2
- infrahub/core/constants/infrahubkind.py +1 -0
- infrahub/core/diff/combiner.py +12 -8
- infrahub/core/diff/coordinator.py +49 -70
- infrahub/core/diff/data_check_synchronizer.py +86 -7
- infrahub/core/diff/enricher/aggregated.py +3 -3
- infrahub/core/diff/enricher/cardinality_one.py +2 -7
- infrahub/core/diff/enricher/hierarchy.py +5 -3
- infrahub/core/diff/enricher/labels.py +14 -4
- infrahub/core/diff/enricher/path_identifier.py +3 -9
- infrahub/core/diff/enricher/summary_counts.py +3 -1
- infrahub/core/diff/merger/merger.py +8 -4
- infrahub/core/diff/model/path.py +47 -29
- infrahub/core/diff/query/all_conflicts.py +6 -3
- infrahub/core/diff/query/artifact.py +1 -1
- infrahub/core/diff/query/delete_query.py +1 -1
- infrahub/core/diff/query/diff_get.py +3 -2
- infrahub/core/diff/query/diff_summary.py +1 -1
- infrahub/core/diff/query/field_specifiers.py +3 -1
- infrahub/core/diff/query/field_summary.py +3 -2
- infrahub/core/diff/query/filters.py +12 -1
- infrahub/core/diff/query/get_conflict_query.py +1 -1
- infrahub/core/diff/query/has_conflicts_query.py +6 -3
- infrahub/core/diff/query/merge.py +3 -3
- infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
- infrahub/core/diff/query/roots_metadata.py +9 -2
- infrahub/core/diff/query/save.py +151 -66
- infrahub/core/diff/query/summary_counts_enricher.py +220 -0
- infrahub/core/diff/query/time_range_query.py +3 -2
- infrahub/core/diff/query/update_conflict_query.py +1 -1
- infrahub/core/diff/query_parser.py +49 -24
- infrahub/core/diff/repository/deserializer.py +24 -25
- infrahub/core/diff/repository/repository.py +76 -20
- infrahub/core/diff/tasks.py +9 -8
- infrahub/core/enums.py +1 -1
- infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
- infrahub/core/ipam/reconciler.py +1 -1
- infrahub/core/ipam/tasks.py +2 -3
- infrahub/core/manager.py +18 -13
- infrahub/core/merge.py +5 -2
- infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
- infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
- infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
- infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
- infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
- infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
- infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
- infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
- infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
- infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
- infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
- infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
- infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
- infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
- infrahub/core/migrations/query/attribute_add.py +1 -1
- infrahub/core/migrations/query/attribute_rename.py +1 -1
- infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
- infrahub/core/migrations/query/node_duplicate.py +1 -1
- infrahub/core/migrations/query/relationship_duplicate.py +1 -1
- infrahub/core/migrations/query/schema_attribute_update.py +1 -1
- infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
- infrahub/core/migrations/schema/node_remove.py +1 -1
- infrahub/core/migrations/schema/tasks.py +5 -5
- infrahub/core/migrations/shared.py +4 -4
- infrahub/core/models.py +7 -8
- infrahub/core/node/__init__.py +161 -40
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
- infrahub/core/node/delete_validator.py +4 -4
- infrahub/core/node/ipam.py +13 -8
- infrahub/core/node/permissions.py +4 -0
- infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
- infrahub/core/node/standard.py +3 -5
- infrahub/core/property.py +1 -1
- infrahub/core/protocols.py +4 -0
- infrahub/core/protocols_base.py +4 -2
- infrahub/core/query/__init__.py +2 -5
- infrahub/core/query/attribute.py +9 -9
- infrahub/core/query/branch.py +5 -5
- infrahub/core/query/delete.py +1 -1
- infrahub/core/query/diff.py +45 -7
- infrahub/core/query/ipam.py +4 -4
- infrahub/core/query/node.py +19 -14
- infrahub/core/query/relationship.py +10 -11
- infrahub/core/query/resource_manager.py +13 -11
- infrahub/core/query/standard_node.py +6 -6
- infrahub/core/query/task.py +3 -3
- infrahub/core/query/task_log.py +1 -1
- infrahub/core/query/utils.py +5 -5
- infrahub/core/registry.py +0 -2
- infrahub/core/relationship/constraints/count.py +1 -1
- infrahub/core/relationship/constraints/peer_kind.py +1 -1
- infrahub/core/relationship/model.py +66 -26
- infrahub/core/schema/__init__.py +6 -4
- infrahub/core/schema/basenode_schema.py +1 -3
- infrahub/core/schema/definitions/core.py +14 -2
- infrahub/core/schema/definitions/internal.py +16 -0
- infrahub/core/schema/generated/genericnode_schema.py +5 -0
- infrahub/core/schema/generated/node_schema.py +5 -0
- infrahub/core/schema/generic_schema.py +5 -1
- infrahub/core/schema/manager.py +45 -42
- infrahub/core/schema/node_schema.py +4 -0
- infrahub/core/schema/profile_schema.py +4 -0
- infrahub/core/schema/relationship_schema.py +2 -2
- infrahub/core/schema/schema_branch.py +248 -14
- infrahub/core/schema/template_schema.py +36 -0
- infrahub/core/task/user_task.py +7 -5
- infrahub/core/timestamp.py +1 -1
- infrahub/core/utils.py +3 -2
- infrahub/core/validators/attribute/choices.py +1 -1
- infrahub/core/validators/attribute/enum.py +1 -1
- infrahub/core/validators/attribute/kind.py +1 -1
- infrahub/core/validators/attribute/length.py +1 -1
- infrahub/core/validators/attribute/optional.py +1 -1
- infrahub/core/validators/attribute/regex.py +1 -1
- infrahub/core/validators/attribute/unique.py +1 -1
- infrahub/core/validators/checks_runner.py +37 -0
- infrahub/core/validators/node/generate_profile.py +1 -1
- infrahub/core/validators/node/hierarchy.py +1 -1
- infrahub/core/validators/query.py +1 -1
- infrahub/core/validators/relationship/count.py +1 -1
- infrahub/core/validators/relationship/optional.py +1 -1
- infrahub/core/validators/relationship/peer.py +1 -1
- infrahub/core/validators/tasks.py +8 -6
- infrahub/core/validators/uniqueness/query.py +20 -17
- infrahub/database/__init__.py +15 -2
- infrahub/database/memgraph.py +1 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
- infrahub/dependencies/builder/diff/combiner.py +1 -1
- infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
- infrahub/dependencies/builder/diff/coordinator.py +0 -2
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
- infrahub/events/branch_action.py +47 -21
- infrahub/events/group_action.py +73 -0
- infrahub/events/models.py +159 -51
- infrahub/events/node_action.py +74 -8
- infrahub/events/repository_action.py +8 -8
- infrahub/events/schema_action.py +21 -8
- infrahub/generators/tasks.py +12 -13
- infrahub/git/base.py +3 -5
- infrahub/git/constants.py +0 -1
- infrahub/git/integrator.py +36 -35
- infrahub/git/repository.py +7 -8
- infrahub/git/tasks.py +43 -107
- infrahub/git_credential/helper.py +2 -3
- infrahub/graphql/analyzer.py +572 -11
- infrahub/graphql/app.py +34 -26
- infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
- infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
- infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
- infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
- infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
- infrahub/graphql/enums.py +1 -1
- infrahub/graphql/initialization.py +5 -1
- infrahub/graphql/loaders/node.py +2 -2
- infrahub/graphql/manager.py +59 -54
- infrahub/graphql/mutations/account.py +20 -13
- infrahub/graphql/mutations/artifact_definition.py +16 -12
- infrahub/graphql/mutations/branch.py +61 -40
- infrahub/graphql/mutations/computed_attribute.py +19 -13
- infrahub/graphql/mutations/diff.py +37 -9
- infrahub/graphql/mutations/diff_conflict.py +9 -8
- infrahub/graphql/mutations/graphql_query.py +19 -11
- infrahub/graphql/mutations/ipam.py +21 -19
- infrahub/graphql/mutations/main.py +197 -44
- infrahub/graphql/mutations/menu.py +8 -8
- infrahub/graphql/mutations/proposed_change.py +36 -28
- infrahub/graphql/mutations/relationship.py +302 -105
- infrahub/graphql/mutations/repository.py +41 -35
- infrahub/graphql/mutations/resource_manager.py +26 -26
- infrahub/graphql/mutations/schema.py +51 -33
- infrahub/graphql/mutations/tasks.py +16 -10
- infrahub/graphql/parser.py +1 -1
- infrahub/graphql/permissions.py +6 -4
- infrahub/graphql/queries/account.py +22 -18
- infrahub/graphql/queries/branch.py +6 -4
- infrahub/graphql/queries/diff/tree.py +48 -42
- infrahub/graphql/queries/event.py +112 -0
- infrahub/graphql/queries/internal.py +3 -3
- infrahub/graphql/queries/ipam.py +23 -18
- infrahub/graphql/queries/relationship.py +11 -10
- infrahub/graphql/queries/resource_manager.py +43 -27
- infrahub/graphql/queries/search.py +9 -8
- infrahub/graphql/queries/status.py +12 -9
- infrahub/graphql/queries/task.py +11 -9
- infrahub/graphql/resolvers/resolver.py +69 -43
- infrahub/graphql/resolvers/single_relationship.py +16 -10
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/subscription/__init__.py +1 -1
- infrahub/graphql/subscription/events.py +1 -1
- infrahub/graphql/subscription/graphql_query.py +8 -8
- infrahub/graphql/types/branch.py +2 -2
- infrahub/graphql/types/common.py +6 -1
- infrahub/graphql/types/enums.py +2 -0
- infrahub/graphql/types/event.py +100 -0
- infrahub/graphql/types/interface.py +2 -2
- infrahub/graphql/types/node.py +3 -3
- infrahub/graphql/types/permission.py +2 -2
- infrahub/graphql/types/relationship.py +3 -3
- infrahub/graphql/types/standard_node.py +9 -11
- infrahub/graphql/utils.py +28 -182
- infrahub/groups/tasks.py +2 -3
- infrahub/lock.py +1 -1
- infrahub/menu/constants.py +1 -0
- infrahub/menu/generator.py +14 -3
- infrahub/menu/menu.py +116 -127
- infrahub/menu/models.py +4 -4
- infrahub/message_bus/messages/__init__.py +0 -4
- infrahub/message_bus/messages/event_branch_merge.py +3 -0
- infrahub/message_bus/messages/request_proposedchange_pipeline.py +2 -0
- infrahub/message_bus/operations/__init__.py +3 -5
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -3
- infrahub/message_bus/operations/check/repository.py +1 -1
- infrahub/message_bus/operations/event/branch.py +7 -3
- infrahub/message_bus/operations/event/schema.py +1 -1
- infrahub/message_bus/operations/finalize/validator.py +1 -1
- infrahub/message_bus/operations/git/file.py +2 -2
- infrahub/message_bus/operations/git/repository.py +1 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -2
- infrahub/message_bus/operations/requests/generator_definition.py +1 -1
- infrahub/message_bus/operations/requests/proposed_change.py +26 -11
- infrahub/message_bus/operations/requests/repository.py +2 -2
- infrahub/message_bus/operations/send/echo.py +1 -1
- infrahub/message_bus/types.py +1 -1
- infrahub/permissions/__init__.py +2 -1
- infrahub/permissions/types.py +26 -0
- infrahub/pools/prefix.py +29 -165
- infrahub/prefect_server/__init__.py +0 -0
- infrahub/prefect_server/app.py +18 -0
- infrahub/prefect_server/database.py +20 -0
- infrahub/prefect_server/events.py +28 -0
- infrahub/prefect_server/models.py +46 -0
- infrahub/proposed_change/models.py +15 -1
- infrahub/proposed_change/tasks.py +173 -35
- infrahub/pytest_plugin.py +4 -4
- infrahub/server.py +12 -11
- infrahub/services/__init__.py +147 -62
- infrahub/services/adapters/cache/__init__.py +7 -5
- infrahub/services/adapters/cache/nats.py +40 -22
- infrahub/services/adapters/cache/redis.py +0 -4
- infrahub/services/adapters/event/__init__.py +10 -18
- infrahub/services/adapters/http/__init__.py +0 -5
- infrahub/services/adapters/http/httpx.py +22 -15
- infrahub/services/adapters/message_bus/__init__.py +23 -6
- infrahub/services/adapters/message_bus/local.py +8 -6
- infrahub/services/adapters/message_bus/nats.py +12 -6
- infrahub/services/adapters/message_bus/rabbitmq.py +22 -9
- infrahub/services/adapters/workflow/__init__.py +11 -8
- infrahub/services/adapters/workflow/local.py +28 -7
- infrahub/services/adapters/workflow/worker.py +23 -7
- infrahub/services/component.py +38 -35
- infrahub/services/scheduler.py +32 -29
- infrahub/storage.py +2 -4
- infrahub/task_manager/constants.py +1 -1
- infrahub/task_manager/event.py +182 -0
- infrahub/task_manager/models.py +125 -1
- infrahub/task_manager/task.py +1 -1
- infrahub/tasks/artifact.py +14 -16
- infrahub/tasks/registry.py +1 -1
- infrahub/tasks/telemetry.py +13 -14
- infrahub/transformations/tasks.py +3 -5
- infrahub/trigger/__init__.py +0 -0
- infrahub/trigger/catalogue.py +15 -0
- infrahub/trigger/constants.py +9 -0
- infrahub/trigger/models.py +69 -0
- infrahub/trigger/tasks.py +85 -0
- infrahub/types.py +1 -1
- infrahub/utils.py +1 -1
- infrahub/webhook/constants.py +0 -2
- infrahub/webhook/models.py +8 -2
- infrahub/webhook/tasks.py +20 -73
- infrahub/webhook/triggers.py +20 -0
- infrahub/workers/infrahub_async.py +36 -25
- infrahub/workers/utils.py +63 -0
- infrahub/workflows/catalogue.py +13 -37
- infrahub/workflows/initialization.py +6 -8
- infrahub/workflows/models.py +3 -5
- infrahub/workflows/utils.py +1 -1
- infrahub_sdk/ctl/check.py +3 -3
- infrahub_sdk/ctl/cli_commands.py +11 -10
- infrahub_sdk/ctl/exceptions.py +0 -6
- infrahub_sdk/ctl/exporter.py +1 -1
- infrahub_sdk/ctl/generator.py +5 -5
- infrahub_sdk/ctl/importer.py +3 -2
- infrahub_sdk/ctl/menu.py +1 -1
- infrahub_sdk/ctl/object.py +1 -1
- infrahub_sdk/ctl/repository.py +23 -15
- infrahub_sdk/ctl/schema.py +2 -2
- infrahub_sdk/ctl/utils.py +4 -3
- infrahub_sdk/ctl/validate.py +2 -1
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +3 -0
- infrahub_sdk/node.py +2 -2
- infrahub_sdk/schema/__init__.py +14 -2
- infrahub_sdk/schema/main.py +7 -0
- infrahub_sdk/utils.py +11 -1
- infrahub_sdk/yaml.py +2 -3
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/METADATA +46 -12
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/RECORD +338 -321
- infrahub_testcontainers/container.py +14 -6
- infrahub_testcontainers/docker-compose.test.yml +24 -5
- infrahub_testcontainers/haproxy.cfg +43 -0
- infrahub_testcontainers/helpers.py +85 -1
- infrahub/core/branch/constants.py +0 -2
- infrahub/graphql/query.py +0 -52
- infrahub/message_bus/messages/request_artifactdefinition_check.py +0 -17
- infrahub/message_bus/operations/requests/artifact_definition.py +0 -148
- infrahub/schema/constants.py +0 -1
- infrahub/schema/tasks.py +0 -76
- infrahub/services/adapters/database/__init__.py +0 -9
- infrahub_sdk/ctl/_file.py +0 -13
- /infrahub/{schema → artifacts}/__init__.py +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0rc0.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Mapping, Optional, Union
|
|
4
4
|
|
|
5
5
|
from graphene import InputObjectType, Mutation
|
|
6
6
|
from graphene.types.mutation import MutationOptions
|
|
@@ -9,13 +9,15 @@ from typing_extensions import Self
|
|
|
9
9
|
|
|
10
10
|
from infrahub import config, lock
|
|
11
11
|
from infrahub.core import registry
|
|
12
|
-
from infrahub.core.
|
|
12
|
+
from infrahub.core.changelog.models import RelationshipChangelogGetter
|
|
13
|
+
from infrahub.core.constants import InfrahubKind, MutationAction, RelationshipCardinality, RelationshipKind
|
|
13
14
|
from infrahub.core.constraint.node.runner import NodeConstraintRunner
|
|
14
15
|
from infrahub.core.manager import NodeManager
|
|
15
16
|
from infrahub.core.node import Node
|
|
16
|
-
from infrahub.core.schema import NodeSchema
|
|
17
|
+
from infrahub.core.schema import NodeSchema, RelationshipSchema
|
|
17
18
|
from infrahub.core.schema.generic_schema import GenericSchema
|
|
18
19
|
from infrahub.core.schema.profile_schema import ProfileSchema
|
|
20
|
+
from infrahub.core.schema.template_schema import TemplateSchema
|
|
19
21
|
from infrahub.core.timestamp import Timestamp
|
|
20
22
|
from infrahub.database import retry_db_transaction
|
|
21
23
|
from infrahub.dependencies.registry import get_component_registry
|
|
@@ -33,13 +35,14 @@ if TYPE_CHECKING:
|
|
|
33
35
|
from graphql import GraphQLResolveInfo
|
|
34
36
|
|
|
35
37
|
from infrahub.core.branch import Branch
|
|
38
|
+
from infrahub.core.protocols import CoreObjectTemplate
|
|
39
|
+
from infrahub.core.relationship.model import RelationshipManager
|
|
36
40
|
from infrahub.core.schema.schema_branch import SchemaBranch
|
|
37
41
|
from infrahub.database import InfrahubDatabase
|
|
38
42
|
|
|
39
43
|
from ..initialization import GraphqlContext
|
|
40
44
|
from .node_getter.interface import MutationNodeGetterInterface
|
|
41
45
|
|
|
42
|
-
# pylint: disable=unused-argument
|
|
43
46
|
|
|
44
47
|
log = get_logger()
|
|
45
48
|
|
|
@@ -55,60 +58,86 @@ class InfrahubMutationOptions(MutationOptions):
|
|
|
55
58
|
|
|
56
59
|
class InfrahubMutationMixin:
|
|
57
60
|
@classmethod
|
|
58
|
-
async def mutate(cls, root: dict, info: GraphQLResolveInfo, data: InputObjectType, *args: Any, **kwargs):
|
|
59
|
-
|
|
61
|
+
async def mutate(cls, root: dict, info: GraphQLResolveInfo, data: InputObjectType, *args: Any, **kwargs): # noqa: ARG003
|
|
62
|
+
graphql_context: GraphqlContext = info.context
|
|
60
63
|
|
|
61
64
|
obj = None
|
|
62
65
|
mutation = None
|
|
63
66
|
action = MutationAction.UNDEFINED
|
|
64
67
|
|
|
65
68
|
if "Create" in cls.__name__:
|
|
66
|
-
obj, mutation = await cls.mutate_create(info=info, branch=
|
|
67
|
-
action = MutationAction.
|
|
69
|
+
obj, mutation = await cls.mutate_create(info=info, branch=graphql_context.branch, data=data, **kwargs)
|
|
70
|
+
action = MutationAction.CREATED
|
|
68
71
|
elif "Update" in cls.__name__:
|
|
69
|
-
obj, mutation = await cls.mutate_update(info=info, branch=
|
|
72
|
+
obj, mutation = await cls.mutate_update(info=info, branch=graphql_context.branch, data=data, **kwargs)
|
|
70
73
|
action = MutationAction.UPDATED
|
|
71
74
|
elif "Upsert" in cls.__name__:
|
|
72
75
|
node_manager = NodeManager()
|
|
73
76
|
node_getters = [
|
|
74
|
-
MutationNodeGetterById(db=
|
|
75
|
-
MutationNodeGetterByHfid(db=
|
|
76
|
-
MutationNodeGetterByDefaultFilter(db=
|
|
77
|
+
MutationNodeGetterById(db=graphql_context.db, node_manager=node_manager),
|
|
78
|
+
MutationNodeGetterByHfid(db=graphql_context.db, node_manager=node_manager),
|
|
79
|
+
MutationNodeGetterByDefaultFilter(db=graphql_context.db, node_manager=node_manager),
|
|
77
80
|
]
|
|
78
81
|
obj, mutation, created = await cls.mutate_upsert(
|
|
79
|
-
info=info, branch=
|
|
82
|
+
info=info, branch=graphql_context.branch, data=data, node_getters=node_getters, **kwargs
|
|
80
83
|
)
|
|
81
84
|
if created:
|
|
82
|
-
action = MutationAction.
|
|
85
|
+
action = MutationAction.CREATED
|
|
83
86
|
else:
|
|
84
87
|
action = MutationAction.UPDATED
|
|
85
88
|
elif "Delete" in cls.__name__:
|
|
86
|
-
obj, mutation = await cls.mutate_delete(info=info, branch=
|
|
87
|
-
action = MutationAction.
|
|
89
|
+
obj, mutation = await cls.mutate_delete(info=info, branch=graphql_context.branch, data=data, **kwargs)
|
|
90
|
+
action = MutationAction.DELETED
|
|
88
91
|
else:
|
|
89
92
|
raise ValueError(
|
|
90
93
|
f"Unexpected class Name: {cls.__name__}, should end with Create, Update, Upsert, or Delete"
|
|
91
94
|
)
|
|
92
95
|
|
|
93
96
|
# Reset the time of the query to guarantee that all resolvers executed after this point will account for the changes
|
|
94
|
-
|
|
97
|
+
graphql_context.at = Timestamp()
|
|
95
98
|
|
|
96
|
-
if config.SETTINGS.broker.enable and
|
|
99
|
+
if config.SETTINGS.broker.enable and graphql_context.background and obj.node_changelog.has_changes:
|
|
97
100
|
log_data = get_log_data()
|
|
98
101
|
request_id = log_data.get("request_id", "")
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
account_id: str | None = None
|
|
104
|
+
if graphql_context.account_session:
|
|
105
|
+
account_id = graphql_context.account_session.account_id
|
|
106
|
+
|
|
107
|
+
meta = EventMeta(
|
|
108
|
+
account_id=account_id,
|
|
109
|
+
initiator_id=WORKER_IDENTITY,
|
|
110
|
+
request_id=request_id,
|
|
111
|
+
branch=graphql_context.branch,
|
|
112
|
+
context=graphql_context.get_context(),
|
|
113
|
+
)
|
|
114
|
+
main_event = NodeMutatedEvent(
|
|
103
115
|
kind=obj._schema.kind,
|
|
104
116
|
node_id=obj.id,
|
|
105
|
-
data=
|
|
117
|
+
data=obj.node_changelog,
|
|
106
118
|
action=action,
|
|
107
119
|
fields=_get_data_fields(data),
|
|
108
|
-
meta=
|
|
120
|
+
meta=meta,
|
|
109
121
|
)
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
relationship_changelogs = RelationshipChangelogGetter(db=graphql_context.db, branch=graphql_context.branch)
|
|
123
|
+
node_changelogs = await relationship_changelogs.get_changelogs(primary_changelog=obj.node_changelog)
|
|
124
|
+
|
|
125
|
+
events = [main_event]
|
|
126
|
+
|
|
127
|
+
for node_changelog in node_changelogs:
|
|
128
|
+
meta = EventMeta.from_parent(parent=main_event)
|
|
129
|
+
event = NodeMutatedEvent(
|
|
130
|
+
kind=node_changelog.node_kind,
|
|
131
|
+
node_id=node_changelog.node_id,
|
|
132
|
+
data=node_changelog,
|
|
133
|
+
action=MutationAction.UPDATED,
|
|
134
|
+
fields=node_changelog.updated_fields,
|
|
135
|
+
meta=meta,
|
|
136
|
+
)
|
|
137
|
+
events.append(event)
|
|
138
|
+
|
|
139
|
+
for event in events:
|
|
140
|
+
graphql_context.background.add_task(graphql_context.active_service.event.send, event)
|
|
112
141
|
|
|
113
142
|
return mutation
|
|
114
143
|
|
|
@@ -127,7 +156,7 @@ class InfrahubMutationMixin:
|
|
|
127
156
|
return obj
|
|
128
157
|
current_profile_ids = await cls._get_profile_ids(db=db, obj=obj)
|
|
129
158
|
if previous_profile_ids is None or previous_profile_ids != current_profile_ids:
|
|
130
|
-
|
|
159
|
+
refreshed_node = await NodeManager.get_one_by_id_or_default_filter(
|
|
131
160
|
db=db,
|
|
132
161
|
kind=cls._meta.schema.kind,
|
|
133
162
|
id=obj.get_id(),
|
|
@@ -135,6 +164,8 @@ class InfrahubMutationMixin:
|
|
|
135
164
|
include_owner=True,
|
|
136
165
|
include_source=True,
|
|
137
166
|
)
|
|
167
|
+
refreshed_node._node_changelog = obj.node_changelog
|
|
168
|
+
return refreshed_node
|
|
138
169
|
return obj
|
|
139
170
|
|
|
140
171
|
@classmethod
|
|
@@ -152,6 +183,95 @@ class InfrahubMutationMixin:
|
|
|
152
183
|
|
|
153
184
|
return await cls.mutate_create_object(data=data, db=db, branch=branch)
|
|
154
185
|
|
|
186
|
+
@classmethod
|
|
187
|
+
async def _get_template_relationship_peers(
|
|
188
|
+
cls, db: InfrahubDatabase, template: CoreObjectTemplate, relationship: RelationshipSchema
|
|
189
|
+
) -> Mapping[str, Node]:
|
|
190
|
+
"""For a given relationship on the template, fetch the related peers."""
|
|
191
|
+
template_relationship_manager: RelationshipManager = getattr(template, relationship.name)
|
|
192
|
+
if relationship.cardinality == RelationshipCardinality.MANY:
|
|
193
|
+
return await template_relationship_manager.get_peers(db=db)
|
|
194
|
+
|
|
195
|
+
peers: dict[str, Node] = {}
|
|
196
|
+
template_relationship_peer = await template_relationship_manager.get_peer(db=db)
|
|
197
|
+
if template_relationship_peer:
|
|
198
|
+
peers[template_relationship_peer.id] = template_relationship_peer
|
|
199
|
+
return peers
|
|
200
|
+
|
|
201
|
+
@classmethod
|
|
202
|
+
async def _extract_peer_data(
|
|
203
|
+
cls,
|
|
204
|
+
db: InfrahubDatabase,
|
|
205
|
+
template_peer: Node,
|
|
206
|
+
obj_peer_schema,
|
|
207
|
+
parent_obj: Node,
|
|
208
|
+
current_template: CoreObjectTemplate,
|
|
209
|
+
) -> Mapping[str, Any]:
|
|
210
|
+
obj_peer_data: dict[str, Any] = {}
|
|
211
|
+
|
|
212
|
+
for attr in template_peer.get_schema().attribute_names:
|
|
213
|
+
if attr not in obj_peer_schema.attribute_names:
|
|
214
|
+
continue
|
|
215
|
+
obj_peer_data[attr] = {"value": getattr(template_peer, attr).value}
|
|
216
|
+
|
|
217
|
+
for rel in template_peer.get_schema().relationship_names:
|
|
218
|
+
rel_manager: RelationshipManager = getattr(template_peer, rel)
|
|
219
|
+
if (
|
|
220
|
+
rel_manager.schema.kind not in [RelationshipKind.COMPONENT, RelationshipKind.PARENT]
|
|
221
|
+
or rel_manager.schema.name not in obj_peer_schema.relationship_names
|
|
222
|
+
):
|
|
223
|
+
continue
|
|
224
|
+
|
|
225
|
+
if list(await rel_manager.get_peers(db=db)) == [current_template.id]:
|
|
226
|
+
obj_peer_data[rel] = {"id": parent_obj.id}
|
|
227
|
+
|
|
228
|
+
return obj_peer_data
|
|
229
|
+
|
|
230
|
+
@classmethod
|
|
231
|
+
async def _handle_template_relationships(
|
|
232
|
+
cls,
|
|
233
|
+
db: InfrahubDatabase,
|
|
234
|
+
branch: Branch,
|
|
235
|
+
obj: Node,
|
|
236
|
+
template: CoreObjectTemplate,
|
|
237
|
+
data: InputObjectType,
|
|
238
|
+
constraint_runner: NodeConstraintRunner | None = None,
|
|
239
|
+
) -> None:
|
|
240
|
+
if constraint_runner is None:
|
|
241
|
+
component_registry = get_component_registry()
|
|
242
|
+
constraint_runner = await component_registry.get_component(NodeConstraintRunner, db=db, branch=branch)
|
|
243
|
+
|
|
244
|
+
for relationship in obj.get_relationships(kind=RelationshipKind.COMPONENT, exclude=list(data)):
|
|
245
|
+
template_relationship_peers = await cls._get_template_relationship_peers(
|
|
246
|
+
db=db, template=template, relationship=relationship
|
|
247
|
+
)
|
|
248
|
+
if not template_relationship_peers:
|
|
249
|
+
continue
|
|
250
|
+
|
|
251
|
+
obj_peer_schema = relationship.get_peer_schema(db=db, branch=branch)
|
|
252
|
+
for template_relationship_peer in template_relationship_peers.values():
|
|
253
|
+
obj_peer_data = await cls._extract_peer_data(
|
|
254
|
+
db=db,
|
|
255
|
+
template_peer=template_relationship_peer,
|
|
256
|
+
obj_peer_schema=obj_peer_schema,
|
|
257
|
+
parent_obj=obj,
|
|
258
|
+
current_template=template,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
obj_peer = await Node.init(schema=obj_peer_schema, db=db)
|
|
262
|
+
await obj_peer.new(db=db, **obj_peer_data)
|
|
263
|
+
await constraint_runner.check(node=obj_peer, field_filters=list(obj_peer_data))
|
|
264
|
+
await obj_peer.save(db=db)
|
|
265
|
+
|
|
266
|
+
await cls._handle_template_relationships(
|
|
267
|
+
db=db,
|
|
268
|
+
branch=branch,
|
|
269
|
+
constraint_runner=constraint_runner,
|
|
270
|
+
obj=obj_peer,
|
|
271
|
+
template=template_relationship_peer,
|
|
272
|
+
data=data,
|
|
273
|
+
)
|
|
274
|
+
|
|
155
275
|
@classmethod
|
|
156
276
|
async def mutate_create(
|
|
157
277
|
cls,
|
|
@@ -160,8 +280,8 @@ class InfrahubMutationMixin:
|
|
|
160
280
|
branch: Branch,
|
|
161
281
|
database: Optional[InfrahubDatabase] = None,
|
|
162
282
|
) -> tuple[Node, Self]:
|
|
163
|
-
|
|
164
|
-
db = database or
|
|
283
|
+
graphql_context: GraphqlContext = info.context
|
|
284
|
+
db = database or graphql_context.db
|
|
165
285
|
obj = await cls._call_mutate_create_object(data=data, db=db, branch=branch)
|
|
166
286
|
result = await cls.mutate_create_to_graphql(info=info, db=db, obj=obj)
|
|
167
287
|
return obj, result
|
|
@@ -175,22 +295,46 @@ class InfrahubMutationMixin:
|
|
|
175
295
|
branch: Branch,
|
|
176
296
|
) -> Node:
|
|
177
297
|
component_registry = get_component_registry()
|
|
178
|
-
node_constraint_runner = await component_registry.get_component(
|
|
298
|
+
node_constraint_runner = await component_registry.get_component(
|
|
299
|
+
NodeConstraintRunner, db=db.start_session(), branch=branch
|
|
300
|
+
)
|
|
179
301
|
node_class = Node
|
|
180
302
|
if cls._meta.schema.kind in registry.node:
|
|
181
303
|
node_class = registry.node[cls._meta.schema.kind]
|
|
182
304
|
|
|
305
|
+
fields_to_validate = list(data)
|
|
183
306
|
try:
|
|
184
|
-
obj = await node_class.init(db=db, schema=cls._meta.schema, branch=branch)
|
|
185
|
-
await obj.new(db=db, **data)
|
|
186
|
-
fields_to_validate = list(data)
|
|
187
|
-
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
188
307
|
if db.is_transaction:
|
|
308
|
+
obj = await node_class.init(db=db, schema=cls._meta.schema, branch=branch)
|
|
309
|
+
await obj.new(db=db, **data)
|
|
310
|
+
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
189
311
|
await obj.save(db=db)
|
|
312
|
+
|
|
313
|
+
object_template = await obj.get_object_template(db=db)
|
|
314
|
+
if object_template:
|
|
315
|
+
await cls._handle_template_relationships(
|
|
316
|
+
db=db,
|
|
317
|
+
branch=branch,
|
|
318
|
+
template=object_template,
|
|
319
|
+
obj=obj,
|
|
320
|
+
data=data,
|
|
321
|
+
)
|
|
190
322
|
else:
|
|
191
323
|
async with db.start_transaction() as dbt:
|
|
324
|
+
obj = await node_class.init(db=dbt, schema=cls._meta.schema, branch=branch)
|
|
325
|
+
await obj.new(db=dbt, **data)
|
|
326
|
+
await node_constraint_runner.check(node=obj, field_filters=fields_to_validate)
|
|
192
327
|
await obj.save(db=dbt)
|
|
193
328
|
|
|
329
|
+
object_template = await obj.get_object_template(db=dbt)
|
|
330
|
+
if object_template:
|
|
331
|
+
await cls._handle_template_relationships(
|
|
332
|
+
db=dbt,
|
|
333
|
+
branch=branch,
|
|
334
|
+
template=object_template,
|
|
335
|
+
obj=obj,
|
|
336
|
+
data=data,
|
|
337
|
+
)
|
|
194
338
|
except ValidationError as exc:
|
|
195
339
|
raise ValueError(str(exc)) from exc
|
|
196
340
|
|
|
@@ -253,8 +397,8 @@ class InfrahubMutationMixin:
|
|
|
253
397
|
database: Optional[InfrahubDatabase] = None,
|
|
254
398
|
node: Optional[Node] = None,
|
|
255
399
|
) -> tuple[Node, Self]:
|
|
256
|
-
|
|
257
|
-
db = database or
|
|
400
|
+
graphql_context: GraphqlContext = info.context
|
|
401
|
+
db = database or graphql_context.db
|
|
258
402
|
|
|
259
403
|
obj = node or await NodeManager.find_object(
|
|
260
404
|
db=db, kind=cls._meta.schema.kind, id=data.get("id"), hfid=data.get("hfid"), branch=branch
|
|
@@ -269,7 +413,12 @@ class InfrahubMutationMixin:
|
|
|
269
413
|
|
|
270
414
|
@classmethod
|
|
271
415
|
async def mutate_update_object(
|
|
272
|
-
cls,
|
|
416
|
+
cls,
|
|
417
|
+
db: InfrahubDatabase,
|
|
418
|
+
info: GraphQLResolveInfo, # noqa: ARG003
|
|
419
|
+
data: InputObjectType,
|
|
420
|
+
branch: Branch,
|
|
421
|
+
obj: Node,
|
|
273
422
|
) -> Node:
|
|
274
423
|
component_registry = get_component_registry()
|
|
275
424
|
node_constraint_runner = await component_registry.get_component(NodeConstraintRunner, db=db, branch=branch)
|
|
@@ -285,6 +434,7 @@ class InfrahubMutationMixin:
|
|
|
285
434
|
fields.remove(field)
|
|
286
435
|
|
|
287
436
|
await obj.save(db=db, fields=fields)
|
|
437
|
+
|
|
288
438
|
obj = await cls._refresh_for_profile_update(
|
|
289
439
|
db=db, branch=branch, obj=obj, previous_profile_ids=before_mutate_profile_ids
|
|
290
440
|
)
|
|
@@ -316,8 +466,8 @@ class InfrahubMutationMixin:
|
|
|
316
466
|
) -> tuple[Node, Self, bool]:
|
|
317
467
|
schema_name = cls._meta.schema.kind
|
|
318
468
|
|
|
319
|
-
|
|
320
|
-
db = database or
|
|
469
|
+
graphql_context: GraphqlContext = info.context
|
|
470
|
+
db = database or graphql_context.db
|
|
321
471
|
|
|
322
472
|
node_schema = db.schema.get(name=schema_name, branch=branch)
|
|
323
473
|
|
|
@@ -345,14 +495,14 @@ class InfrahubMutationMixin:
|
|
|
345
495
|
data: InputObjectType,
|
|
346
496
|
branch: Branch,
|
|
347
497
|
) -> tuple[Node, Self]:
|
|
348
|
-
|
|
498
|
+
graphql_context: GraphqlContext = info.context
|
|
349
499
|
|
|
350
500
|
obj = await NodeManager.find_object(
|
|
351
|
-
db=
|
|
501
|
+
db=graphql_context.db, kind=cls._meta.schema.kind, id=data.get("id"), hfid=data.get("hfid"), branch=branch
|
|
352
502
|
)
|
|
353
503
|
|
|
354
504
|
try:
|
|
355
|
-
async with
|
|
505
|
+
async with graphql_context.db.start_transaction() as db:
|
|
356
506
|
deleted = await NodeManager.delete(db=db, branch=branch, nodes=[obj])
|
|
357
507
|
except ValidationError as exc:
|
|
358
508
|
raise ValueError(str(exc)) from exc
|
|
@@ -367,11 +517,14 @@ class InfrahubMutationMixin:
|
|
|
367
517
|
|
|
368
518
|
class InfrahubMutation(InfrahubMutationMixin, Mutation):
|
|
369
519
|
@classmethod
|
|
370
|
-
def __init_subclass_with_meta__(
|
|
371
|
-
cls,
|
|
520
|
+
def __init_subclass_with_meta__(
|
|
521
|
+
cls,
|
|
522
|
+
schema: Optional[Union[NodeSchema, GenericSchema, ProfileSchema, TemplateSchema]] = None,
|
|
523
|
+
_meta=None,
|
|
524
|
+
**options,
|
|
372
525
|
) -> None:
|
|
373
526
|
# Make sure schema is a valid NodeSchema Node Class
|
|
374
|
-
if not isinstance(schema,
|
|
527
|
+
if not isinstance(schema, NodeSchema | GenericSchema | ProfileSchema | TemplateSchema):
|
|
375
528
|
raise ValueError(f"You need to pass a valid NodeSchema in '{cls.__name__}.Meta', received '{schema}'")
|
|
376
529
|
|
|
377
530
|
if not _meta:
|
|
@@ -34,7 +34,7 @@ def validate_namespace(data: InputObjectType) -> None:
|
|
|
34
34
|
|
|
35
35
|
class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
36
36
|
@classmethod
|
|
37
|
-
def __init_subclass_with_meta__(
|
|
37
|
+
def __init_subclass_with_meta__(
|
|
38
38
|
cls, schema: NodeSchema, _meta: Optional[Any] = None, **options: dict[str, Any]
|
|
39
39
|
) -> None:
|
|
40
40
|
# Make sure schema is a valid NodeSchema Node Class
|
|
@@ -53,7 +53,7 @@ class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
|
53
53
|
info: GraphQLResolveInfo,
|
|
54
54
|
data: InputObjectType,
|
|
55
55
|
branch: Branch,
|
|
56
|
-
database: Optional[InfrahubDatabase] = None,
|
|
56
|
+
database: Optional[InfrahubDatabase] = None, # noqa: ARG003
|
|
57
57
|
) -> tuple[Node, Self]:
|
|
58
58
|
validate_namespace(data=data)
|
|
59
59
|
|
|
@@ -67,13 +67,13 @@ class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
|
67
67
|
info: GraphQLResolveInfo,
|
|
68
68
|
data: InputObjectType,
|
|
69
69
|
branch: Branch,
|
|
70
|
-
database: Optional[InfrahubDatabase] = None,
|
|
71
|
-
node: Optional[Node] = None,
|
|
70
|
+
database: Optional[InfrahubDatabase] = None, # noqa: ARG003
|
|
71
|
+
node: Optional[Node] = None, # noqa: ARG003
|
|
72
72
|
) -> tuple[Node, Self]:
|
|
73
|
-
|
|
73
|
+
graphql_context: GraphqlContext = info.context
|
|
74
74
|
|
|
75
75
|
obj = await NodeManager.find_object(
|
|
76
|
-
db=
|
|
76
|
+
db=graphql_context.db, kind=CoreMenuItem, id=data.get("id"), hfid=data.get("hfid"), branch=branch
|
|
77
77
|
)
|
|
78
78
|
validate_namespace(data=data)
|
|
79
79
|
|
|
@@ -90,9 +90,9 @@ class InfrahubCoreMenuMutation(InfrahubMutationMixin, Mutation):
|
|
|
90
90
|
data: InputObjectType,
|
|
91
91
|
branch: Branch,
|
|
92
92
|
) -> tuple[Node, Self]:
|
|
93
|
-
|
|
93
|
+
graphql_context: GraphqlContext = info.context
|
|
94
94
|
obj = await NodeManager.find_object(
|
|
95
|
-
db=
|
|
95
|
+
db=graphql_context.db, kind=CoreMenuItem, id=data.get("id"), hfid=data.get("hfid"), branch=branch
|
|
96
96
|
)
|
|
97
97
|
if obj.protected.value:
|
|
98
98
|
raise ValidationError(input_value="This object is protected, it can't be deleted.")
|
|
@@ -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):
|
|
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,12 +49,11 @@ class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
|
49
49
|
info: GraphQLResolveInfo,
|
|
50
50
|
data: InputObjectType,
|
|
51
51
|
branch: Branch,
|
|
52
|
-
database: Optional[InfrahubDatabase] = None,
|
|
52
|
+
database: Optional[InfrahubDatabase] = None, # noqa: ARG003
|
|
53
53
|
):
|
|
54
|
-
|
|
55
|
-
db: InfrahubDatabase = info.context.db
|
|
54
|
+
graphql_context: GraphqlContext = info.context
|
|
56
55
|
|
|
57
|
-
async with db.start_transaction() as dbt:
|
|
56
|
+
async with graphql_context.db.start_transaction() as dbt:
|
|
58
57
|
proposed_change, result = await super().mutate_create(info=info, data=data, branch=branch, database=dbt)
|
|
59
58
|
destination_branch = proposed_change.destination_branch.value
|
|
60
59
|
source_branch = await _get_source_branch(db=dbt, name=proposed_change.source_branch.value)
|
|
@@ -65,34 +64,35 @@ class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
|
65
64
|
input_value="Currently only the 'main' branch is supported as a destination for a proposed change"
|
|
66
65
|
)
|
|
67
66
|
|
|
68
|
-
if
|
|
67
|
+
if graphql_context.service:
|
|
69
68
|
message_list = [
|
|
70
69
|
messages.RequestProposedChangePipeline(
|
|
71
70
|
proposed_change=proposed_change.id,
|
|
72
71
|
source_branch=source_branch.name,
|
|
73
72
|
source_branch_sync_with_git=source_branch.sync_with_git,
|
|
74
73
|
destination_branch=destination_branch,
|
|
74
|
+
context=graphql_context.get_context(),
|
|
75
75
|
),
|
|
76
76
|
]
|
|
77
77
|
|
|
78
78
|
for message in message_list:
|
|
79
|
-
await
|
|
79
|
+
await graphql_context.service.message_bus.send(message=message)
|
|
80
80
|
|
|
81
81
|
return proposed_change, result
|
|
82
82
|
|
|
83
83
|
@classmethod
|
|
84
|
-
async def mutate_update(
|
|
84
|
+
async def mutate_update(
|
|
85
85
|
cls,
|
|
86
86
|
info: GraphQLResolveInfo,
|
|
87
87
|
data: InputObjectType,
|
|
88
88
|
branch: Branch,
|
|
89
|
-
database: Optional[InfrahubDatabase] = None,
|
|
90
|
-
node: Optional[Node] = None,
|
|
89
|
+
database: Optional[InfrahubDatabase] = None, # noqa: ARG003
|
|
90
|
+
node: Optional[Node] = None, # noqa: ARG003
|
|
91
91
|
):
|
|
92
|
-
|
|
92
|
+
graphql_context: GraphqlContext = info.context
|
|
93
93
|
|
|
94
94
|
obj = await NodeManager.get_one_by_id_or_default_filter(
|
|
95
|
-
db=
|
|
95
|
+
db=graphql_context.db,
|
|
96
96
|
kind=cls._meta.schema.kind,
|
|
97
97
|
id=data.get("id"),
|
|
98
98
|
branch=branch,
|
|
@@ -108,9 +108,9 @@ class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
|
108
108
|
state.validate_state_transition(updated_state)
|
|
109
109
|
|
|
110
110
|
# Check before starting a transaction, stopping in the middle of the transaction seems to break with memgraph
|
|
111
|
-
if updated_state == ProposedChangeState.MERGED and
|
|
111
|
+
if updated_state == ProposedChangeState.MERGED and graphql_context.account_session:
|
|
112
112
|
try:
|
|
113
|
-
|
|
113
|
+
graphql_context.active_permissions.raise_for_permission(
|
|
114
114
|
permission=GlobalPermission(
|
|
115
115
|
action=GlobalPermissions.MERGE_PROPOSED_CHANGE.value,
|
|
116
116
|
decision=PermissionDecision.ALLOW_ALL.value,
|
|
@@ -123,17 +123,22 @@ class InfrahubProposedChangeMutation(InfrahubMutationMixin, Mutation):
|
|
|
123
123
|
data["state"]["value"] = ProposedChangeState.MERGING.value
|
|
124
124
|
|
|
125
125
|
proposed_change, result = await super().mutate_update(
|
|
126
|
-
info=info, data=data, branch=branch, database=
|
|
126
|
+
info=info, data=data, branch=branch, database=graphql_context.db, node=obj
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
if updated_state == ProposedChangeState.MERGED:
|
|
130
|
-
await
|
|
130
|
+
await graphql_context.service.workflow.execute_workflow(
|
|
131
131
|
workflow=PROPOSED_CHANGE_MERGE,
|
|
132
|
+
context=graphql_context.get_context(),
|
|
132
133
|
parameters={
|
|
133
134
|
"proposed_change_id": proposed_change.id,
|
|
134
135
|
"proposed_change_name": proposed_change.name.value,
|
|
135
136
|
},
|
|
136
137
|
)
|
|
138
|
+
# When the PROPOSED_CHANGE_MERGE succeeds it will have correctly changed the state
|
|
139
|
+
# from the overridden "merging" value, so here we change it back to reflect the
|
|
140
|
+
# correct value for the event that will be generated.
|
|
141
|
+
proposed_change.node_changelog.attributes["state"].value = ProposedChangeState.MERGED.value
|
|
137
142
|
|
|
138
143
|
return proposed_change, result
|
|
139
144
|
|
|
@@ -152,23 +157,23 @@ class ProposedChangeRequestRunCheck(Mutation):
|
|
|
152
157
|
@classmethod
|
|
153
158
|
async def mutate(
|
|
154
159
|
cls,
|
|
155
|
-
root: dict, #
|
|
160
|
+
root: dict, # noqa: ARG003
|
|
156
161
|
info: GraphQLResolveInfo,
|
|
157
162
|
data: dict[str, Any],
|
|
158
163
|
) -> dict[str, bool]:
|
|
159
|
-
|
|
164
|
+
graphql_context: GraphqlContext = info.context
|
|
160
165
|
|
|
161
166
|
check_type = data.get("check_type") or CheckType.ALL
|
|
162
167
|
|
|
163
168
|
identifier = data.get("id", "")
|
|
164
169
|
proposed_change = await NodeManager.get_one_by_id_or_default_filter(
|
|
165
|
-
id=identifier, kind=InfrahubKind.PROPOSEDCHANGE, db=
|
|
170
|
+
id=identifier, kind=InfrahubKind.PROPOSEDCHANGE, db=graphql_context.db
|
|
166
171
|
)
|
|
167
172
|
state = ProposedChangeState(proposed_change.state.value.value)
|
|
168
173
|
state.validate_state_check_run()
|
|
169
174
|
|
|
170
175
|
destination_branch = proposed_change.destination_branch.value
|
|
171
|
-
source_branch = await _get_source_branch(db=
|
|
176
|
+
source_branch = await _get_source_branch(db=graphql_context.db, name=proposed_change.source_branch.value)
|
|
172
177
|
|
|
173
178
|
message = messages.RequestProposedChangePipeline(
|
|
174
179
|
proposed_change=proposed_change.id,
|
|
@@ -176,9 +181,10 @@ class ProposedChangeRequestRunCheck(Mutation):
|
|
|
176
181
|
source_branch_sync_with_git=source_branch.sync_with_git,
|
|
177
182
|
destination_branch=destination_branch,
|
|
178
183
|
check_type=check_type,
|
|
184
|
+
context=graphql_context.get_context(),
|
|
179
185
|
)
|
|
180
|
-
if
|
|
181
|
-
await
|
|
186
|
+
if graphql_context.service:
|
|
187
|
+
await graphql_context.service.message_bus.send(message=message)
|
|
182
188
|
|
|
183
189
|
return {"ok": True}
|
|
184
190
|
|
|
@@ -198,37 +204,39 @@ class ProposedChangeMerge(Mutation):
|
|
|
198
204
|
@classmethod
|
|
199
205
|
async def mutate(
|
|
200
206
|
cls,
|
|
201
|
-
root: dict, #
|
|
207
|
+
root: dict, # noqa: ARG003
|
|
202
208
|
info: GraphQLResolveInfo,
|
|
203
209
|
data: dict[str, Any],
|
|
204
210
|
wait_until_completion: bool = True,
|
|
205
211
|
) -> dict[str, bool]:
|
|
206
|
-
|
|
212
|
+
graphql_context: GraphqlContext = info.context
|
|
207
213
|
task: dict | None = None
|
|
208
214
|
|
|
209
215
|
identifier = data.get("id", "")
|
|
210
216
|
proposed_change = await NodeManager.get_one(
|
|
211
|
-
id=identifier, kind=InfrahubKind.PROPOSEDCHANGE, db=
|
|
217
|
+
id=identifier, kind=InfrahubKind.PROPOSEDCHANGE, db=graphql_context.db, raise_on_error=True
|
|
212
218
|
)
|
|
213
219
|
state = ProposedChangeState(proposed_change.state.value.value)
|
|
214
220
|
if state != ProposedChangeState.OPEN:
|
|
215
221
|
raise ValidationError("Only proposed change in OPEN state can be merged")
|
|
216
222
|
|
|
217
|
-
async with
|
|
223
|
+
async with graphql_context.db.start_session() as db:
|
|
218
224
|
proposed_change.state.value = ProposedChangeState.MERGING.value
|
|
219
225
|
proposed_change.save(db=db)
|
|
220
226
|
|
|
221
227
|
if wait_until_completion:
|
|
222
|
-
await
|
|
228
|
+
await graphql_context.service.workflow.execute_workflow(
|
|
223
229
|
workflow=PROPOSED_CHANGE_MERGE,
|
|
230
|
+
context=graphql_context.get_context(),
|
|
224
231
|
parameters={
|
|
225
232
|
"proposed_change_id": proposed_change.id,
|
|
226
233
|
"proposed_change_name": proposed_change.name.value,
|
|
227
234
|
},
|
|
228
235
|
)
|
|
229
236
|
else:
|
|
230
|
-
workflow = await
|
|
237
|
+
workflow = await graphql_context.service.workflow.submit_workflow(
|
|
231
238
|
workflow=PROPOSED_CHANGE_MERGE,
|
|
239
|
+
context=graphql_context.get_context(),
|
|
232
240
|
parameters={
|
|
233
241
|
"proposed_change_id": proposed_change.id,
|
|
234
242
|
"proposed_change_name": proposed_change.name.value,
|