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
|
@@ -28,7 +28,7 @@ async def connectivity(message: messages.GitRepositoryConnectivity, service: Inf
|
|
|
28
28
|
response = GitRepositoryConnectivityResponse(
|
|
29
29
|
data=response_data,
|
|
30
30
|
)
|
|
31
|
-
await service.
|
|
31
|
+
await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@flow(name="refresh-git-fetch", flow_run_name="Fetch git repository {message.repository_name} on " + WORKER_IDENTITY)
|
|
@@ -125,7 +125,7 @@ async def check(message: messages.RequestGeneratorDefinitionCheck, service: Infr
|
|
|
125
125
|
)
|
|
126
126
|
for event in events:
|
|
127
127
|
event.assign_meta(parent=message)
|
|
128
|
-
await service.send(message=event)
|
|
128
|
+
await service.message_bus.send(message=event)
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
def _run_generator(instance_id: Optional[str], managed_branch: bool, impacted_instances: list[str]) -> bool:
|
|
@@ -20,6 +20,7 @@ from infrahub.message_bus.types import (
|
|
|
20
20
|
ProposedChangeSubscriber,
|
|
21
21
|
)
|
|
22
22
|
from infrahub.proposed_change.models import (
|
|
23
|
+
RequestArtifactDefinitionCheck,
|
|
23
24
|
RequestProposedChangeDataIntegrity,
|
|
24
25
|
RequestProposedChangeRepositoryChecks,
|
|
25
26
|
RequestProposedChangeRunGenerators,
|
|
@@ -28,6 +29,7 @@ from infrahub.proposed_change.models import (
|
|
|
28
29
|
)
|
|
29
30
|
from infrahub.services import InfrahubServices # noqa: TC001
|
|
30
31
|
from infrahub.workflows.catalogue import (
|
|
32
|
+
REQUEST_ARTIFACT_DEFINITION_CHECK,
|
|
31
33
|
REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
|
|
32
34
|
REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
33
35
|
REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
|
|
@@ -84,7 +86,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
84
86
|
)
|
|
85
87
|
for event in events:
|
|
86
88
|
event.assign_meta(parent=message)
|
|
87
|
-
await service.send(message=event)
|
|
89
|
+
await service.message_bus.send(message=event)
|
|
88
90
|
return
|
|
89
91
|
|
|
90
92
|
await _gather_repository_repository_diffs(repositories=repositories, service=service)
|
|
@@ -122,7 +124,9 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
122
124
|
do_repository_checks=message.check_type is CheckType.ALL,
|
|
123
125
|
)
|
|
124
126
|
await service.workflow.submit_workflow(
|
|
125
|
-
workflow=REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
|
|
127
|
+
workflow=REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
|
|
128
|
+
context=message.context,
|
|
129
|
+
parameters={"model": model_proposed_change_run_generator},
|
|
126
130
|
)
|
|
127
131
|
|
|
128
132
|
if message.check_type in [CheckType.ALL, CheckType.DATA] and branch_diff.has_node_changes(
|
|
@@ -136,7 +140,9 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
136
140
|
branch_diff=branch_diff,
|
|
137
141
|
)
|
|
138
142
|
await service.workflow.submit_workflow(
|
|
139
|
-
workflow=REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
|
|
143
|
+
workflow=REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
|
|
144
|
+
context=message.context,
|
|
145
|
+
parameters={"model": model_proposed_change_data_integrity},
|
|
140
146
|
)
|
|
141
147
|
|
|
142
148
|
if message.check_type in [CheckType.REPOSITORY, CheckType.USER]:
|
|
@@ -148,7 +154,9 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
148
154
|
branch_diff=branch_diff,
|
|
149
155
|
)
|
|
150
156
|
await service.workflow.submit_workflow(
|
|
151
|
-
workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
157
|
+
workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
158
|
+
context=message.context,
|
|
159
|
+
parameters={"model": model_proposed_change_repo_checks},
|
|
152
160
|
)
|
|
153
161
|
|
|
154
162
|
if message.check_type in [CheckType.ALL, CheckType.SCHEMA] and branch_diff.has_data_changes(
|
|
@@ -156,6 +164,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
156
164
|
):
|
|
157
165
|
await service.workflow.submit_workflow(
|
|
158
166
|
workflow=REQUEST_PROPOSED_CHANGE_SCHEMA_INTEGRITY,
|
|
167
|
+
context=message.context,
|
|
159
168
|
parameters={
|
|
160
169
|
"model": RequestProposedChangeSchemaIntegrity(
|
|
161
170
|
proposed_change=message.proposed_change,
|
|
@@ -170,6 +179,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
170
179
|
if message.check_type in [CheckType.ALL, CheckType.TEST]:
|
|
171
180
|
await service.workflow.submit_workflow(
|
|
172
181
|
workflow=REQUEST_PROPOSED_CHANGE_USER_TESTS,
|
|
182
|
+
context=message.context,
|
|
173
183
|
parameters={
|
|
174
184
|
"model": RequestProposedChangeUserTests(
|
|
175
185
|
proposed_change=message.proposed_change,
|
|
@@ -183,7 +193,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
183
193
|
|
|
184
194
|
for event in events:
|
|
185
195
|
event.assign_meta(parent=message)
|
|
186
|
-
await service.send(message=event)
|
|
196
|
+
await service.message_bus.send(message=event)
|
|
187
197
|
|
|
188
198
|
|
|
189
199
|
@flow(
|
|
@@ -232,7 +242,7 @@ async def refresh_artifacts(message: messages.RequestProposedChangeRefreshArtifa
|
|
|
232
242
|
|
|
233
243
|
if select:
|
|
234
244
|
log.info(f"Trigger processing of {artifact_definition.definition_name}")
|
|
235
|
-
|
|
245
|
+
model = RequestArtifactDefinitionCheck(
|
|
236
246
|
artifact_definition=artifact_definition,
|
|
237
247
|
branch_diff=message.branch_diff,
|
|
238
248
|
proposed_change=message.proposed_change,
|
|
@@ -241,8 +251,7 @@ async def refresh_artifacts(message: messages.RequestProposedChangeRefreshArtifa
|
|
|
241
251
|
destination_branch=message.destination_branch,
|
|
242
252
|
)
|
|
243
253
|
|
|
244
|
-
|
|
245
|
-
await service.send(message=msg)
|
|
254
|
+
await service.workflow.submit_workflow(REQUEST_ARTIFACT_DEFINITION_CHECK, parameters={"model": model})
|
|
246
255
|
|
|
247
256
|
|
|
248
257
|
GATHER_ARTIFACT_DEFINITIONS = """
|
|
@@ -520,7 +529,7 @@ async def _get_proposed_change_repositories(
|
|
|
520
529
|
return _parse_proposed_change_repositories(message=message, source=source_all, destination=destination_all)
|
|
521
530
|
|
|
522
531
|
|
|
523
|
-
@task(name="proposed-change-validate-repository-conflicts", task_run_name="Validate conflicts on repository")
|
|
532
|
+
@task(name="proposed-change-validate-repository-conflicts", task_run_name="Validate conflicts on repository") # type: ignore[arg-type]
|
|
524
533
|
async def _validate_repository_merge_conflicts(
|
|
525
534
|
repositories: list[ProposedChangeRepository], service: InfrahubServices
|
|
526
535
|
) -> bool:
|
|
@@ -529,7 +538,10 @@ async def _validate_repository_merge_conflicts(
|
|
|
529
538
|
for repo in repositories:
|
|
530
539
|
if repo.has_diff and not repo.is_staging:
|
|
531
540
|
git_repo = await InfrahubRepository.init(
|
|
532
|
-
id=repo.repository_id,
|
|
541
|
+
id=repo.repository_id,
|
|
542
|
+
name=repo.repository_name,
|
|
543
|
+
client=service.client,
|
|
544
|
+
service=service,
|
|
533
545
|
)
|
|
534
546
|
async with lock.registry.get(name=repo.repository_name, namespace="repository"):
|
|
535
547
|
repo.conflicts = await git_repo.get_conflicts(
|
|
@@ -551,7 +563,10 @@ async def _gather_repository_repository_diffs(
|
|
|
551
563
|
if repo.has_diff and repo.source_commit and repo.destination_commit:
|
|
552
564
|
# TODO we need to find a way to return all files in the repo if the repo is new
|
|
553
565
|
git_repo = await InfrahubRepository.init(
|
|
554
|
-
id=repo.repository_id,
|
|
566
|
+
id=repo.repository_id,
|
|
567
|
+
name=repo.repository_name,
|
|
568
|
+
client=service.client,
|
|
569
|
+
service=service,
|
|
555
570
|
)
|
|
556
571
|
|
|
557
572
|
files_changed: list[str] = []
|
|
@@ -91,7 +91,7 @@ async def checks(message: messages.RequestRepositoryChecks, service: InfrahubSer
|
|
|
91
91
|
|
|
92
92
|
for event in events:
|
|
93
93
|
event.assign_meta(parent=message)
|
|
94
|
-
await service.send(message=event)
|
|
94
|
+
await service.message_bus.send(message=event)
|
|
95
95
|
|
|
96
96
|
|
|
97
97
|
@flow(
|
|
@@ -130,4 +130,4 @@ async def user_checks(message: messages.RequestRepositoryUserChecks, service: In
|
|
|
130
130
|
|
|
131
131
|
for event in events:
|
|
132
132
|
event.assign_meta(parent=message)
|
|
133
|
-
await service.send(message=event)
|
|
133
|
+
await service.message_bus.send(message=event)
|
|
@@ -10,4 +10,4 @@ async def request(message: messages.SendEchoRequest, service: InfrahubServices)
|
|
|
10
10
|
service.log.info(f"Received message: {message.message}")
|
|
11
11
|
if message.reply_requested:
|
|
12
12
|
response = SendEchoRequestResponse(data=SendEchoRequestResponseData(response=f"Reply to: {message.message}"))
|
|
13
|
-
await service.
|
|
13
|
+
await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
|
infrahub/message_bus/types.py
CHANGED
|
@@ -9,7 +9,7 @@ from pydantic import BaseModel, Field
|
|
|
9
9
|
from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus
|
|
10
10
|
from infrahub.exceptions import NodeNotFoundError
|
|
11
11
|
|
|
12
|
-
SCHEMA_CHANGE = re.compile("^Schema[A-Z]")
|
|
12
|
+
SCHEMA_CHANGE = re.compile(r"^Schema[A-Z]")
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class MessageTTL(int, Enum):
|
infrahub/permissions/__init__.py
CHANGED
|
@@ -2,12 +2,13 @@ from infrahub.permissions.backend import PermissionBackend
|
|
|
2
2
|
from infrahub.permissions.local_backend import LocalPermissionBackend
|
|
3
3
|
from infrahub.permissions.manager import PermissionManager
|
|
4
4
|
from infrahub.permissions.report import report_schema_permissions
|
|
5
|
-
from infrahub.permissions.types import AssignedPermissions
|
|
5
|
+
from infrahub.permissions.types import AssignedPermissions, get_global_permission_for_kind
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"AssignedPermissions",
|
|
9
9
|
"LocalPermissionBackend",
|
|
10
10
|
"PermissionBackend",
|
|
11
11
|
"PermissionManager",
|
|
12
|
+
"get_global_permission_for_kind",
|
|
12
13
|
"report_schema_permissions",
|
|
13
14
|
]
|
infrahub/permissions/types.py
CHANGED
|
@@ -2,8 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, TypedDict
|
|
4
4
|
|
|
5
|
+
from infrahub.core.constants import GlobalPermissions, InfrahubKind
|
|
6
|
+
from infrahub.core.schema import NodeSchema
|
|
7
|
+
|
|
5
8
|
if TYPE_CHECKING:
|
|
6
9
|
from infrahub.core.account import GlobalPermission, ObjectPermission
|
|
10
|
+
from infrahub.core.schema import MainSchemaTypes
|
|
7
11
|
from infrahub.permissions.constants import BranchRelativePermissionDecision
|
|
8
12
|
|
|
9
13
|
|
|
@@ -18,3 +22,25 @@ class KindPermissions(TypedDict):
|
|
|
18
22
|
delete: BranchRelativePermissionDecision
|
|
19
23
|
update: BranchRelativePermissionDecision
|
|
20
24
|
view: BranchRelativePermissionDecision
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_global_permission_for_kind(schema: MainSchemaTypes) -> GlobalPermissions | None:
|
|
28
|
+
kind_permission_map = {
|
|
29
|
+
InfrahubKind.GENERICACCOUNT: GlobalPermissions.MANAGE_ACCOUNTS,
|
|
30
|
+
InfrahubKind.ACCOUNTGROUP: GlobalPermissions.MANAGE_ACCOUNTS,
|
|
31
|
+
InfrahubKind.ACCOUNTROLE: GlobalPermissions.MANAGE_ACCOUNTS,
|
|
32
|
+
InfrahubKind.BASEPERMISSION: GlobalPermissions.MANAGE_PERMISSIONS,
|
|
33
|
+
InfrahubKind.GENERICREPOSITORY: GlobalPermissions.MANAGE_REPOSITORIES,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if schema.kind in kind_permission_map:
|
|
37
|
+
return kind_permission_map[schema.kind]
|
|
38
|
+
|
|
39
|
+
if isinstance(schema, NodeSchema):
|
|
40
|
+
for base in schema.inherit_from:
|
|
41
|
+
try:
|
|
42
|
+
return kind_permission_map[base]
|
|
43
|
+
except KeyError:
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
return None
|
infrahub/pools/prefix.py
CHANGED
|
@@ -1,174 +1,38 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ipaddress
|
|
4
|
-
from
|
|
5
|
-
from ipaddress import IPv4Network, IPv6Network
|
|
6
|
-
from typing import Optional, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Literal
|
|
7
5
|
|
|
6
|
+
from netaddr import IPSet
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Class to automatically manage Prefixes and help to carve out sub-prefixes
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
def __init__(self, network: str) -> None:
|
|
15
|
-
self.network = ipaddress.ip_network(network)
|
|
16
|
-
|
|
17
|
-
# Define biggest and smallest possible masks
|
|
18
|
-
self.mask_biggest = self.network.prefixlen + 1
|
|
19
|
-
if self.network.version == 4:
|
|
20
|
-
self.mask_smallest = 32
|
|
21
|
-
else:
|
|
22
|
-
self.mask_smallest = 128
|
|
23
|
-
|
|
24
|
-
self.available_subnets = defaultdict(list)
|
|
25
|
-
self.sub_by_key: dict[str, Optional[str]] = OrderedDict()
|
|
26
|
-
self.sub_by_id: dict[str, str] = OrderedDict()
|
|
27
|
-
|
|
28
|
-
# Save the top level available subnet
|
|
29
|
-
for subnet in list(self.network.subnets(new_prefix=self.mask_biggest)):
|
|
30
|
-
self.available_subnets[self.mask_biggest].append(str(subnet))
|
|
31
|
-
|
|
32
|
-
def reserve(self, subnet: str, identifier: Optional[str] = None) -> bool:
|
|
33
|
-
"""
|
|
34
|
-
Indicate that a specific subnet is already reserved/used
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
# TODO Add check to make sure the subnet provided has the right size
|
|
38
|
-
sub = ipaddress.ip_network(subnet)
|
|
39
|
-
|
|
40
|
-
if int(sub.prefixlen) <= int(self.network.prefixlen):
|
|
41
|
-
raise ValueError(f"{subnet} do not have the right size ({sub.prefixlen},{self.network.prefixlen})")
|
|
42
|
-
|
|
43
|
-
if sub.supernet(new_prefix=self.network.prefixlen) != self.network:
|
|
44
|
-
raise ValueError(f"{subnet} is not part of this network")
|
|
45
|
-
|
|
46
|
-
# Check first if this ID as already done a reservation
|
|
47
|
-
if identifier and identifier in self.sub_by_id.keys():
|
|
48
|
-
if self.sub_by_id[identifier] == str(sub):
|
|
49
|
-
return True
|
|
50
|
-
raise ValueError(
|
|
51
|
-
f"this identifier ({identifier}) is already used but for a different resource ({self.sub_by_id[identifier]})"
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
if identifier and str(sub) in self.sub_by_key.keys():
|
|
55
|
-
raise ValueError(f"this subnet is already reserved but not with this identifier ({identifier})")
|
|
56
|
-
|
|
57
|
-
if str(sub) in self.sub_by_key.keys():
|
|
58
|
-
self.remove_subnet_from_available_list(sub)
|
|
59
|
-
return True
|
|
60
|
-
|
|
61
|
-
# Check if the subnet itself is available
|
|
62
|
-
# if available reserve and return
|
|
63
|
-
if subnet in self.available_subnets[sub.prefixlen]:
|
|
64
|
-
if identifier:
|
|
65
|
-
self.sub_by_id[identifier] = subnet
|
|
66
|
-
self.sub_by_key[subnet] = identifier
|
|
67
|
-
else:
|
|
68
|
-
self.sub_by_key[subnet] = None
|
|
69
|
-
|
|
70
|
-
self.remove_subnet_from_available_list(sub)
|
|
71
|
-
return True
|
|
72
|
-
|
|
73
|
-
# If not reserved already, check if the subnet is available
|
|
74
|
-
# start at sublen and check all available subnet
|
|
75
|
-
# increase 1 by 1 until we find the closer supernet available
|
|
76
|
-
# break it down and keep track of the other available subnets
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from infrahub.core.ipam.constants import IPNetworkType
|
|
77
10
|
|
|
78
|
-
for sublen in range(sub.prefixlen - 1, self.network.prefixlen, -1):
|
|
79
|
-
supernet = sub.supernet(new_prefix=sublen)
|
|
80
|
-
if str(supernet) in self.available_subnets[sublen]:
|
|
81
|
-
self.split_supernet(supernet=supernet, subnet=sub)
|
|
82
|
-
return self.reserve(subnet=subnet, identifier=identifier)
|
|
83
11
|
|
|
84
|
-
|
|
12
|
+
def get_next_available_prefix(pool: IPSet, prefix_length: int, prefix_ver: Literal[4, 6] = 4) -> IPNetworkType:
|
|
13
|
+
"""Get the next available prefix of a given prefix length from an IPSet.
|
|
85
14
|
|
|
86
|
-
|
|
87
|
-
|
|
15
|
+
Args:
|
|
16
|
+
pool: netaddr IPSet object with available subnets
|
|
17
|
+
prefix_length: length of the desired prefix
|
|
18
|
+
prefix_ver: IPSet can contain a mix of IPv4 and IPv6 subnets. This parameter specifies the IP version of prefix to acquire.
|
|
88
19
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
subs = supernet.subnets(new_prefix=clean_prefixlen)
|
|
109
|
-
next_sub: Union[IPv4Network, IPv6Network] = next(subs) # type: ignore[assignment]
|
|
110
|
-
self.split_supernet(supernet=supernet, subnet=next_sub)
|
|
111
|
-
self.reserve(subnet=str(next_sub), identifier=identifier)
|
|
112
|
-
return next_sub
|
|
113
|
-
|
|
114
|
-
raise IndexError("No More subnet available")
|
|
115
|
-
|
|
116
|
-
def get_nbr_available_subnets(self) -> dict[int, int]:
|
|
117
|
-
tmp = {}
|
|
118
|
-
for i in range(self.mask_biggest, self.mask_smallest + 1):
|
|
119
|
-
tmp[i] = len(self.available_subnets[i])
|
|
120
|
-
|
|
121
|
-
return tmp
|
|
122
|
-
|
|
123
|
-
def check_if_already_allocated(self, identifier: str) -> bool:
|
|
124
|
-
"""
|
|
125
|
-
Check if a subnet has already been allocated based on an identifier
|
|
126
|
-
|
|
127
|
-
Need to add the same capability based on Network address
|
|
128
|
-
If both identifier and subnet are provided, identifier take precedence
|
|
129
|
-
"""
|
|
130
|
-
if identifier in self.sub_by_id.keys():
|
|
131
|
-
return True
|
|
132
|
-
return False
|
|
133
|
-
|
|
134
|
-
def split_supernet(
|
|
135
|
-
self, supernet: Union[IPv4Network, IPv6Network], subnet: Union[IPv4Network, IPv6Network]
|
|
136
|
-
) -> None:
|
|
137
|
-
"""Split a supernet into smaller networks"""
|
|
138
|
-
|
|
139
|
-
# TODO ensure subnet is small than supernet
|
|
140
|
-
# TODO ensure that subnet is part of supernet
|
|
141
|
-
parent_net = supernet
|
|
142
|
-
for i in range(supernet.prefixlen + 1, subnet.prefixlen + 1):
|
|
143
|
-
tmp_net: list[Union[IPv4Network, IPv6Network]] = list(parent_net.subnets(new_prefix=i))
|
|
144
|
-
|
|
145
|
-
if i == subnet.prefixlen:
|
|
146
|
-
for net in tmp_net:
|
|
147
|
-
self.available_subnets[i].append(str(net))
|
|
148
|
-
else:
|
|
149
|
-
if subnet.subnet_of(other=tmp_net[0]): # type: ignore[arg-type]
|
|
150
|
-
parent = 0
|
|
151
|
-
other = 1
|
|
152
|
-
else:
|
|
153
|
-
parent = 1
|
|
154
|
-
other = 0
|
|
155
|
-
|
|
156
|
-
parent_net = tmp_net[parent]
|
|
157
|
-
self.available_subnets[i].append(str(tmp_net[other]))
|
|
158
|
-
|
|
159
|
-
self.remove_subnet_from_available_list(supernet)
|
|
160
|
-
|
|
161
|
-
def remove_subnet_from_available_list(self, subnet: Union[IPv4Network, IPv6Network]) -> None:
|
|
162
|
-
"""Remove a subnet from the list of available Subnet."""
|
|
163
|
-
try:
|
|
164
|
-
idx = self.available_subnets[subnet.prefixlen].index(str(subnet))
|
|
165
|
-
del self.available_subnets[subnet.prefixlen][idx]
|
|
166
|
-
except ValueError:
|
|
167
|
-
# Already removed
|
|
168
|
-
pass
|
|
169
|
-
|
|
170
|
-
# if idx:
|
|
171
|
-
# return True
|
|
172
|
-
# except:
|
|
173
|
-
# log.warn("Unable to remove %s from list of available subnets" % str(subnet))
|
|
174
|
-
# return False
|
|
20
|
+
Raises:
|
|
21
|
+
ValueError: If there are no available subnets in the pool
|
|
22
|
+
"""
|
|
23
|
+
prefix_ver_map = {
|
|
24
|
+
4: ipaddress.IPv4Network,
|
|
25
|
+
6: ipaddress.IPv6Network,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
filtered_pool = IPSet([])
|
|
29
|
+
for subnet in pool.iter_cidrs():
|
|
30
|
+
if isinstance(ipaddress.ip_network(str(subnet)), prefix_ver_map[prefix_ver]):
|
|
31
|
+
filtered_pool.add(subnet)
|
|
32
|
+
|
|
33
|
+
for cidr in filtered_pool.iter_cidrs():
|
|
34
|
+
if cidr.prefixlen <= prefix_length:
|
|
35
|
+
next_available = ipaddress.ip_network(f"{cidr.network}/{prefix_length}")
|
|
36
|
+
return next_available
|
|
37
|
+
|
|
38
|
+
raise ValueError("No available subnets in pool")
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, FastAPI
|
|
4
|
+
from prefect.server.api.server import create_app
|
|
5
|
+
|
|
6
|
+
from . import events
|
|
7
|
+
|
|
8
|
+
router = APIRouter(prefix="/infrahub")
|
|
9
|
+
|
|
10
|
+
router.include_router(events.router)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_infrahub_prefect() -> FastAPI:
|
|
14
|
+
app = create_app()
|
|
15
|
+
api_app: FastAPI = app.__dict__["api_app"]
|
|
16
|
+
api_app.include_router(router=router)
|
|
17
|
+
|
|
18
|
+
return app
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from prefect.server.events.schemas.events import ReceivedEvent
|
|
6
|
+
from prefect.server.events.storage import INTERACTIVE_PAGE_SIZE
|
|
7
|
+
from prefect.server.events.storage.database import raw_count_events, read_events
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from prefect.server.events.filters import EventFilter
|
|
11
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def query_events(
|
|
15
|
+
session: AsyncSession, filter: EventFilter, page_size: int = INTERACTIVE_PAGE_SIZE, offset: int | None = None
|
|
16
|
+
) -> tuple[list[ReceivedEvent], int]:
|
|
17
|
+
count = await raw_count_events(session, filter) # type: ignore[attr-defined]
|
|
18
|
+
page = await read_events(session, filter, limit=page_size, offset=offset) # type: ignore[attr-defined]
|
|
19
|
+
events = [ReceivedEvent.model_validate(e, from_attributes=True) for e in page]
|
|
20
|
+
return events, count
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from fastapi import APIRouter
|
|
2
|
+
from fastapi.param_functions import Depends
|
|
3
|
+
from prefect.server.database import PrefectDBInterface, provide_database_interface
|
|
4
|
+
|
|
5
|
+
from .database import query_events
|
|
6
|
+
from .models import InfrahubEventfilterInput, InfrahubEventPage
|
|
7
|
+
|
|
8
|
+
router = APIRouter(prefix="/events", tags=["Infrahub"])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@router.post(
|
|
12
|
+
"/filter",
|
|
13
|
+
)
|
|
14
|
+
async def read_events(
|
|
15
|
+
event_filter: InfrahubEventfilterInput,
|
|
16
|
+
db: PrefectDBInterface = Depends(provide_database_interface), # noqa: B008
|
|
17
|
+
) -> InfrahubEventPage:
|
|
18
|
+
event_filter.filter.set_prefix()
|
|
19
|
+
|
|
20
|
+
async with db.session_context() as session:
|
|
21
|
+
events, total = await query_events(
|
|
22
|
+
session=session, filter=event_filter.filter, page_size=event_filter.limit, offset=event_filter.offset
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
return InfrahubEventPage(
|
|
26
|
+
events=events,
|
|
27
|
+
total=total,
|
|
28
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Sequence, cast
|
|
2
|
+
|
|
3
|
+
from prefect.server.database import PrefectDBInterface, db_injector
|
|
4
|
+
from prefect.server.events.filters import EventFilter, EventNameFilter, EventOrder, EventRelatedFilter
|
|
5
|
+
from prefect.server.events.schemas.events import ReceivedEvent
|
|
6
|
+
from prefect.server.utilities.schemas import PrefectBaseModel
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from sqlalchemy.sql.expression import ColumnExpressionArgument
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class InfrahubEventFilter(EventFilter):
|
|
14
|
+
matching_related: list[EventRelatedFilter] = Field(default_factory=list)
|
|
15
|
+
|
|
16
|
+
def set_prefix(self) -> None:
|
|
17
|
+
if self.event:
|
|
18
|
+
if self.event.prefix is not None and "infrahub." not in self.event.prefix:
|
|
19
|
+
self.event.prefix.append("infrahub.")
|
|
20
|
+
else:
|
|
21
|
+
self.event = EventNameFilter(prefix=["infrahub."], name=[], exclude_prefix=None, exclude_name=None)
|
|
22
|
+
|
|
23
|
+
@db_injector
|
|
24
|
+
def build_where_clauses(self, db: PrefectDBInterface) -> Sequence["ColumnExpressionArgument[bool]"]:
|
|
25
|
+
result = cast(list["ColumnExpressionArgument[bool]"], super().build_where_clauses())
|
|
26
|
+
top_level_filter = self._scoped_event_resources(db)
|
|
27
|
+
for matching_related in self.matching_related:
|
|
28
|
+
matching_related._top_level_filter = top_level_filter
|
|
29
|
+
result.extend(matching_related.build_where_clauses())
|
|
30
|
+
|
|
31
|
+
return result
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def default(cls) -> "InfrahubEventFilter":
|
|
35
|
+
return cls(event=None, any_resource=None, resource=None, related=None, order=EventOrder.DESC)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class InfrahubEventPage(PrefectBaseModel):
|
|
39
|
+
events: list[ReceivedEvent] = Field(..., description="The Events matching the query")
|
|
40
|
+
total: int = Field(..., description="The total number of matching Events")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class InfrahubEventfilterInput(BaseModel):
|
|
44
|
+
limit: int = Field(default=50)
|
|
45
|
+
filter: InfrahubEventFilter = Field(default_factory=InfrahubEventFilter.default)
|
|
46
|
+
offset: int | None = Field(default=None)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from pydantic import Field
|
|
1
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
2
2
|
|
|
3
3
|
from infrahub.message_bus.messages.proposed_change.base_with_diff import BaseProposedChangeWithDiffMessage
|
|
4
|
+
from infrahub.message_bus.types import ProposedChangeArtifactDefinition, ProposedChangeBranchDiff
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class RequestProposedChangeDataIntegrity(BaseProposedChangeWithDiffMessage):
|
|
@@ -26,3 +27,16 @@ class RequestProposedChangeSchemaIntegrity(BaseProposedChangeWithDiffMessage):
|
|
|
26
27
|
|
|
27
28
|
class RequestProposedChangeUserTests(BaseProposedChangeWithDiffMessage):
|
|
28
29
|
"""Sent trigger to run tests (smoke, units, integrations) for a proposed change."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class RequestArtifactDefinitionCheck(BaseModel):
|
|
33
|
+
"""Sent to validate the generation of artifacts in relation to a proposed change."""
|
|
34
|
+
|
|
35
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
36
|
+
|
|
37
|
+
artifact_definition: ProposedChangeArtifactDefinition = Field(..., description="The Artifact Definition")
|
|
38
|
+
branch_diff: ProposedChangeBranchDiff = Field(..., description="The calculated diff between the two branches")
|
|
39
|
+
proposed_change: str = Field(..., description="The unique ID of the Proposed Change")
|
|
40
|
+
source_branch: str = Field(..., description="The source branch")
|
|
41
|
+
source_branch_sync_with_git: bool = Field(..., description="Indicates if the source branch should sync with git")
|
|
42
|
+
destination_branch: str = Field(..., description="The target branch")
|