infrahub-server 1.2.0b1__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/api/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +1 -3
- infrahub/artifacts/tasks.py +1 -3
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +239 -11
- infrahub/computed_attribute/tasks.py +77 -442
- infrahub/computed_attribute/triggers.py +11 -45
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +57 -57
- infrahub/core/branch/tasks.py +12 -9
- infrahub/core/changelog/diff.py +16 -8
- infrahub/core/changelog/models.py +189 -26
- infrahub/core/constants/__init__.py +5 -1
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +3 -3
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +34 -34
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +9 -4
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/{m020_add_generate_template_attr.py → m022_add_generate_template_attr.py} +3 -3
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +18 -21
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +29 -28
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +5 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +24 -24
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +40 -46
- infrahub/core/schema/attribute_schema.py +9 -9
- infrahub/core/schema/basenode_schema.py +93 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +13 -19
- infrahub/core/schema/definitions/core/account.py +151 -148
- infrahub/core/schema/definitions/core/artifact.py +122 -113
- infrahub/core/schema/definitions/core/builtin.py +19 -16
- infrahub/core/schema/definitions/core/check.py +61 -53
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +89 -85
- infrahub/core/schema/definitions/core/graphql_query.py +72 -70
- infrahub/core/schema/definitions/core/group.py +96 -93
- infrahub/core/schema/definitions/core/ipam.py +176 -235
- infrahub/core/schema/definitions/core/lineage.py +18 -16
- infrahub/core/schema/definitions/core/menu.py +42 -40
- infrahub/core/schema/definitions/core/permission.py +144 -142
- infrahub/core/schema/definitions/core/profile.py +16 -27
- infrahub/core/schema/definitions/core/propose_change.py +88 -79
- infrahub/core/schema/definitions/core/propose_change_comment.py +170 -165
- infrahub/core/schema/definitions/core/propose_change_validator.py +290 -288
- infrahub/core/schema/definitions/core/repository.py +231 -225
- infrahub/core/schema/definitions/core/resource_pool.py +156 -166
- infrahub/core/schema/definitions/core/template.py +27 -12
- infrahub/core/schema/definitions/core/transform.py +85 -76
- infrahub/core/schema/definitions/core/webhook.py +127 -101
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +7 -7
- infrahub/core/schema/schema_branch.py +276 -138
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +26 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +13 -25
- infrahub/events/branch_action.py +26 -18
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +10 -24
- infrahub/events/models.py +10 -16
- infrahub/events/node_action.py +87 -32
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +23 -24
- infrahub/generators/models.py +1 -3
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +26 -25
- infrahub/git/models.py +22 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +67 -49
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +6 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +13 -10
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/computed_attribute.py +4 -5
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +50 -70
- infrahub/graphql/mutations/main.py +164 -141
- infrahub/graphql/mutations/menu.py +5 -5
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +67 -35
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +4 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/queries/diff/tree.py +4 -4
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/event.py +20 -11
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/menu/generator.py +7 -7
- infrahub/menu/menu.py +0 -10
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/messages/__init__.py +1 -11
- infrahub/message_bus/messages/check_generator_run.py +2 -0
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/operations/__init__.py +0 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/generator_definition.py +19 -19
- infrahub/message_bus/operations/requests/proposed_change.py +3 -1
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/tasks.py +37 -28
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +1 -2
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/task_manager/event.py +23 -9
- infrahub/tasks/artifact.py +2 -4
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +2 -5
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +14 -1
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -90
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +22 -5
- infrahub/webhook/tasks.py +44 -19
- infrahub/webhook/triggers.py +22 -5
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +28 -20
- infrahub/workflows/initialization.py +1 -3
- infrahub/workflows/models.py +1 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +27 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +69 -20
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +10 -0
- infrahub_sdk/task/manager.py +12 -6
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +12 -4
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +3 -2
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +289 -260
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
infrahub/git/tasks.py
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
from infrahub_sdk import InfrahubClient
|
|
2
|
-
from infrahub_sdk.protocols import
|
|
2
|
+
from infrahub_sdk.protocols import (
|
|
3
|
+
CoreArtifact,
|
|
4
|
+
CoreArtifactDefinition,
|
|
5
|
+
CoreCheckDefinition,
|
|
6
|
+
CoreRepository,
|
|
7
|
+
CoreRepositoryValidator,
|
|
8
|
+
CoreUserValidator,
|
|
9
|
+
)
|
|
3
10
|
from infrahub_sdk.uuidt import UUIDT
|
|
4
11
|
from prefect import flow, task
|
|
5
12
|
from prefect.cache_policies import NONE
|
|
@@ -7,11 +14,12 @@ from prefect.logging import get_run_logger
|
|
|
7
14
|
|
|
8
15
|
from infrahub import lock
|
|
9
16
|
from infrahub.context import InfrahubContext
|
|
10
|
-
from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus, ValidatorConclusion
|
|
17
|
+
from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus, ValidatorConclusion
|
|
11
18
|
from infrahub.core.registry import registry
|
|
12
19
|
from infrahub.exceptions import CheckError, RepositoryError
|
|
13
20
|
from infrahub.message_bus import Meta, messages
|
|
14
21
|
from infrahub.services import InfrahubServices
|
|
22
|
+
from infrahub.validators.tasks import start_validator
|
|
15
23
|
from infrahub.worker import WORKER_IDENTITY
|
|
16
24
|
|
|
17
25
|
from ..core.manager import NodeManager
|
|
@@ -509,7 +517,9 @@ async def git_repository_diff_names_only(
|
|
|
509
517
|
name="git-repository-user-checks-definition-trigger",
|
|
510
518
|
flow_run_name="Trigger user defined checks for repository {model.repository_name}",
|
|
511
519
|
)
|
|
512
|
-
async def trigger_repository_user_checks_definitions(
|
|
520
|
+
async def trigger_repository_user_checks_definitions(
|
|
521
|
+
model: UserCheckDefinitionData, context: InfrahubContext, service: InfrahubServices
|
|
522
|
+
) -> None:
|
|
513
523
|
await add_tags(branches=[model.branch_name], nodes=[model.proposed_change])
|
|
514
524
|
log = get_run_logger()
|
|
515
525
|
|
|
@@ -520,8 +530,8 @@ async def trigger_repository_user_checks_definitions(model: UserCheckDefinitionD
|
|
|
520
530
|
validator_execution_id = str(UUIDT())
|
|
521
531
|
check_execution_ids: list[str] = []
|
|
522
532
|
await proposed_change.validations.fetch()
|
|
523
|
-
validator = None
|
|
524
533
|
|
|
534
|
+
previous_validator: CoreUserValidator | None = None
|
|
525
535
|
for relationship in proposed_change.validations.peers:
|
|
526
536
|
existing_validator = relationship.peer
|
|
527
537
|
|
|
@@ -530,26 +540,21 @@ async def trigger_repository_user_checks_definitions(model: UserCheckDefinitionD
|
|
|
530
540
|
and existing_validator.repository.id == model.repository_id
|
|
531
541
|
and existing_validator.check_definition.id == model.check_definition_id
|
|
532
542
|
):
|
|
533
|
-
|
|
534
|
-
service.log.info("Found the same validator", validator=
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
validator
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
"repository": model.repository_id,
|
|
549
|
-
"check_definition": model.check_definition_id,
|
|
550
|
-
},
|
|
551
|
-
)
|
|
552
|
-
await validator.save()
|
|
543
|
+
previous_validator = existing_validator
|
|
544
|
+
service.log.info("Found the same validator", validator=previous_validator)
|
|
545
|
+
|
|
546
|
+
validator = await start_validator(
|
|
547
|
+
service=service,
|
|
548
|
+
validator=previous_validator,
|
|
549
|
+
validator_type=CoreUserValidator,
|
|
550
|
+
proposed_change=model.proposed_change,
|
|
551
|
+
data={
|
|
552
|
+
"label": f"Check: {definition.name.value}",
|
|
553
|
+
"repository": model.repository_id,
|
|
554
|
+
"check_definition": model.check_definition_id,
|
|
555
|
+
},
|
|
556
|
+
context=context,
|
|
557
|
+
)
|
|
553
558
|
|
|
554
559
|
if definition.targets.id:
|
|
555
560
|
# Check against a group of targets
|
|
@@ -612,14 +617,22 @@ async def trigger_repository_user_checks_definitions(model: UserCheckDefinitionD
|
|
|
612
617
|
for model in check_models
|
|
613
618
|
]
|
|
614
619
|
|
|
615
|
-
await run_checks_and_update_validator(
|
|
620
|
+
await run_checks_and_update_validator(
|
|
621
|
+
checks=checks_coroutines,
|
|
622
|
+
validator=validator,
|
|
623
|
+
context=context,
|
|
624
|
+
service=service,
|
|
625
|
+
proposed_change_id=model.proposed_change,
|
|
626
|
+
)
|
|
616
627
|
|
|
617
628
|
|
|
618
629
|
@flow(
|
|
619
630
|
name="git-repository-trigger-user-checks",
|
|
620
631
|
flow_run_name="Evaluating user-defined checks on repository {model.repository_name}",
|
|
621
632
|
)
|
|
622
|
-
async def trigger_user_checks(
|
|
633
|
+
async def trigger_user_checks(
|
|
634
|
+
model: TriggerRepositoryUserChecks, service: InfrahubServices, context: InfrahubContext
|
|
635
|
+
) -> None:
|
|
623
636
|
"""Request to start validation checks on a specific repository for User-defined checks."""
|
|
624
637
|
|
|
625
638
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
|
|
@@ -645,7 +658,9 @@ async def trigger_user_checks(model: TriggerRepositoryUserChecks, service: Infra
|
|
|
645
658
|
branch_diff=model.branch_diff,
|
|
646
659
|
)
|
|
647
660
|
await service.workflow.submit_workflow(
|
|
648
|
-
workflow=GIT_REPOSITORY_USER_CHECKS_DEFINITIONS_TRIGGER,
|
|
661
|
+
workflow=GIT_REPOSITORY_USER_CHECKS_DEFINITIONS_TRIGGER,
|
|
662
|
+
context=context,
|
|
663
|
+
parameters={"model": user_check_definition_model},
|
|
649
664
|
)
|
|
650
665
|
|
|
651
666
|
|
|
@@ -653,7 +668,9 @@ async def trigger_user_checks(model: TriggerRepositoryUserChecks, service: Infra
|
|
|
653
668
|
name="git-repository-trigger-internal-checks",
|
|
654
669
|
flow_run_name="Running repository checks for repository {model.repository}",
|
|
655
670
|
)
|
|
656
|
-
async def trigger_internal_checks(
|
|
671
|
+
async def trigger_internal_checks(
|
|
672
|
+
model: TriggerRepositoryInternalChecks, service: InfrahubServices, context: InfrahubContext
|
|
673
|
+
) -> None:
|
|
657
674
|
"""Request to start validation checks on a specific repository."""
|
|
658
675
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
|
|
659
676
|
log = get_run_logger()
|
|
@@ -669,7 +686,7 @@ async def trigger_internal_checks(model: TriggerRepositoryInternalChecks, servic
|
|
|
669
686
|
await repository.checks.fetch()
|
|
670
687
|
|
|
671
688
|
validator_name = f"Repository Validator: {repository.name.value}"
|
|
672
|
-
|
|
689
|
+
previous_validator: CoreRepositoryValidator | None = None
|
|
673
690
|
for relationship in proposed_change.validations.peers:
|
|
674
691
|
existing_validator = relationship.peer
|
|
675
692
|
|
|
@@ -677,24 +694,19 @@ async def trigger_internal_checks(model: TriggerRepositoryInternalChecks, servic
|
|
|
677
694
|
existing_validator.typename == InfrahubKind.REPOSITORYVALIDATOR
|
|
678
695
|
and existing_validator.repository.id == model.repository
|
|
679
696
|
):
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
validator
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
"proposed_change": model.proposed_change,
|
|
694
|
-
"repository": model.repository,
|
|
695
|
-
},
|
|
696
|
-
)
|
|
697
|
-
await validator.save()
|
|
697
|
+
previous_validator = existing_validator
|
|
698
|
+
|
|
699
|
+
validator = await start_validator(
|
|
700
|
+
service=service,
|
|
701
|
+
validator=previous_validator,
|
|
702
|
+
validator_type=CoreRepositoryValidator,
|
|
703
|
+
proposed_change=model.proposed_change,
|
|
704
|
+
data={
|
|
705
|
+
"label": validator_name,
|
|
706
|
+
"repository": model.repository,
|
|
707
|
+
},
|
|
708
|
+
context=context,
|
|
709
|
+
)
|
|
698
710
|
|
|
699
711
|
check_execution_id = str(UUIDT())
|
|
700
712
|
check_execution_ids.append(check_execution_id)
|
|
@@ -718,7 +730,13 @@ async def trigger_internal_checks(model: TriggerRepositoryInternalChecks, servic
|
|
|
718
730
|
expected_return=ValidatorConclusion,
|
|
719
731
|
)
|
|
720
732
|
|
|
721
|
-
await run_checks_and_update_validator(
|
|
733
|
+
await run_checks_and_update_validator(
|
|
734
|
+
checks=[check_coroutine],
|
|
735
|
+
validator=validator,
|
|
736
|
+
context=context,
|
|
737
|
+
service=service,
|
|
738
|
+
proposed_change_id=model.proposed_change,
|
|
739
|
+
)
|
|
722
740
|
|
|
723
741
|
|
|
724
742
|
@flow(
|
|
@@ -822,7 +840,7 @@ async def run_user_check(model: UserCheckData, service: InfrahubServices) -> Val
|
|
|
822
840
|
client=service.client,
|
|
823
841
|
commit=model.commit,
|
|
824
842
|
params=model.variables,
|
|
825
|
-
)
|
|
843
|
+
) # type: ignore[misc]
|
|
826
844
|
if check_run.passed:
|
|
827
845
|
conclusion = ValidatorConclusion.SUCCESS
|
|
828
846
|
severity = "info"
|
infrahub/git/utils.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from infrahub.core import registry
|
|
4
|
+
from infrahub.core.constants import InfrahubKind
|
|
5
|
+
from infrahub.core.manager import NodeManager
|
|
6
|
+
from infrahub.database import InfrahubDatabase
|
|
7
|
+
|
|
8
|
+
from .models import RepositoryBranchInfo, RepositoryData
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from infrahub.core.protocols import CoreGenericRepository
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def get_repositories_commit_per_branch(
|
|
15
|
+
db: InfrahubDatabase,
|
|
16
|
+
) -> dict[str, RepositoryData]:
|
|
17
|
+
"""Get a list of all repositories and their commit on each branches.
|
|
18
|
+
|
|
19
|
+
This method is similar to 'get_list_repositories' method in the Python SDK.
|
|
20
|
+
|
|
21
|
+
NOTE: At some point, we should refactor this function to use a single Database query instead of one per branch
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
repositories: dict[str, RepositoryData] = {}
|
|
25
|
+
|
|
26
|
+
for branch in list(registry.branch.values()):
|
|
27
|
+
repos: list[CoreGenericRepository] = await NodeManager.query(
|
|
28
|
+
db=db,
|
|
29
|
+
branch=branch,
|
|
30
|
+
fields={"id": None, "name": None, "commit": None, "internal_status": None},
|
|
31
|
+
schema=InfrahubKind.GENERICREPOSITORY,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
for repository in repos:
|
|
35
|
+
repo_name = repository.name.value
|
|
36
|
+
if repo_name not in repositories:
|
|
37
|
+
repositories[repo_name] = RepositoryData(
|
|
38
|
+
repository_id=repository.get_id(),
|
|
39
|
+
repository_name=repo_name,
|
|
40
|
+
branches={},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
repositories[repo_name].branches[branch.name] = repository.commit.value # type: ignore[attr-defined]
|
|
44
|
+
repositories[repo_name].branch_info[branch.name] = RepositoryBranchInfo(
|
|
45
|
+
internal_status=repository.internal_status.value
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return repositories
|
infrahub/git/worktree.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from pydantic import BaseModel
|
|
7
6
|
|
|
@@ -14,7 +13,7 @@ class Worktree(BaseModel):
|
|
|
14
13
|
identifier: str
|
|
15
14
|
directory: Path
|
|
16
15
|
commit: str
|
|
17
|
-
branch:
|
|
16
|
+
branch: str | None = None
|
|
18
17
|
|
|
19
18
|
@classmethod
|
|
20
19
|
def init(cls, text: str) -> Worktree:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import sys
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
import typer
|
|
6
5
|
from infrahub_sdk import Config, InfrahubClientSync
|
|
@@ -16,7 +15,7 @@ REGEX_PASSWORD = r"^Password.*\'(.*\:\/\/)(.*)@(.*)\'"
|
|
|
16
15
|
|
|
17
16
|
@app.command()
|
|
18
17
|
def askpass(
|
|
19
|
-
text:
|
|
18
|
+
text: list[str] | None = typer.Argument(None),
|
|
20
19
|
config_file: str = typer.Option("infrahub.toml", envvar="INFRAHUB_CONFIG"),
|
|
21
20
|
) -> None:
|
|
22
21
|
config.SETTINGS.initialize_and_exit(config_file=config_file)
|
infrahub/graphql/analyzer.py
CHANGED
|
@@ -258,6 +258,18 @@ class GraphQLQueryReport:
|
|
|
258
258
|
|
|
259
259
|
return access
|
|
260
260
|
|
|
261
|
+
def fields_by_kind(self, kind: str) -> list[str]:
|
|
262
|
+
fields: list[str] = []
|
|
263
|
+
if access := self.requested_read.get(kind):
|
|
264
|
+
fields.extend(list(access.attributes))
|
|
265
|
+
fields.extend(list(access.relationships))
|
|
266
|
+
|
|
267
|
+
return fields
|
|
268
|
+
|
|
269
|
+
@cached_property
|
|
270
|
+
def top_level_kinds(self) -> list[str]:
|
|
271
|
+
return [query.infrahub_model.kind for query in self.queries if query.infrahub_model]
|
|
272
|
+
|
|
261
273
|
@cached_property
|
|
262
274
|
def kind_action_map(self) -> dict[str, set[MutateAction]]:
|
|
263
275
|
access: dict[str, set[MutateAction]] = {}
|
infrahub/graphql/app.py
CHANGED
|
@@ -13,9 +13,7 @@ from typing import (
|
|
|
13
13
|
AsyncGenerator,
|
|
14
14
|
Awaitable,
|
|
15
15
|
Callable,
|
|
16
|
-
Optional,
|
|
17
16
|
Sequence,
|
|
18
|
-
Union,
|
|
19
17
|
cast,
|
|
20
18
|
)
|
|
21
19
|
|
|
@@ -87,7 +85,7 @@ GQL_ERROR = "error"
|
|
|
87
85
|
GQL_START = "start"
|
|
88
86
|
GQL_STOP = "stop"
|
|
89
87
|
|
|
90
|
-
ContextValue =
|
|
88
|
+
ContextValue = Any | Callable[[HTTPConnection], Any]
|
|
91
89
|
RootValue = Any
|
|
92
90
|
|
|
93
91
|
|
|
@@ -95,13 +93,13 @@ class InfrahubGraphQLApp:
|
|
|
95
93
|
def __init__(
|
|
96
94
|
self,
|
|
97
95
|
permission_checker: GraphQLQueryPermissionChecker,
|
|
98
|
-
schema:
|
|
96
|
+
schema: graphene.Schema | None = None,
|
|
99
97
|
*,
|
|
100
|
-
on_get:
|
|
98
|
+
on_get: Callable[[Request], Response | Awaitable[Response]] | None = None,
|
|
101
99
|
root_value: RootValue = None,
|
|
102
|
-
middleware:
|
|
100
|
+
middleware: Middleware | None = None,
|
|
103
101
|
error_formatter: Callable[[GraphQLError], GraphQLFormattedError] = format_error,
|
|
104
|
-
execution_context_class:
|
|
102
|
+
execution_context_class: type[ExecutionContext] | None = None,
|
|
105
103
|
) -> None:
|
|
106
104
|
self._schema = schema
|
|
107
105
|
self.on_get = on_get
|
|
@@ -116,7 +114,7 @@ class InfrahubGraphQLApp:
|
|
|
116
114
|
db: InfrahubDatabase
|
|
117
115
|
if scope["type"] == "http":
|
|
118
116
|
request = Request(scope=scope, receive=receive)
|
|
119
|
-
response:
|
|
117
|
+
response: Response | None = None
|
|
120
118
|
jwt_auth = await jwt_scheme(request)
|
|
121
119
|
api_key = await api_key_scheme(request)
|
|
122
120
|
cookie_auth = await cookie_auth_scheme(request)
|
|
@@ -166,7 +164,7 @@ class InfrahubGraphQLApp:
|
|
|
166
164
|
else:
|
|
167
165
|
raise ValueError(f"Unsupported scope type: ${scope['type']}")
|
|
168
166
|
|
|
169
|
-
async def _get_on_get(self, request: Request) ->
|
|
167
|
+
async def _get_on_get(self, request: Request) -> Response | None:
|
|
170
168
|
handler = self.on_get
|
|
171
169
|
|
|
172
170
|
if handler is None:
|
|
@@ -388,8 +386,8 @@ class InfrahubGraphQLApp:
|
|
|
388
386
|
graphql_params = await prepare_graphql_params(db=db, branch=branch)
|
|
389
387
|
|
|
390
388
|
errors: list[GraphQLError] = []
|
|
391
|
-
operation:
|
|
392
|
-
document:
|
|
389
|
+
operation: OperationDefinitionNode | None = None
|
|
390
|
+
document: DocumentNode | None = None
|
|
393
391
|
|
|
394
392
|
try:
|
|
395
393
|
document = parse(query)
|
|
@@ -474,11 +472,11 @@ class InfrahubGraphQLApp:
|
|
|
474
472
|
await websocket.send_json({"type": GQL_COMPLETE, "id": operation_id})
|
|
475
473
|
|
|
476
474
|
|
|
477
|
-
async def _get_operation_from_request(request: Request) ->
|
|
475
|
+
async def _get_operation_from_request(request: Request) -> dict[str, Any] | list[Any]:
|
|
478
476
|
content_type = request.headers.get("Content-Type", "").split(";")[0]
|
|
479
477
|
if content_type == "application/json":
|
|
480
478
|
try:
|
|
481
|
-
return cast(
|
|
479
|
+
return cast(dict[str, Any] | list[Any], await request.json())
|
|
482
480
|
except (TypeError, ValueError) as err:
|
|
483
481
|
raise ValueError("Request body is not a valid JSON") from err
|
|
484
482
|
elif content_type == "multipart/form-data":
|
|
@@ -487,7 +485,7 @@ async def _get_operation_from_request(request: Request) -> Union[dict[str, Any],
|
|
|
487
485
|
raise ValueError("Content-type must be application/json or multipart/form-data")
|
|
488
486
|
|
|
489
487
|
|
|
490
|
-
async def _get_operation_from_multipart(request: Request) ->
|
|
488
|
+
async def _get_operation_from_multipart(request: Request) -> dict[str, Any] | list[Any]:
|
|
491
489
|
try:
|
|
492
490
|
request_body = await request.form()
|
|
493
491
|
except Exception as err:
|
|
@@ -526,7 +524,7 @@ async def _get_operation_from_multipart(request: Request) -> Union[dict[str, Any
|
|
|
526
524
|
|
|
527
525
|
def _inject_file_to_operations(ops_tree: Any, _file: UploadFile, path: Sequence[str]) -> None:
|
|
528
526
|
k = path[0]
|
|
529
|
-
key:
|
|
527
|
+
key: str | int
|
|
530
528
|
try:
|
|
531
529
|
key = int(k)
|
|
532
530
|
except ValueError:
|
infrahub/graphql/context.py
CHANGED
|
@@ -17,6 +17,12 @@ async def apply_external_context(graphql_context: GraphqlContext, context_input:
|
|
|
17
17
|
if not context_input or not context_input.account:
|
|
18
18
|
return
|
|
19
19
|
|
|
20
|
+
if graphql_context.active_account_session.account_id == context_input.account.id:
|
|
21
|
+
# If the account_id from the request context is the same as the current account
|
|
22
|
+
# there's no point moving forward with other checks to override the current
|
|
23
|
+
# context we can just continue with what is already there.
|
|
24
|
+
return
|
|
25
|
+
|
|
20
26
|
permission = define_global_permission_from_branch(
|
|
21
27
|
permission=GlobalPermissions.OVERRIDE_CONTEXT, branch_name=graphql_context.branch.name
|
|
22
28
|
)
|
|
@@ -9,6 +9,7 @@ from infrahub.context import InfrahubContext
|
|
|
9
9
|
from infrahub.core import registry
|
|
10
10
|
from infrahub.core.timestamp import Timestamp
|
|
11
11
|
from infrahub.exceptions import InitializationError
|
|
12
|
+
from infrahub.graphql.resolvers.many_relationship import ManyRelationshipResolver
|
|
12
13
|
from infrahub.graphql.resolvers.single_relationship import SingleRelationshipResolver
|
|
13
14
|
from infrahub.permissions import PermissionManager
|
|
14
15
|
|
|
@@ -36,6 +37,7 @@ class GraphqlContext:
|
|
|
36
37
|
branch: Branch
|
|
37
38
|
types: dict
|
|
38
39
|
single_relationship_resolver: SingleRelationshipResolver
|
|
40
|
+
many_relationship_resolver: ManyRelationshipResolver
|
|
39
41
|
service: InfrahubServices | None = None
|
|
40
42
|
at: Timestamp | None = None
|
|
41
43
|
related_node_ids: set | None = None
|
|
@@ -111,6 +113,7 @@ async def prepare_graphql_params(
|
|
|
111
113
|
db=db,
|
|
112
114
|
branch=branch,
|
|
113
115
|
single_relationship_resolver=SingleRelationshipResolver(),
|
|
116
|
+
many_relationship_resolver=ManyRelationshipResolver(),
|
|
114
117
|
at=Timestamp(at),
|
|
115
118
|
types=gqlm.get_graphql_types(),
|
|
116
119
|
related_node_ids=set(),
|
infrahub/graphql/loaders/node.py
CHANGED
|
@@ -10,6 +10,8 @@ from infrahub.core.node import Node
|
|
|
10
10
|
from infrahub.core.timestamp import Timestamp
|
|
11
11
|
from infrahub.database import InfrahubDatabase
|
|
12
12
|
|
|
13
|
+
from .shared import to_frozen_set
|
|
14
|
+
|
|
13
15
|
|
|
14
16
|
@dataclass
|
|
15
17
|
class GetManyParams:
|
|
@@ -68,15 +70,3 @@ class NodeDataLoader(DataLoader[str, Node | None]):
|
|
|
68
70
|
for node_id in keys:
|
|
69
71
|
results.append(nodes_by_id.get(node_id, None))
|
|
70
72
|
return results
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def to_frozen_set(to_freeze: dict[str, Any]) -> frozenset:
|
|
74
|
-
freezing_dict = {}
|
|
75
|
-
for k, v in to_freeze.items():
|
|
76
|
-
if isinstance(v, dict):
|
|
77
|
-
freezing_dict[k] = to_frozen_set(v)
|
|
78
|
-
elif isinstance(v, list | set):
|
|
79
|
-
freezing_dict[k] = frozenset(v)
|
|
80
|
-
else:
|
|
81
|
-
freezing_dict[k] = v
|
|
82
|
-
return frozenset(freezing_dict)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from aiodataloader import DataLoader
|
|
5
|
+
|
|
6
|
+
from infrahub.core.branch.models import Branch
|
|
7
|
+
from infrahub.core.manager import NodeManager
|
|
8
|
+
from infrahub.core.relationship.model import Relationship
|
|
9
|
+
from infrahub.core.schema.relationship_schema import RelationshipSchema
|
|
10
|
+
from infrahub.core.timestamp import Timestamp
|
|
11
|
+
from infrahub.database import InfrahubDatabase
|
|
12
|
+
|
|
13
|
+
from .shared import to_frozen_set
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class QueryPeerParams:
|
|
18
|
+
branch: Branch | str
|
|
19
|
+
source_kind: str
|
|
20
|
+
schema: RelationshipSchema
|
|
21
|
+
filters: dict[str, Any]
|
|
22
|
+
fields: dict | None = None
|
|
23
|
+
at: Timestamp | str | None = None
|
|
24
|
+
branch_agnostic: bool = False
|
|
25
|
+
|
|
26
|
+
def __hash__(self) -> int:
|
|
27
|
+
frozen_fields: frozenset | None = None
|
|
28
|
+
if self.fields:
|
|
29
|
+
frozen_fields = to_frozen_set(self.fields)
|
|
30
|
+
frozen_filters = to_frozen_set(self.filters)
|
|
31
|
+
timestamp = Timestamp(self.at)
|
|
32
|
+
branch = self.branch.name if isinstance(self.branch, Branch) else self.branch
|
|
33
|
+
hash_str = "|".join(
|
|
34
|
+
[
|
|
35
|
+
str(hash(frozen_fields)),
|
|
36
|
+
str(hash(frozen_filters)),
|
|
37
|
+
timestamp.to_string(),
|
|
38
|
+
branch,
|
|
39
|
+
self.schema.name,
|
|
40
|
+
str(self.source_kind),
|
|
41
|
+
str(self.branch_agnostic),
|
|
42
|
+
]
|
|
43
|
+
)
|
|
44
|
+
return hash(hash_str)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class PeerRelationshipsDataLoader(DataLoader[str, list[Relationship]]):
|
|
48
|
+
def __init__(self, db: InfrahubDatabase, query_params: QueryPeerParams, *args: Any, **kwargs: Any) -> None:
|
|
49
|
+
super().__init__(*args, **kwargs)
|
|
50
|
+
self.query_params = query_params
|
|
51
|
+
self.db = db
|
|
52
|
+
|
|
53
|
+
async def batch_load_fn(self, keys: list[Any]) -> list[list[Relationship]]: # pylint: disable=method-hidden
|
|
54
|
+
async with self.db.start_session() as db:
|
|
55
|
+
peer_rels = await NodeManager.query_peers(
|
|
56
|
+
db=db,
|
|
57
|
+
ids=keys,
|
|
58
|
+
source_kind=self.query_params.source_kind,
|
|
59
|
+
schema=self.query_params.schema,
|
|
60
|
+
filters=self.query_params.filters,
|
|
61
|
+
fields=self.query_params.fields,
|
|
62
|
+
at=self.query_params.at,
|
|
63
|
+
branch=self.query_params.branch,
|
|
64
|
+
branch_agnostic=self.query_params.branch_agnostic,
|
|
65
|
+
fetch_peers=True,
|
|
66
|
+
)
|
|
67
|
+
peer_rels_by_node_id: dict[str, list[Relationship]] = {}
|
|
68
|
+
for rel in peer_rels:
|
|
69
|
+
node_id = rel.node_id
|
|
70
|
+
if node_id not in peer_rels_by_node_id:
|
|
71
|
+
peer_rels_by_node_id[node_id] = []
|
|
72
|
+
peer_rels_by_node_id[node_id].append(rel)
|
|
73
|
+
|
|
74
|
+
results = []
|
|
75
|
+
for node_id in keys:
|
|
76
|
+
results.append(peer_rels_by_node_id.get(node_id, []))
|
|
77
|
+
return results
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def to_frozen_set(to_freeze: dict[str, Any]) -> frozenset:
|
|
5
|
+
freezing_dict = {}
|
|
6
|
+
for k, v in to_freeze.items():
|
|
7
|
+
if isinstance(v, dict):
|
|
8
|
+
freezing_dict[k] = to_frozen_set(v)
|
|
9
|
+
elif isinstance(v, list | set):
|
|
10
|
+
freezing_dict[k] = frozenset(v)
|
|
11
|
+
else:
|
|
12
|
+
freezing_dict[k] = v
|
|
13
|
+
return frozenset(freezing_dict)
|
infrahub/graphql/manager.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Iterable
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Iterable
|
|
5
5
|
|
|
6
6
|
import graphene
|
|
7
7
|
|
|
@@ -38,6 +38,7 @@ from .mutations.repository import InfrahubRepositoryMutation
|
|
|
38
38
|
from .mutations.resource_manager import (
|
|
39
39
|
InfrahubNumberPoolMutation,
|
|
40
40
|
)
|
|
41
|
+
from .mutations.webhook import InfrahubWebhookMutation
|
|
41
42
|
from .resolvers.resolver import (
|
|
42
43
|
account_resolver,
|
|
43
44
|
ancestors_resolver,
|
|
@@ -75,9 +76,7 @@ class DeleteInput(graphene.InputObjectType):
|
|
|
75
76
|
hfid = graphene.List(of_type=graphene.String, required=False)
|
|
76
77
|
|
|
77
78
|
|
|
78
|
-
GraphQLTypes =
|
|
79
|
-
type[InfrahubMutation], type[BaseAttributeType], type[graphene.Interface], type[graphene.ObjectType]
|
|
80
|
-
]
|
|
79
|
+
GraphQLTypes = type[InfrahubMutation] | type[BaseAttributeType] | type[graphene.Interface] | type[graphene.ObjectType]
|
|
81
80
|
|
|
82
81
|
|
|
83
82
|
class OrderInput(graphene.InputObjectType):
|
|
@@ -513,6 +512,8 @@ class GraphQLSchemaManager:
|
|
|
513
512
|
InfrahubKind.NAMESPACE: InfrahubIPNamespaceMutation,
|
|
514
513
|
InfrahubKind.NUMBERPOOL: InfrahubNumberPoolMutation,
|
|
515
514
|
InfrahubKind.MENUITEM: InfrahubCoreMenuMutation,
|
|
515
|
+
InfrahubKind.STANDARDWEBHOOK: InfrahubWebhookMutation,
|
|
516
|
+
InfrahubKind.CUSTOMWEBHOOK: InfrahubWebhookMutation,
|
|
516
517
|
}
|
|
517
518
|
|
|
518
519
|
if isinstance(node_schema, NodeSchema) and node_schema.is_ip_prefix():
|
|
@@ -643,7 +644,9 @@ class GraphQLSchemaManager:
|
|
|
643
644
|
self.set_type(name=type_name, graphql_type=relationship_property)
|
|
644
645
|
|
|
645
646
|
def generate_graphql_mutations(
|
|
646
|
-
self,
|
|
647
|
+
self,
|
|
648
|
+
schema: NodeSchema | ProfileSchema | TemplateSchema,
|
|
649
|
+
base_class: type[InfrahubMutation],
|
|
647
650
|
) -> GraphqlMutations:
|
|
648
651
|
graphql_mutation_create_input = self.generate_graphql_mutation_create_input(schema)
|
|
649
652
|
graphql_mutation_update_input = self.generate_graphql_mutation_update_input(schema)
|
|
@@ -682,7 +685,7 @@ class GraphQLSchemaManager:
|
|
|
682
685
|
slug = InputField(StringAttributeCreate, required=True)
|
|
683
686
|
description = InputField(StringAttributeCreate, required=False)
|
|
684
687
|
"""
|
|
685
|
-
attrs: dict[str,
|
|
688
|
+
attrs: dict[str, graphene.String | graphene.InputField] = {"id": graphene.String(required=False)}
|
|
686
689
|
|
|
687
690
|
for attr in schema.attributes:
|
|
688
691
|
if attr.read_only:
|
|
@@ -718,7 +721,7 @@ class GraphQLSchemaManager:
|
|
|
718
721
|
slug = InputField(StringAttributeUpdate, required=False)
|
|
719
722
|
description = InputField(StringAttributeUpdate, required=False)
|
|
720
723
|
"""
|
|
721
|
-
attrs: dict[str,
|
|
724
|
+
attrs: dict[str, graphene.String | graphene.InputField] = {
|
|
722
725
|
"id": graphene.String(required=False),
|
|
723
726
|
"hfid": graphene.List(of_type=graphene.String, required=False),
|
|
724
727
|
}
|
|
@@ -759,7 +762,7 @@ class GraphQLSchemaManager:
|
|
|
759
762
|
slug = InputField(StringAttributeUpdate, required=True)
|
|
760
763
|
description = InputField(StringAttributeUpdate, required=False)
|
|
761
764
|
"""
|
|
762
|
-
attrs: dict[str,
|
|
765
|
+
attrs: dict[str, graphene.String | graphene.InputField] = {
|
|
763
766
|
"id": graphene.String(required=False),
|
|
764
767
|
"hfid": graphene.List(of_type=graphene.String, required=False),
|
|
765
768
|
}
|
|
@@ -855,7 +858,7 @@ class GraphQLSchemaManager:
|
|
|
855
858
|
|
|
856
859
|
def generate_filters(
|
|
857
860
|
self, schema: MainSchemaTypes, top_level: bool = False, include_properties: bool = True
|
|
858
|
-
) -> dict[str,
|
|
861
|
+
) -> dict[str, graphene.Scalar | graphene.List]:
|
|
859
862
|
"""Generate the GraphQL filters for a given Schema object.
|
|
860
863
|
|
|
861
864
|
The generated filter will be different if we are at the top_level (query)
|
|
@@ -920,7 +923,7 @@ class GraphQLSchemaManager:
|
|
|
920
923
|
self,
|
|
921
924
|
schema: MainSchemaTypes,
|
|
922
925
|
node: type[InfrahubObject],
|
|
923
|
-
relation_property:
|
|
926
|
+
relation_property: type[InfrahubObject] | None = None,
|
|
924
927
|
populate_cache: bool = False,
|
|
925
928
|
) -> type[InfrahubObject]:
|
|
926
929
|
"""Generate a edged GraphQL object Type from a Infrahub NodeSchema for pagination."""
|