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
|
@@ -30,7 +30,7 @@ class RelationshipCountUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
|
30
30
|
self.max_count_override = max_count_override
|
|
31
31
|
super().__init__(**kwargs)
|
|
32
32
|
|
|
33
|
-
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
|
|
33
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
34
34
|
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
|
|
35
35
|
self.params.update(branch_params)
|
|
36
36
|
|
|
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
|
|
|
20
20
|
class RelationshipOptionalUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
21
21
|
name = "relationship_constraints_optional_validator"
|
|
22
22
|
|
|
23
|
-
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
|
|
23
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
24
24
|
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
|
|
25
25
|
self.params.update(branch_params)
|
|
26
26
|
|
|
@@ -21,7 +21,7 @@ if TYPE_CHECKING:
|
|
|
21
21
|
class RelationshipPeerUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
22
22
|
name = "relationship_constraints_peer_validator"
|
|
23
23
|
|
|
24
|
-
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None:
|
|
24
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
25
25
|
peer_schema = db.schema.get(name=self.relationship_schema.peer, branch=self.branch)
|
|
26
26
|
allowed_peer_kinds = [peer_schema.kind]
|
|
27
27
|
if isinstance(peer_schema, GenericSchema):
|
|
@@ -13,14 +13,16 @@ from infrahub.core.validators.model import (
|
|
|
13
13
|
SchemaConstraintValidatorRequest,
|
|
14
14
|
)
|
|
15
15
|
from infrahub.dependencies.registry import get_component_registry
|
|
16
|
-
from infrahub.services import
|
|
16
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
17
17
|
from infrahub.workflows.utils import add_tags
|
|
18
18
|
|
|
19
19
|
from .models.validate_migration import SchemaValidateMigrationData, SchemaValidatorPathResponseData
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@flow(name="schema_validate_migrations", flow_run_name="Validate schema migrations", persist_result=True)
|
|
23
|
-
async def schema_validate_migrations(
|
|
23
|
+
async def schema_validate_migrations(
|
|
24
|
+
message: SchemaValidateMigrationData, service: InfrahubServices
|
|
25
|
+
) -> list[SchemaValidatorPathResponseData]:
|
|
24
26
|
batch = InfrahubBatch(return_exceptions=True)
|
|
25
27
|
log = get_run_logger()
|
|
26
28
|
await add_tags(branches=[message.branch.name])
|
|
@@ -33,7 +35,7 @@ async def schema_validate_migrations(message: SchemaValidateMigrationData) -> li
|
|
|
33
35
|
# NOTE this task is a good candidate to add a progress bar
|
|
34
36
|
for constraint in message.constraints:
|
|
35
37
|
schema = message.schema_branch.get(name=constraint.path.schema_kind)
|
|
36
|
-
if not isinstance(schema,
|
|
38
|
+
if not isinstance(schema, GenericSchema | NodeSchema):
|
|
37
39
|
continue
|
|
38
40
|
batch.add(
|
|
39
41
|
task=schema_path_validate,
|
|
@@ -41,13 +43,14 @@ async def schema_validate_migrations(message: SchemaValidateMigrationData) -> li
|
|
|
41
43
|
constraint_name=constraint.constraint_name,
|
|
42
44
|
node_schema=schema,
|
|
43
45
|
schema_path=constraint.path,
|
|
46
|
+
service=service,
|
|
44
47
|
)
|
|
45
48
|
|
|
46
49
|
results = [result async for _, result in batch.execute()]
|
|
47
50
|
return results
|
|
48
51
|
|
|
49
52
|
|
|
50
|
-
@task(
|
|
53
|
+
@task( # type: ignore[arg-type]
|
|
51
54
|
name="schema-path-validate",
|
|
52
55
|
task_run_name="Validate schema path {constraint_name} in {branch.name}",
|
|
53
56
|
description="Validate if a given migration is compatible with the existing data",
|
|
@@ -59,9 +62,8 @@ async def schema_path_validate(
|
|
|
59
62
|
constraint_name: str,
|
|
60
63
|
node_schema: NodeSchema | GenericSchema,
|
|
61
64
|
schema_path: SchemaPath,
|
|
65
|
+
service: InfrahubServices,
|
|
62
66
|
) -> SchemaValidatorPathResponseData:
|
|
63
|
-
service = services.service
|
|
64
|
-
|
|
65
67
|
async with service.database.start_session() as db:
|
|
66
68
|
constraint_request = SchemaConstraintValidatorRequest(
|
|
67
69
|
branch=branch,
|
|
@@ -30,7 +30,7 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
30
30
|
def get_context(self) -> dict[str, str]:
|
|
31
31
|
return {"kind": self.query_request.kind}
|
|
32
32
|
|
|
33
|
-
async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
|
|
33
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
|
|
34
34
|
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
|
|
35
35
|
self.params.update(branch_params)
|
|
36
36
|
from_times = db.render_list_comprehension(items="relationships(potential_path)", item_name="from")
|
|
@@ -56,6 +56,7 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
56
56
|
relationship_names = set()
|
|
57
57
|
relationship_attr_paths = []
|
|
58
58
|
relationship_only_attr_paths = []
|
|
59
|
+
relationship_only_attr_values = []
|
|
59
60
|
relationship_attr_paths_with_value = []
|
|
60
61
|
for rel_path in self.query_request.relationship_attribute_paths:
|
|
61
62
|
relationship_names.add(rel_path.identifier)
|
|
@@ -67,6 +68,8 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
67
68
|
relationship_attr_paths.append((rel_path.identifier, rel_path.attribute_name))
|
|
68
69
|
else:
|
|
69
70
|
relationship_only_attr_paths.append(rel_path.identifier)
|
|
71
|
+
if rel_path.value:
|
|
72
|
+
relationship_only_attr_values.append(rel_path.value)
|
|
70
73
|
|
|
71
74
|
if (
|
|
72
75
|
not attr_paths
|
|
@@ -89,34 +92,37 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
89
92
|
"relationship_attr_paths": relationship_attr_paths,
|
|
90
93
|
"relationship_attr_paths_with_value": relationship_attr_paths_with_value,
|
|
91
94
|
"relationship_only_attr_paths": relationship_only_attr_paths,
|
|
95
|
+
"relationship_only_attr_values": relationship_only_attr_values,
|
|
92
96
|
"min_count_required": self.min_count_required,
|
|
93
97
|
}
|
|
94
98
|
)
|
|
95
99
|
|
|
96
100
|
attr_paths_subquery = """
|
|
97
|
-
|
|
98
|
-
MATCH attr_path = (start_node)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[r:HAS_VALUE]->(attr_value:AttributeValue)
|
|
101
|
+
MATCH attr_path = (start_node:%(node_kind)s)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[r:HAS_VALUE]->(attr_value:AttributeValue)
|
|
99
102
|
WHERE attr.name in $attribute_names
|
|
100
103
|
AND ([attr.name, type(r)] in $attr_paths
|
|
101
104
|
OR [attr.name, type(r), attr_value.value] in $attr_paths_with_value)
|
|
102
|
-
RETURN attr_path as potential_path, NULL as rel_identifier, attr.name as potential_attr, attr_value.value as potential_attr_value
|
|
103
|
-
"""
|
|
105
|
+
RETURN start_node, attr_path as potential_path, NULL as rel_identifier, attr.name as potential_attr, attr_value.value as potential_attr_value
|
|
106
|
+
""" % {"node_kind": self.query_request.kind}
|
|
104
107
|
|
|
105
108
|
relationship_attr_paths_with_value_subquery = """
|
|
106
|
-
|
|
107
|
-
MATCH rel_path = (start_node)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)-[:HAS_ATTRIBUTE]->(rel_attr:Attribute)-[:HAS_VALUE]->(rel_attr_value:AttributeValue)
|
|
109
|
+
MATCH rel_path = (start_node:%(node_kind)s)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)-[:HAS_ATTRIBUTE]->(rel_attr:Attribute)-[:HAS_VALUE]->(rel_attr_value:AttributeValue)
|
|
108
110
|
WHERE relationship_node.name in $relationship_names
|
|
109
111
|
AND ([relationship_node.name, rel_attr.name] in $relationship_attr_paths
|
|
110
112
|
OR [relationship_node.name, rel_attr.name, rel_attr_value.value] in $relationship_attr_paths_with_value)
|
|
111
|
-
RETURN rel_path as potential_path, relationship_node.name as rel_identifier, rel_attr.name as potential_attr, rel_attr_value.value as potential_attr_value
|
|
112
|
-
"""
|
|
113
|
+
RETURN start_node, rel_path as potential_path, relationship_node.name as rel_identifier, rel_attr.name as potential_attr, rel_attr_value.value as potential_attr_value
|
|
114
|
+
""" % {"node_kind": self.query_request.kind}
|
|
113
115
|
|
|
114
116
|
relationship_only_attr_paths_subquery = """
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
MATCH rel_path = (start_node:%(node_kind)s)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)
|
|
118
|
+
WHERE %(rel_node_filter)s relationship_node.name in $relationship_only_attr_paths
|
|
119
|
+
RETURN start_node, rel_path as potential_path, relationship_node.name as rel_identifier, "id" as potential_attr, related_n.uuid as potential_attr_value
|
|
120
|
+
""" % {
|
|
121
|
+
"node_kind": self.query_request.kind,
|
|
122
|
+
"rel_node_filter": "related_n.uuid IN $relationship_only_attr_values AND "
|
|
123
|
+
if relationship_only_attr_values
|
|
124
|
+
else "",
|
|
125
|
+
}
|
|
120
126
|
|
|
121
127
|
select_subqueries = []
|
|
122
128
|
if attr_paths or attr_paths_with_value:
|
|
@@ -130,8 +136,6 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
130
136
|
|
|
131
137
|
# ruff: noqa: E501
|
|
132
138
|
query = """
|
|
133
|
-
// group by node
|
|
134
|
-
MATCH (start_node:%(node_kind)s)
|
|
135
139
|
// get attributes for node and its relationships
|
|
136
140
|
CALL {
|
|
137
141
|
%(select_subqueries_str)s
|
|
@@ -201,7 +205,6 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
201
205
|
attr_value,
|
|
202
206
|
relationship_identifier
|
|
203
207
|
""" % {
|
|
204
|
-
"node_kind": self.query_request.kind,
|
|
205
208
|
"select_subqueries_str": select_subqueries_str,
|
|
206
209
|
"branch_filter": branch_filter,
|
|
207
210
|
"from_times": from_times,
|
infrahub/database/__init__.py
CHANGED
|
@@ -173,6 +173,19 @@ class InfrahubDatabase:
|
|
|
173
173
|
elif self.db_type == DatabaseType.MEMGRAPH:
|
|
174
174
|
self.manager = DatabaseManagerMemgraph(db=self)
|
|
175
175
|
|
|
176
|
+
def __del__(self) -> None:
|
|
177
|
+
if not self._session or not self._is_session_local or self._session.closed():
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
loop = asyncio.get_running_loop()
|
|
182
|
+
except RuntimeError:
|
|
183
|
+
loop = None
|
|
184
|
+
if loop and loop.is_running():
|
|
185
|
+
loop.create_task(self._session.close())
|
|
186
|
+
else:
|
|
187
|
+
asyncio.run(self._session.close())
|
|
188
|
+
|
|
176
189
|
@property
|
|
177
190
|
def is_session(self) -> bool:
|
|
178
191
|
if self._mode == InfrahubDatabaseMode.SESSION:
|
|
@@ -307,7 +320,7 @@ class InfrahubDatabase:
|
|
|
307
320
|
params: dict[str, Any] | None = None,
|
|
308
321
|
name: str = "undefined",
|
|
309
322
|
context: dict[str, str] | None = None,
|
|
310
|
-
type: QueryType | None = None,
|
|
323
|
+
type: QueryType | None = None,
|
|
311
324
|
) -> list[Record]:
|
|
312
325
|
results, _ = await self.execute_query_with_metadata(
|
|
313
326
|
query=query, params=params, name=name, context=context, type=type
|
|
@@ -320,7 +333,7 @@ class InfrahubDatabase:
|
|
|
320
333
|
params: dict[str, Any] | None = None,
|
|
321
334
|
name: str = "undefined",
|
|
322
335
|
context: dict[str, str] | None = None,
|
|
323
|
-
type: QueryType | None = None,
|
|
336
|
+
type: QueryType | None = None,
|
|
324
337
|
) -> tuple[list[Record], dict[str, Any]]:
|
|
325
338
|
with trace.get_tracer(__name__).start_as_current_span("execute_db_query_with_metadata") as span:
|
|
326
339
|
span.set_attribute("query", query)
|
infrahub/database/memgraph.py
CHANGED
|
@@ -21,7 +21,7 @@ class IndexNodeMemgraph(IndexItem):
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class IndexManagerMemgraph(IndexManagerBase):
|
|
24
|
-
def init(self, nodes: list[IndexItem], rels: list[IndexItem]) -> None:
|
|
24
|
+
def init(self, nodes: list[IndexItem], rels: list[IndexItem]) -> None: # noqa: ARG002
|
|
25
25
|
self.nodes = [IndexNodeMemgraph(**item.model_dump()) for item in nodes]
|
|
26
26
|
self.initialized = True
|
|
27
27
|
|
|
@@ -2,7 +2,6 @@ from infrahub.core.constraint.node.runner import NodeConstraintRunner
|
|
|
2
2
|
from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
|
|
3
3
|
|
|
4
4
|
from ..node.grouped_uniqueness import NodeGroupedUniquenessConstraintDependency
|
|
5
|
-
from ..node.uniqueness import NodeAttributeUniquenessConstraintDependency
|
|
6
5
|
from ..relationship_manager.count import RelationshipCountConstraintDependency
|
|
7
6
|
from ..relationship_manager.peer_kind import RelationshipPeerKindConstraintDependency
|
|
8
7
|
from ..relationship_manager.profiles_kind import RelationshipProfilesKindConstraintDependency
|
|
@@ -15,7 +14,6 @@ class NodeConstraintRunnerDependency(DependencyBuilder[NodeConstraintRunner]):
|
|
|
15
14
|
db=context.db,
|
|
16
15
|
branch=context.branch,
|
|
17
16
|
node_constraints=[
|
|
18
|
-
NodeAttributeUniquenessConstraintDependency.build(context=context),
|
|
19
17
|
NodeGroupedUniquenessConstraintDependency.build(context=context),
|
|
20
18
|
],
|
|
21
19
|
relationship_manager_constraints=[
|
|
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
|
|
|
4
4
|
|
|
5
5
|
class DiffCombinerDependency(DependencyBuilder[DiffCombiner]):
|
|
6
6
|
@classmethod
|
|
7
|
-
def build(cls, context: DependencyBuilderContext) -> DiffCombiner:
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> DiffCombiner: # noqa: ARG003
|
|
8
8
|
return DiffCombiner()
|
|
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
|
|
|
4
4
|
|
|
5
5
|
class DiffConflictsEnricherDependency(DependencyBuilder[ConflictsEnricher]):
|
|
6
6
|
@classmethod
|
|
7
|
-
def build(cls, context: DependencyBuilderContext) -> ConflictsEnricher:
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> ConflictsEnricher: # noqa: ARG003
|
|
8
8
|
return ConflictsEnricher()
|
|
@@ -8,7 +8,6 @@ from .conflicts_enricher import DiffConflictsEnricherDependency
|
|
|
8
8
|
from .data_check_synchronizer import DiffDataCheckSynchronizerDependency
|
|
9
9
|
from .enricher.aggregated import DiffAggregatedEnricherDependency
|
|
10
10
|
from .enricher.labels import DiffLabelsEnricherDependency
|
|
11
|
-
from .enricher.summary_counts import DiffSummaryCountsEnricherDependency
|
|
12
11
|
from .repository import DiffRepositoryDependency
|
|
13
12
|
|
|
14
13
|
|
|
@@ -22,7 +21,6 @@ class DiffCoordinatorDependency(DependencyBuilder[DiffCoordinator]):
|
|
|
22
21
|
diff_enricher=DiffAggregatedEnricherDependency.build(context=context),
|
|
23
22
|
conflicts_enricher=DiffConflictsEnricherDependency.build(context=context),
|
|
24
23
|
labels_enricher=DiffLabelsEnricherDependency.build(context=context),
|
|
25
|
-
summary_counts_enricher=DiffSummaryCountsEnricherDependency.build(context=context),
|
|
26
24
|
data_check_synchronizer=DiffDataCheckSynchronizerDependency.build(context=context),
|
|
27
25
|
conflict_transferer=DiffConflictTransfererDependency.build(context=context),
|
|
28
26
|
)
|
|
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
|
|
|
4
4
|
|
|
5
5
|
class DiffDeserializerDependency(DependencyBuilder[EnrichedDiffDeserializer]):
|
|
6
6
|
@classmethod
|
|
7
|
-
def build(cls, context: DependencyBuilderContext) -> EnrichedDiffDeserializer:
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> EnrichedDiffDeserializer: # noqa: ARG003
|
|
8
8
|
return EnrichedDiffDeserializer()
|
|
@@ -4,5 +4,5 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
|
|
|
4
4
|
|
|
5
5
|
class DiffSummaryCountsEnricherDependency(DependencyBuilder[DiffSummaryCountsEnricher]):
|
|
6
6
|
@classmethod
|
|
7
|
-
def build(cls, context: DependencyBuilderContext) -> DiffSummaryCountsEnricher:
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> DiffSummaryCountsEnricher: # noqa: ARG003
|
|
8
8
|
return DiffSummaryCountsEnricher()
|
infrahub/events/branch_action.py
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
from pydantic import Field
|
|
1
|
+
from pydantic import Field, computed_field
|
|
2
2
|
|
|
3
3
|
from infrahub.message_bus import InfrahubMessage
|
|
4
4
|
from infrahub.message_bus.messages.refresh_registry_branches import RefreshRegistryBranches
|
|
5
5
|
from infrahub.message_bus.messages.refresh_registry_rebasedbranch import RefreshRegistryRebasedBranch
|
|
6
6
|
|
|
7
|
-
from .
|
|
7
|
+
from .constants import EVENT_NAMESPACE
|
|
8
|
+
from .models import InfrahubEvent
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
class
|
|
11
|
+
class BranchDeletedEvent(InfrahubEvent):
|
|
11
12
|
"""Event generated when a branch has been deleted"""
|
|
12
13
|
|
|
14
|
+
branch_name: str = Field(..., description="The name of the branch")
|
|
13
15
|
branch_id: str = Field(..., description="The ID of the mutated node")
|
|
14
16
|
sync_with_git: bool = Field(..., description="Indicates if the branch was extended to Git")
|
|
15
17
|
|
|
16
|
-
def get_name(self) -> str:
|
|
17
|
-
return f"{self.get_event_namespace()}.branch.deleted"
|
|
18
|
-
|
|
19
18
|
def get_resource(self) -> dict[str, str]:
|
|
20
19
|
return {
|
|
21
|
-
"prefect.resource.id": f"infrahub.branch.{self.
|
|
20
|
+
"prefect.resource.id": f"infrahub.branch.{self.branch_name}",
|
|
22
21
|
"infrahub.branch.id": self.branch_id,
|
|
23
|
-
"infrahub.branch.name": self.
|
|
22
|
+
"infrahub.branch.name": self.branch_name,
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
def get_messages(self) -> list[InfrahubMessage]:
|
|
@@ -35,21 +34,23 @@ class BranchDeleteEvent(InfrahubBranchEvent):
|
|
|
35
34
|
]
|
|
36
35
|
return events
|
|
37
36
|
|
|
37
|
+
@computed_field
|
|
38
|
+
def event_name(self) -> str:
|
|
39
|
+
return f"{EVENT_NAMESPACE}.branch.deleted"
|
|
40
|
+
|
|
38
41
|
|
|
39
|
-
class
|
|
42
|
+
class BranchCreatedEvent(InfrahubEvent):
|
|
40
43
|
"""Event generated when a branch has been created"""
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
branch_name: str = Field(..., description="The name of the branch")
|
|
46
|
+
branch_id: str = Field(..., description="The ID of the branch")
|
|
43
47
|
sync_with_git: bool = Field(..., description="Indicates if the branch was extended to Git")
|
|
44
48
|
|
|
45
|
-
def get_name(self) -> str:
|
|
46
|
-
return f"{self.get_event_namespace()}.branch.created"
|
|
47
|
-
|
|
48
49
|
def get_resource(self) -> dict[str, str]:
|
|
49
50
|
return {
|
|
50
|
-
"prefect.resource.id": f"infrahub.branch.{self.
|
|
51
|
+
"prefect.resource.id": f"infrahub.branch.{self.branch_name}",
|
|
51
52
|
"infrahub.branch.id": self.branch_id,
|
|
52
|
-
"infrahub.branch.name": self.
|
|
53
|
+
"infrahub.branch.name": self.branch_name,
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
def get_messages(self) -> list[InfrahubMessage]:
|
|
@@ -64,18 +65,39 @@ class BranchCreateEvent(InfrahubBranchEvent):
|
|
|
64
65
|
]
|
|
65
66
|
return events
|
|
66
67
|
|
|
68
|
+
@computed_field
|
|
69
|
+
def event_name(self) -> str:
|
|
70
|
+
return f"{EVENT_NAMESPACE}.branch.created"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class BranchMergedEvent(InfrahubEvent):
|
|
74
|
+
"""Event generated when a branch has been merged"""
|
|
75
|
+
|
|
76
|
+
def get_resource(self) -> dict[str, str]:
|
|
77
|
+
return {
|
|
78
|
+
"prefect.resource.id": f"infrahub.branch.{self.meta.get_branch_id()}",
|
|
79
|
+
"infrahub.node.kind": "Branch",
|
|
80
|
+
"infrahub.node.id": self.meta.get_branch_id(),
|
|
81
|
+
"infrahub.node.label": self.meta.context.branch.name,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
def get_messages(self) -> list[InfrahubMessage]:
|
|
85
|
+
return []
|
|
86
|
+
|
|
87
|
+
@computed_field
|
|
88
|
+
def event_name(self) -> str:
|
|
89
|
+
return f"{EVENT_NAMESPACE}.branch.merged"
|
|
90
|
+
|
|
67
91
|
|
|
68
|
-
class
|
|
92
|
+
class BranchRebasedEvent(InfrahubEvent):
|
|
69
93
|
"""Event generated when a branch has been rebased"""
|
|
70
94
|
|
|
71
95
|
branch_id: str = Field(..., description="The ID of the mutated node")
|
|
72
|
-
|
|
73
|
-
def get_name(self) -> str:
|
|
74
|
-
return f"{self.get_event_namespace()}.branch.rebased"
|
|
96
|
+
branch_name: str = Field(..., description="The name of the branch")
|
|
75
97
|
|
|
76
98
|
def get_resource(self) -> dict[str, str]:
|
|
77
99
|
return {
|
|
78
|
-
"prefect.resource.id": f"infrahub.branch.{self.
|
|
100
|
+
"prefect.resource.id": f"infrahub.branch.{self.branch_name}",
|
|
79
101
|
"infrahub.branch.id": self.branch_id,
|
|
80
102
|
}
|
|
81
103
|
|
|
@@ -85,6 +107,10 @@ class BranchRebaseEvent(InfrahubBranchEvent):
|
|
|
85
107
|
# branch=self.branch,
|
|
86
108
|
# meta=self.get_message_meta(),
|
|
87
109
|
# ),
|
|
88
|
-
RefreshRegistryRebasedBranch(branch=self.
|
|
110
|
+
RefreshRegistryRebasedBranch(branch=self.branch_name),
|
|
89
111
|
]
|
|
90
112
|
return events
|
|
113
|
+
|
|
114
|
+
@computed_field
|
|
115
|
+
def event_name(self) -> str:
|
|
116
|
+
return f"{EVENT_NAMESPACE}.branch.rebased"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from pydantic import Field, computed_field
|
|
4
|
+
|
|
5
|
+
from infrahub.core.constants import MutationAction
|
|
6
|
+
from infrahub.message_bus import InfrahubMessage
|
|
7
|
+
|
|
8
|
+
from .constants import EVENT_NAMESPACE
|
|
9
|
+
from .models import EventNode, InfrahubEvent
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GroupMutatedEvent(InfrahubEvent):
|
|
13
|
+
"""Event generated when a node has been mutated"""
|
|
14
|
+
|
|
15
|
+
kind: str = Field(..., description="The type of updated group")
|
|
16
|
+
node_id: str = Field(..., description="The ID of the updated group")
|
|
17
|
+
action: MutationAction = Field(..., description="The action taken on the node")
|
|
18
|
+
members: list[EventNode] = Field(default_factory=list, description="Updated members during this event.")
|
|
19
|
+
|
|
20
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
21
|
+
related = super().get_related()
|
|
22
|
+
related.append(
|
|
23
|
+
{
|
|
24
|
+
"prefect.resource.id": self.node_id,
|
|
25
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
26
|
+
"infrahub.node.kind": self.kind,
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
for member in self.members:
|
|
30
|
+
related.append(
|
|
31
|
+
{
|
|
32
|
+
"prefect.resource.id": member.id,
|
|
33
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
34
|
+
"infrahub.node.kind": member.kind,
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
return related
|
|
39
|
+
|
|
40
|
+
@computed_field
|
|
41
|
+
def event_name(self) -> str:
|
|
42
|
+
return f"{EVENT_NAMESPACE}.group.{self.action.value}"
|
|
43
|
+
|
|
44
|
+
def get_resource(self) -> dict[str, str]:
|
|
45
|
+
return {
|
|
46
|
+
"prefect.resource.id": f"infrahub.node.{self.node_id}",
|
|
47
|
+
"infrahub.node.kind": self.kind,
|
|
48
|
+
"infrahub.node.id": self.node_id,
|
|
49
|
+
"infrahub.node.action": self.action.value,
|
|
50
|
+
"infrahub.node.root_id": self.node_id,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
def get_payload(self) -> dict[str, Any]:
|
|
54
|
+
return {"members": [member.model_dump() for member in self.members]}
|
|
55
|
+
|
|
56
|
+
def get_messages(self) -> list[InfrahubMessage]:
|
|
57
|
+
return []
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class GroupMemberAddedEvent(GroupMutatedEvent):
|
|
61
|
+
action: MutationAction = MutationAction.CREATED
|
|
62
|
+
|
|
63
|
+
@computed_field
|
|
64
|
+
def event_name(self) -> str:
|
|
65
|
+
return f"{EVENT_NAMESPACE}.group.member_added"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class GroupMemberRemovedEvent(GroupMutatedEvent):
|
|
69
|
+
action: MutationAction = MutationAction.DELETED
|
|
70
|
+
|
|
71
|
+
@computed_field
|
|
72
|
+
def event_name(self) -> str:
|
|
73
|
+
return f"{EVENT_NAMESPACE}.group.member_removed"
|