infrahub-server 1.2.0rc0__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/api/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +5 -3
- infrahub/artifacts/tasks.py +3 -5
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +240 -12
- infrahub/computed_attribute/tasks.py +77 -441
- infrahub/computed_attribute/triggers.py +13 -47
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +58 -58
- infrahub/core/branch/tasks.py +74 -22
- infrahub/core/changelog/diff.py +95 -36
- infrahub/core/changelog/models.py +217 -43
- infrahub/core/constants/__init__.py +28 -0
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constants/schema.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/enricher/cardinality_one.py +5 -0
- infrahub/core/diff/enricher/hierarchy.py +17 -4
- infrahub/core/diff/enricher/labels.py +5 -0
- infrahub/core/diff/enricher/path_identifier.py +4 -0
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +32 -9
- infrahub/core/diff/parent_node_adder.py +78 -0
- infrahub/core/diff/payload_builder.py +13 -2
- infrahub/core/diff/query/filters.py +2 -2
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query/save.py +188 -182
- infrahub/core/diff/query/summary_counts_enricher.py +51 -4
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/diff/repository/deserializer.py +8 -3
- infrahub/core/diff/repository/repository.py +156 -38
- infrahub/core/diff/tasks.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/index.py +3 -0
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +36 -36
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +12 -3
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +43 -26
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/node_remove.py +26 -12
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +43 -39
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +7 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +228 -40
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +51 -59
- infrahub/core/schema/attribute_schema.py +16 -8
- infrahub/core/schema/basenode_schema.py +105 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +147 -0
- infrahub/core/schema/definitions/core/account.py +171 -0
- infrahub/core/schema/definitions/core/artifact.py +136 -0
- infrahub/core/schema/definitions/core/builtin.py +24 -0
- infrahub/core/schema/definitions/core/check.py +68 -0
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +100 -0
- infrahub/core/schema/definitions/core/graphql_query.py +79 -0
- infrahub/core/schema/definitions/core/group.py +108 -0
- infrahub/core/schema/definitions/core/ipam.py +193 -0
- infrahub/core/schema/definitions/core/lineage.py +19 -0
- infrahub/core/schema/definitions/core/menu.py +48 -0
- infrahub/core/schema/definitions/core/permission.py +163 -0
- infrahub/core/schema/definitions/core/profile.py +18 -0
- infrahub/core/schema/definitions/core/propose_change.py +97 -0
- infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
- infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
- infrahub/core/schema/definitions/core/repository.py +286 -0
- infrahub/core/schema/definitions/core/resource_pool.py +170 -0
- infrahub/core/schema/definitions/core/template.py +27 -0
- infrahub/core/schema/definitions/core/transform.py +96 -0
- infrahub/core/schema/definitions/core/webhook.py +134 -0
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +14 -6
- infrahub/core/schema/schema_branch.py +292 -144
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/timestamp.py +3 -3
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +27 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/builder/diff/deserializer.py +3 -1
- infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
- infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +64 -0
- infrahub/events/branch_action.py +33 -22
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +51 -21
- infrahub/events/models.py +18 -19
- infrahub/events/node_action.py +88 -37
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +32 -24
- infrahub/generators/models.py +2 -3
- infrahub/generators/tasks.py +24 -4
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +48 -24
- infrahub/git/models.py +101 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +408 -6
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +39 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +17 -19
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/branch.py +26 -1
- infrahub/graphql/mutations/computed_attribute.py +9 -5
- infrahub/graphql/mutations/diff.py +23 -11
- infrahub/graphql/mutations/diff_conflict.py +5 -0
- infrahub/graphql/mutations/generator.py +83 -0
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +54 -74
- infrahub/graphql/mutations/main.py +195 -132
- infrahub/graphql/mutations/menu.py +7 -7
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +93 -19
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +19 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/permissions.py +1 -10
- infrahub/graphql/queries/diff/tree.py +19 -14
- infrahub/graphql/queries/event.py +5 -2
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/context.py +12 -0
- infrahub/graphql/types/event.py +84 -17
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/lock.py +20 -20
- infrahub/menu/constants.py +0 -1
- infrahub/menu/generator.py +9 -21
- infrahub/menu/menu.py +17 -38
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/__init__.py +11 -13
- infrahub/message_bus/messages/__init__.py +1 -21
- infrahub/message_bus/messages/check_generator_run.py +3 -3
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/messages/send_echo_request.py +1 -1
- infrahub/message_bus/operations/__init__.py +1 -10
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/event/worker.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -2
- infrahub/message_bus/operations/requests/generator_definition.py +21 -23
- infrahub/message_bus/operations/requests/proposed_change.py +14 -10
- infrahub/permissions/globals.py +15 -0
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/models.py +3 -0
- infrahub/proposed_change/tasks.py +58 -45
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +2 -3
- infrahub/services/__init__.py +2 -2
- infrahub/services/adapters/cache/__init__.py +4 -6
- infrahub/services/adapters/cache/nats.py +4 -5
- infrahub/services/adapters/cache/redis.py +3 -7
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/services/adapters/message_bus/__init__.py +3 -3
- infrahub/services/adapters/message_bus/local.py +2 -2
- infrahub/services/adapters/message_bus/nats.py +4 -4
- infrahub/services/adapters/message_bus/rabbitmq.py +4 -4
- infrahub/services/adapters/workflow/local.py +2 -2
- infrahub/services/component.py +5 -5
- infrahub/services/protocols.py +7 -7
- infrahub/services/scheduler.py +1 -3
- infrahub/task_manager/event.py +102 -9
- infrahub/task_manager/models.py +27 -7
- infrahub/tasks/artifact.py +7 -6
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +4 -6
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +54 -5
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -84
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +176 -44
- infrahub/webhook/tasks.py +154 -155
- infrahub/webhook/triggers.py +31 -7
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +86 -35
- infrahub/workflows/initialization.py +8 -2
- infrahub/workflows/models.py +27 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +35 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/cli_commands.py +5 -1
- infrahub_sdk/ctl/utils.py +0 -16
- infrahub_sdk/exceptions.py +12 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +71 -22
- infrahub_sdk/protocols.py +21 -8
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +11 -0
- infrahub_sdk/task/constants.py +3 -0
- infrahub_sdk/task/exceptions.py +25 -0
- infrahub_sdk/task/manager.py +551 -0
- infrahub_sdk/task/models.py +74 -0
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +142 -33
- infrahub_sdk/utils.py +29 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +8 -6
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +349 -293
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/core/schema/definitions/core.py +0 -2286
- infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
- infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
- infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/messages/request_repository_checks.py +0 -12
- infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
- infrahub/message_bus/operations/check/repository.py +0 -293
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/message_bus/operations/requests/repository.py +0 -133
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
infrahub/api/dependencies.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, AsyncIterator
|
|
3
|
+
from typing import TYPE_CHECKING, AsyncIterator
|
|
4
4
|
|
|
5
5
|
from fastapi import Depends, Query, Request
|
|
6
6
|
from fastapi.security import APIKeyHeader, HTTPAuthorizationCredentials, HTTPBearer
|
|
@@ -25,7 +25,7 @@ jwt_scheme = HTTPBearer(auto_error=False)
|
|
|
25
25
|
api_key_scheme = APIKeyHeader(name="X-INFRAHUB-KEY", auto_error=False)
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
async def cookie_auth_scheme(request: Request) ->
|
|
28
|
+
async def cookie_auth_scheme(request: Request) -> str | None:
|
|
29
29
|
return request.cookies.get("access_token") # Replace with the actual name of your JWT cookie
|
|
30
30
|
|
|
31
31
|
|
|
@@ -62,7 +62,7 @@ async def get_access_token(
|
|
|
62
62
|
async def get_refresh_token(
|
|
63
63
|
request: Request,
|
|
64
64
|
db: InfrahubDatabase = Depends(get_db),
|
|
65
|
-
jwt_header:
|
|
65
|
+
jwt_header: HTTPAuthorizationCredentials | None = Depends(jwt_scheme),
|
|
66
66
|
) -> RefreshTokenData:
|
|
67
67
|
token = None
|
|
68
68
|
|
|
@@ -83,8 +83,8 @@ async def get_refresh_token(
|
|
|
83
83
|
|
|
84
84
|
async def get_branch_params(
|
|
85
85
|
db: InfrahubDatabase = Depends(get_db),
|
|
86
|
-
branch_name:
|
|
87
|
-
at:
|
|
86
|
+
branch_name: str | None = Query(None, alias="branch", description="Name of the branch to use for the query"),
|
|
87
|
+
at: str | None = Query(None, description="Time to use for the query, in absolute or relative format"),
|
|
88
88
|
) -> BranchParams:
|
|
89
89
|
branch = await registry.get_branch(db=db, branch=branch_name)
|
|
90
90
|
|
|
@@ -93,7 +93,7 @@ async def get_branch_params(
|
|
|
93
93
|
|
|
94
94
|
async def get_branch_dep(
|
|
95
95
|
db: InfrahubDatabase = Depends(get_db),
|
|
96
|
-
branch_name:
|
|
96
|
+
branch_name: str | None = Query(None, alias="branch", description="Name of the branch to use for the query"),
|
|
97
97
|
) -> Branch:
|
|
98
98
|
return await registry.get_branch(db=db, branch=branch_name)
|
|
99
99
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
|
|
4
4
|
|
|
@@ -9,13 +9,13 @@ from infrahub.core.timestamp import Timestamp
|
|
|
9
9
|
class DiffQueryValidated(BaseModel):
|
|
10
10
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
11
11
|
branch: Branch
|
|
12
|
-
time_from:
|
|
13
|
-
time_to:
|
|
12
|
+
time_from: str | None = None
|
|
13
|
+
time_to: str | None = None
|
|
14
14
|
branch_only: bool
|
|
15
15
|
|
|
16
16
|
@field_validator("time_from", "time_to", mode="before")
|
|
17
17
|
@classmethod
|
|
18
|
-
def validate_time(cls, value:
|
|
18
|
+
def validate_time(cls, value: str | None) -> str | None:
|
|
19
19
|
if not value:
|
|
20
20
|
return None
|
|
21
21
|
Timestamp(value)
|
|
@@ -24,12 +24,12 @@ class DiffQueryValidated(BaseModel):
|
|
|
24
24
|
@model_validator(mode="before")
|
|
25
25
|
@classmethod
|
|
26
26
|
def validate_time_from_if_required(cls, values: dict[str, Any]) -> dict[str, Any]:
|
|
27
|
-
branch:
|
|
28
|
-
time_from:
|
|
27
|
+
branch: Branch | None = values.get("branch")
|
|
28
|
+
time_from: Timestamp | None = values.get("time_from")
|
|
29
29
|
if getattr(branch, "is_default", False) and not time_from:
|
|
30
30
|
branch_name = getattr(branch, "name", "")
|
|
31
31
|
raise ValueError(f"time_from is mandatory when diffing on the default branch `{branch_name}`.")
|
|
32
|
-
time_to:
|
|
32
|
+
time_to: Timestamp | None = values.get("time_to")
|
|
33
33
|
if time_to and time_from and time_to < time_from:
|
|
34
34
|
raise ValueError("time_from and time_to are not a valid time range")
|
|
35
35
|
return values
|
infrahub/api/schema.py
CHANGED
infrahub/artifacts/models.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from pydantic import BaseModel, Field
|
|
4
2
|
|
|
3
|
+
from infrahub.context import InfrahubContext
|
|
4
|
+
|
|
5
5
|
|
|
6
6
|
class CheckArtifactCreate(BaseModel):
|
|
7
7
|
"""Runs a check to verify the creation of an artifact."""
|
|
@@ -17,9 +17,11 @@ class CheckArtifactCreate(BaseModel):
|
|
|
17
17
|
repository_kind: str = Field(..., description="The kind of the Repository")
|
|
18
18
|
branch_name: str = Field(..., description="The branch where the check is run")
|
|
19
19
|
target_id: str = Field(..., description="The ID of the target object for this artifact")
|
|
20
|
+
target_kind: str = Field(..., description="The kind of the target object for this artifact")
|
|
20
21
|
target_name: str = Field(..., description="Name of the artifact target")
|
|
21
|
-
artifact_id:
|
|
22
|
+
artifact_id: str | None = Field(default=None, description="The id of the artifact if it previously existed")
|
|
22
23
|
query: str = Field(..., description="The name of the query to use when collecting data")
|
|
23
24
|
timeout: int = Field(..., description="Timeout for requests used to generate this artifact")
|
|
24
25
|
variables: dict = Field(..., description="Input variables when generating the artifact")
|
|
25
26
|
validator_id: str = Field(..., description="The ID of the validator")
|
|
27
|
+
context: InfrahubContext = Field(..., description="The context of the task")
|
infrahub/artifacts/tasks.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Union
|
|
2
|
-
|
|
3
1
|
from prefect import flow
|
|
4
2
|
|
|
5
3
|
from infrahub.artifacts.models import CheckArtifactCreate
|
|
@@ -32,10 +30,10 @@ async def create(model: CheckArtifactCreate, service: InfrahubServices) -> Valid
|
|
|
32
30
|
service=service,
|
|
33
31
|
)
|
|
34
32
|
|
|
35
|
-
artifact = await define_artifact(model=model, service=service)
|
|
33
|
+
artifact, artifact_created = await define_artifact(model=model, service=service)
|
|
36
34
|
|
|
37
35
|
severity = "info"
|
|
38
|
-
artifact_result: dict[str,
|
|
36
|
+
artifact_result: dict[str, str | bool | None] = {
|
|
39
37
|
"changed": None,
|
|
40
38
|
"checksum": None,
|
|
41
39
|
"artifact_id": None,
|
|
@@ -44,7 +42,7 @@ async def create(model: CheckArtifactCreate, service: InfrahubServices) -> Valid
|
|
|
44
42
|
check_message = "Failed to render artifact"
|
|
45
43
|
|
|
46
44
|
try:
|
|
47
|
-
result = await repo.render_artifact(artifact=artifact, message=model)
|
|
45
|
+
result = await repo.render_artifact(artifact=artifact, artifact_created=artifact_created, message=model)
|
|
48
46
|
artifact_result["changed"] = result.changed
|
|
49
47
|
artifact_result["checksum"] = result.checksum
|
|
50
48
|
artifact_result["artifact_id"] = result.artifact_id
|
infrahub/cli/__init__.py
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
from asyncio import run as aiorun
|
|
2
2
|
|
|
3
3
|
import typer
|
|
4
|
+
from infrahub_sdk.async_typer import AsyncTyper
|
|
4
5
|
|
|
5
6
|
from infrahub import config
|
|
6
|
-
from infrahub.cli.context import CliContext
|
|
7
|
-
from infrahub.cli.db import app as db_app
|
|
8
|
-
from infrahub.cli.events import app as events_app
|
|
9
|
-
from infrahub.cli.git_agent import app as git_app
|
|
10
|
-
from infrahub.cli.server import app as server_app
|
|
11
|
-
from infrahub.cli.tasks import app as tasks_app
|
|
12
7
|
from infrahub.core.initialization import initialization
|
|
13
8
|
from infrahub.database import InfrahubDatabase, get_db
|
|
14
9
|
|
|
15
|
-
|
|
10
|
+
from .context import CliContext
|
|
11
|
+
from .db import app as db_app
|
|
12
|
+
from .events import app as events_app
|
|
13
|
+
from .git_agent import app as git_app
|
|
14
|
+
from .server import app as server_app
|
|
15
|
+
from .tasks import app as tasks_app
|
|
16
|
+
from .upgrade import upgrade_cmd
|
|
17
|
+
|
|
18
|
+
app = AsyncTyper(name="Infrahub CLI", pretty_exceptions_enable=False)
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
@app.callback()
|
|
@@ -22,10 +25,11 @@ def common(ctx: typer.Context) -> None:
|
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
app.add_typer(server_app, name="server")
|
|
25
|
-
app.add_typer(git_app, name="git-agent")
|
|
28
|
+
app.add_typer(git_app, name="git-agent", hidden=True)
|
|
26
29
|
app.add_typer(db_app, name="db")
|
|
27
|
-
app.add_typer(events_app, name="events", help="Interact with the events system.")
|
|
30
|
+
app.add_typer(events_app, name="events", help="Interact with the events system.", hidden=True)
|
|
28
31
|
app.add_typer(tasks_app, name="tasks", hidden=True)
|
|
32
|
+
app.command(name="upgrade")(upgrade_cmd)
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
async def _init_shell(config_file: str) -> None:
|
infrahub/cli/db.py
CHANGED
|
@@ -4,7 +4,7 @@ import importlib
|
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
6
|
from enum import Enum
|
|
7
|
-
from typing import TYPE_CHECKING
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
import typer
|
|
10
10
|
from infrahub_sdk.async_typer import AsyncTyper
|
|
@@ -16,23 +16,16 @@ from rich.table import Table
|
|
|
16
16
|
|
|
17
17
|
from infrahub import config
|
|
18
18
|
from infrahub.core import registry
|
|
19
|
-
from infrahub.core.constants import InfrahubKind
|
|
20
19
|
from infrahub.core.graph import GRAPH_VERSION
|
|
21
20
|
from infrahub.core.graph.constraints import ConstraintManagerBase, ConstraintManagerMemgraph, ConstraintManagerNeo4j
|
|
22
21
|
from infrahub.core.graph.index import node_indexes, rel_indexes
|
|
23
22
|
from infrahub.core.graph.schema import GRAPH_SCHEMA
|
|
24
23
|
from infrahub.core.initialization import (
|
|
25
|
-
create_anonymous_role,
|
|
26
|
-
create_default_menu,
|
|
27
|
-
create_default_roles,
|
|
28
|
-
create_super_administrator_role,
|
|
29
|
-
create_super_administrators_group,
|
|
30
24
|
first_time_initialization,
|
|
31
25
|
get_root_node,
|
|
32
26
|
initialization,
|
|
33
27
|
initialize_registry,
|
|
34
28
|
)
|
|
35
|
-
from infrahub.core.manager import NodeManager
|
|
36
29
|
from infrahub.core.migrations.graph import get_graph_migrations
|
|
37
30
|
from infrahub.core.migrations.schema.models import SchemaApplyMigrationData
|
|
38
31
|
from infrahub.core.migrations.schema.tasks import schema_apply_migrations
|
|
@@ -48,6 +41,8 @@ from infrahub.services import InfrahubServices
|
|
|
48
41
|
from infrahub.services.adapters.message_bus.local import BusSimulator
|
|
49
42
|
from infrahub.services.adapters.workflow.local import WorkflowLocalExecution
|
|
50
43
|
|
|
44
|
+
from .constants import ERROR_BADGE, FAILED_BADGE, SUCCESS_BADGE
|
|
45
|
+
|
|
51
46
|
if TYPE_CHECKING:
|
|
52
47
|
from infrahub.cli.context import CliContext
|
|
53
48
|
from infrahub.database import InfrahubDatabase
|
|
@@ -121,6 +116,7 @@ async def load_test_data(
|
|
|
121
116
|
|
|
122
117
|
context: CliContext = ctx.obj
|
|
123
118
|
dbdriver = await context.init_db(retry=1)
|
|
119
|
+
|
|
124
120
|
async with dbdriver.start_session() as db:
|
|
125
121
|
await initialization(db=db)
|
|
126
122
|
|
|
@@ -136,8 +132,8 @@ async def load_test_data(
|
|
|
136
132
|
await dbdriver.close()
|
|
137
133
|
|
|
138
134
|
|
|
139
|
-
@app.command()
|
|
140
|
-
async def
|
|
135
|
+
@app.command(name="migrate")
|
|
136
|
+
async def migrate_cmd(
|
|
141
137
|
ctx: typer.Context,
|
|
142
138
|
check: bool = typer.Option(False, help="Check the state of the database without applying the migrations."),
|
|
143
139
|
config_file: str = typer.Argument("infrahub.toml", envvar="INFRAHUB_CONFIG"),
|
|
@@ -147,53 +143,18 @@ async def migrate(
|
|
|
147
143
|
logging.getLogger("neo4j").setLevel(logging.ERROR)
|
|
148
144
|
logging.getLogger("prefect").setLevel(logging.ERROR)
|
|
149
145
|
|
|
150
|
-
log = get_logger()
|
|
151
|
-
|
|
152
146
|
config.load_and_exit(config_file_name=config_file)
|
|
153
147
|
|
|
154
148
|
context: CliContext = ctx.obj
|
|
155
149
|
dbdriver = await context.init_db(retry=1)
|
|
156
|
-
async with dbdriver.start_session() as db:
|
|
157
|
-
rprint("Checking current state of the Database")
|
|
158
150
|
|
|
159
|
-
|
|
160
|
-
root_node = await get_root_node(db=db)
|
|
161
|
-
migrations = await get_graph_migrations(root=root_node)
|
|
162
|
-
|
|
163
|
-
if not migrations:
|
|
164
|
-
rprint(f"Database up-to-date (v{root_node.graph_version}), no migration to execute.")
|
|
165
|
-
else:
|
|
166
|
-
rprint(
|
|
167
|
-
f"Database needs to be updated (v{root_node.graph_version} -> v{GRAPH_VERSION}), {len(migrations)} migrations pending"
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
if migrations and not check:
|
|
171
|
-
for migration in migrations:
|
|
172
|
-
log.debug(f"Execute Migration: {migration.name}")
|
|
173
|
-
execution_result = await migration.execute(db=db)
|
|
174
|
-
validation_result = None
|
|
175
|
-
|
|
176
|
-
if execution_result.success:
|
|
177
|
-
validation_result = await migration.validate_migration(db=db)
|
|
178
|
-
if validation_result.success:
|
|
179
|
-
rprint(f"Migration: {migration.name} [green]SUCCESS[/green]")
|
|
180
|
-
root_node.graph_version = migration.minimum_version + 1
|
|
181
|
-
await root_node.save(db=db)
|
|
182
|
-
|
|
183
|
-
if not execution_result.success or validation_result and not validation_result.success:
|
|
184
|
-
rprint(f"Migration: {migration.name} [bold red]FAILED[/bold red]")
|
|
185
|
-
for error in execution_result.errors:
|
|
186
|
-
rprint(f" {error}")
|
|
187
|
-
if validation_result and not validation_result.success:
|
|
188
|
-
for error in validation_result.errors:
|
|
189
|
-
rprint(f" {error}")
|
|
190
|
-
break
|
|
151
|
+
await migrate_database(db=dbdriver, initialize=True, check=check)
|
|
191
152
|
|
|
192
153
|
await dbdriver.close()
|
|
193
154
|
|
|
194
155
|
|
|
195
|
-
@app.command()
|
|
196
|
-
async def
|
|
156
|
+
@app.command(name="update-core-schema")
|
|
157
|
+
async def update_core_schema_cmd(
|
|
197
158
|
ctx: typer.Context,
|
|
198
159
|
debug: bool = typer.Option(False, help="Enable advanced logging and troubleshooting"),
|
|
199
160
|
config_file: str = typer.Argument("infrahub.toml", envvar="INFRAHUB_CONFIG"),
|
|
@@ -209,116 +170,14 @@ async def update_core_schema(
|
|
|
209
170
|
context: CliContext = ctx.obj
|
|
210
171
|
dbdriver = await context.init_db(retry=1)
|
|
211
172
|
|
|
212
|
-
|
|
173
|
+
service = await InfrahubServices.new(
|
|
174
|
+
database=dbdriver, message_bus=BusSimulator(), workflow=WorkflowLocalExecution()
|
|
175
|
+
)
|
|
213
176
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
# ----------------------------------------------------------
|
|
219
|
-
service = await InfrahubServices.new(
|
|
220
|
-
database=db, message_bus=BusSimulator(), workflow=WorkflowLocalExecution()
|
|
221
|
-
)
|
|
222
|
-
await initialize_registry(db=db)
|
|
223
|
-
|
|
224
|
-
default_branch = registry.get_branch_from_registry(branch=registry.default_branch)
|
|
225
|
-
|
|
226
|
-
registry.schema = SchemaManager()
|
|
227
|
-
schema = SchemaRoot(**internal_schema)
|
|
228
|
-
registry.schema.register_schema(schema=schema)
|
|
229
|
-
|
|
230
|
-
# ----------------------------------------------------------
|
|
231
|
-
# Load Current Schema from the database
|
|
232
|
-
# ----------------------------------------------------------
|
|
233
|
-
schema_default_branch = await registry.schema.load_schema_from_db(db=db, branch=default_branch)
|
|
234
|
-
registry.schema.set_schema_branch(name=default_branch.name, schema=schema_default_branch)
|
|
235
|
-
branch_schema = registry.schema.get_schema_branch(name=registry.default_branch)
|
|
236
|
-
|
|
237
|
-
candidate_schema = branch_schema.duplicate()
|
|
238
|
-
candidate_schema.load_schema(schema=SchemaRoot(**internal_schema))
|
|
239
|
-
candidate_schema.load_schema(schema=SchemaRoot(**core_models))
|
|
240
|
-
candidate_schema.load_schema(schema=SchemaRoot(**deprecated_models))
|
|
241
|
-
candidate_schema.process()
|
|
242
|
-
|
|
243
|
-
schema_diff = branch_schema.diff(other=candidate_schema)
|
|
244
|
-
branch_schema.validate_node_deletions(diff=schema_diff)
|
|
245
|
-
result = branch_schema.validate_update(
|
|
246
|
-
other=candidate_schema, diff=schema_diff, enforce_update_support=False
|
|
247
|
-
)
|
|
248
|
-
if result.errors:
|
|
249
|
-
rprint(f"{error_badge} | Unable to update the schema, due to failed validations")
|
|
250
|
-
for error in result.errors:
|
|
251
|
-
rprint(error.to_string())
|
|
252
|
-
raise typer.Exit(1)
|
|
253
|
-
|
|
254
|
-
if not result.diff.all:
|
|
255
|
-
await create_defaults(db=db)
|
|
256
|
-
rprint("Core Schema Up to date, nothing to update")
|
|
257
|
-
raise typer.Exit(0)
|
|
258
|
-
|
|
259
|
-
rprint("Core Schema has diff, will need to be updated")
|
|
260
|
-
if debug:
|
|
261
|
-
result.diff.print()
|
|
262
|
-
|
|
263
|
-
# ----------------------------------------------------------
|
|
264
|
-
# Validate if the new schema is valid with the content of the database
|
|
265
|
-
# ----------------------------------------------------------
|
|
266
|
-
validate_migration_data = SchemaValidateMigrationData(
|
|
267
|
-
branch=default_branch,
|
|
268
|
-
schema_branch=candidate_schema,
|
|
269
|
-
constraints=result.constraints,
|
|
270
|
-
)
|
|
271
|
-
responses = await schema_validate_migrations(message=validate_migration_data, service=service)
|
|
272
|
-
error_messages = [violation.message for response in responses for violation in response.violations]
|
|
273
|
-
if error_messages:
|
|
274
|
-
rprint(f"{error_badge} | Unable to update the schema, due to failed validations")
|
|
275
|
-
for message in error_messages:
|
|
276
|
-
rprint(message)
|
|
277
|
-
raise typer.Exit(1)
|
|
278
|
-
|
|
279
|
-
# ----------------------------------------------------------
|
|
280
|
-
# Update the schema
|
|
281
|
-
# ----------------------------------------------------------
|
|
282
|
-
origin_schema = branch_schema.duplicate()
|
|
283
|
-
|
|
284
|
-
# Update the internal schema
|
|
285
|
-
schema_default_branch.load_schema(schema=SchemaRoot(**internal_schema))
|
|
286
|
-
schema_default_branch.process()
|
|
287
|
-
registry.schema.set_schema_branch(name=default_branch.name, schema=schema_default_branch)
|
|
288
|
-
|
|
289
|
-
async with db.start_transaction() as dbt:
|
|
290
|
-
await registry.schema.update_schema_branch(
|
|
291
|
-
schema=candidate_schema,
|
|
292
|
-
db=dbt,
|
|
293
|
-
branch=default_branch.name,
|
|
294
|
-
diff=result.diff,
|
|
295
|
-
limit=result.diff.all,
|
|
296
|
-
update_db=True,
|
|
297
|
-
)
|
|
298
|
-
default_branch.update_schema_hash()
|
|
299
|
-
rprint("The Core Schema has been updated")
|
|
300
|
-
if debug:
|
|
301
|
-
rprint(f"New schema hash: {default_branch.active_schema_hash.main}")
|
|
302
|
-
await default_branch.save(db=dbt)
|
|
303
|
-
|
|
304
|
-
# ----------------------------------------------------------
|
|
305
|
-
# Run the migrations
|
|
306
|
-
# ----------------------------------------------------------
|
|
307
|
-
apply_migration_data = SchemaApplyMigrationData(
|
|
308
|
-
branch=default_branch,
|
|
309
|
-
new_schema=candidate_schema,
|
|
310
|
-
previous_schema=origin_schema,
|
|
311
|
-
migrations=result.migrations,
|
|
312
|
-
)
|
|
313
|
-
migration_error_msgs = await schema_apply_migrations(message=apply_migration_data, service=service)
|
|
314
|
-
|
|
315
|
-
if migration_error_msgs:
|
|
316
|
-
rprint(f"{error_badge} | Some error(s) happened while running the schema migrations")
|
|
317
|
-
for message in migration_error_msgs:
|
|
318
|
-
rprint(message)
|
|
319
|
-
raise typer.Exit(1)
|
|
320
|
-
|
|
321
|
-
await create_defaults(db=db)
|
|
177
|
+
with prefect_test_harness():
|
|
178
|
+
await update_core_schema(db=dbdriver, service=service, initialize=True, debug=debug)
|
|
179
|
+
|
|
180
|
+
await dbdriver.close()
|
|
322
181
|
|
|
323
182
|
|
|
324
183
|
@app.command()
|
|
@@ -333,7 +192,7 @@ async def constraint(
|
|
|
333
192
|
context: CliContext = ctx.obj
|
|
334
193
|
dbdriver = await context.init_db(retry=1)
|
|
335
194
|
|
|
336
|
-
manager:
|
|
195
|
+
manager: ConstraintManagerBase | None = None
|
|
337
196
|
if dbdriver.db_type == DatabaseType.NEO4J:
|
|
338
197
|
manager = ConstraintManagerNeo4j.from_graph_schema(db=dbdriver, schema=GRAPH_SCHEMA)
|
|
339
198
|
elif dbdriver.db_type == DatabaseType.MEMGRAPH:
|
|
@@ -405,35 +264,158 @@ async def index(
|
|
|
405
264
|
await dbdriver.close()
|
|
406
265
|
|
|
407
266
|
|
|
408
|
-
async def
|
|
409
|
-
"""
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
267
|
+
async def migrate_database(db: InfrahubDatabase, initialize: bool = False, check: bool = False) -> None:
|
|
268
|
+
"""Apply the latest migrations to the database, this function will print the status directly in the console.
|
|
269
|
+
|
|
270
|
+
This function is expected to run on an empty
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
db: The database object.
|
|
274
|
+
check: If True, the function will only check the status of the database and not apply the migrations. Defaults to False.
|
|
275
|
+
"""
|
|
276
|
+
rprint("Checking current state of the Database")
|
|
277
|
+
|
|
278
|
+
if initialize:
|
|
279
|
+
await initialize_registry(db=db)
|
|
280
|
+
|
|
281
|
+
root_node = await get_root_node(db=db)
|
|
282
|
+
migrations = await get_graph_migrations(root=root_node)
|
|
283
|
+
|
|
284
|
+
if not migrations:
|
|
285
|
+
rprint(f"Database up-to-date (v{root_node.graph_version}), no migration to execute.")
|
|
286
|
+
return
|
|
417
287
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
db=db,
|
|
421
|
-
limit=1,
|
|
288
|
+
rprint(
|
|
289
|
+
f"Database needs to be updated (v{root_node.graph_version} -> v{GRAPH_VERSION}), {len(migrations)} migrations pending"
|
|
422
290
|
)
|
|
423
|
-
|
|
424
|
-
|
|
291
|
+
|
|
292
|
+
if check:
|
|
293
|
+
return
|
|
294
|
+
|
|
295
|
+
for migration in migrations:
|
|
296
|
+
execution_result = await migration.execute(db=db)
|
|
297
|
+
validation_result = None
|
|
298
|
+
|
|
299
|
+
if execution_result.success:
|
|
300
|
+
validation_result = await migration.validate_migration(db=db)
|
|
301
|
+
if validation_result.success:
|
|
302
|
+
rprint(f"Migration: {migration.name} {SUCCESS_BADGE}")
|
|
303
|
+
root_node.graph_version = migration.minimum_version + 1
|
|
304
|
+
await root_node.save(db=db)
|
|
305
|
+
|
|
306
|
+
if not execution_result.success or validation_result and not validation_result.success:
|
|
307
|
+
rprint(f"Migration: {migration.name} {FAILED_BADGE}")
|
|
308
|
+
for error in execution_result.errors:
|
|
309
|
+
rprint(f" {error}")
|
|
310
|
+
if validation_result and not validation_result.success:
|
|
311
|
+
for error in validation_result.errors:
|
|
312
|
+
rprint(f" {error}")
|
|
313
|
+
break
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
async def initialize_internal_schema() -> None:
|
|
317
|
+
registry.schema = SchemaManager()
|
|
318
|
+
schema = SchemaRoot(**internal_schema)
|
|
319
|
+
registry.schema.register_schema(schema=schema)
|
|
425
320
|
|
|
426
321
|
|
|
427
|
-
async def
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
322
|
+
async def update_core_schema(
|
|
323
|
+
db: InfrahubDatabase, service: InfrahubServices, initialize: bool = True, debug: bool = False
|
|
324
|
+
) -> None:
|
|
325
|
+
"""Update the core schema of Infrahub to the latest version"""
|
|
326
|
+
# ----------------------------------------------------------
|
|
327
|
+
# Initialize Schema and Registry
|
|
328
|
+
# ----------------------------------------------------------
|
|
329
|
+
if initialize:
|
|
330
|
+
await initialize_registry(db=db)
|
|
331
|
+
await initialize_internal_schema()
|
|
332
|
+
|
|
333
|
+
default_branch = registry.get_branch_from_registry(branch=registry.default_branch)
|
|
334
|
+
|
|
335
|
+
# ----------------------------------------------------------
|
|
336
|
+
# Load Current Schema from the database
|
|
337
|
+
# ----------------------------------------------------------
|
|
338
|
+
schema_default_branch = await registry.schema.load_schema_from_db(db=db, branch=default_branch)
|
|
339
|
+
registry.schema.set_schema_branch(name=default_branch.name, schema=schema_default_branch)
|
|
340
|
+
branch_schema = registry.schema.get_schema_branch(name=registry.default_branch)
|
|
341
|
+
|
|
342
|
+
candidate_schema = branch_schema.duplicate()
|
|
343
|
+
candidate_schema.load_schema(schema=SchemaRoot(**internal_schema))
|
|
344
|
+
candidate_schema.load_schema(schema=SchemaRoot(**core_models))
|
|
345
|
+
candidate_schema.load_schema(schema=SchemaRoot(**deprecated_models))
|
|
346
|
+
candidate_schema.process()
|
|
347
|
+
|
|
348
|
+
schema_diff = branch_schema.diff(other=candidate_schema)
|
|
349
|
+
branch_schema.validate_node_deletions(diff=schema_diff)
|
|
350
|
+
result = branch_schema.validate_update(other=candidate_schema, diff=schema_diff, enforce_update_support=False)
|
|
351
|
+
if result.errors:
|
|
352
|
+
rprint(f"{ERROR_BADGE} | Unable to update the schema, due to failed validations")
|
|
353
|
+
for error in result.errors:
|
|
354
|
+
rprint(error.to_string())
|
|
355
|
+
raise typer.Exit(1)
|
|
356
|
+
|
|
357
|
+
if not result.diff.all:
|
|
358
|
+
rprint("Core Schema Up to date, nothing to update")
|
|
359
|
+
return
|
|
360
|
+
|
|
361
|
+
rprint("Core Schema has diff, will need to be updated")
|
|
362
|
+
if debug:
|
|
363
|
+
result.diff.print()
|
|
364
|
+
|
|
365
|
+
# ----------------------------------------------------------
|
|
366
|
+
# Validate if the new schema is valid with the content of the database
|
|
367
|
+
# ----------------------------------------------------------
|
|
368
|
+
validate_migration_data = SchemaValidateMigrationData(
|
|
369
|
+
branch=default_branch,
|
|
370
|
+
schema_branch=candidate_schema,
|
|
371
|
+
constraints=result.constraints,
|
|
432
372
|
)
|
|
433
|
-
|
|
434
|
-
|
|
373
|
+
responses = await schema_validate_migrations(message=validate_migration_data, service=service)
|
|
374
|
+
error_messages = [violation.message for response in responses for violation in response.violations]
|
|
375
|
+
if error_messages:
|
|
376
|
+
rprint(f"{ERROR_BADGE} | Unable to update the schema, due to failed validations")
|
|
377
|
+
for message in error_messages:
|
|
378
|
+
rprint(message)
|
|
379
|
+
raise typer.Exit(1)
|
|
435
380
|
|
|
436
|
-
|
|
381
|
+
# ----------------------------------------------------------
|
|
382
|
+
# Update the schema
|
|
383
|
+
# ----------------------------------------------------------
|
|
384
|
+
origin_schema = branch_schema.duplicate()
|
|
385
|
+
|
|
386
|
+
# Update the internal schema
|
|
387
|
+
schema_default_branch.load_schema(schema=SchemaRoot(**internal_schema))
|
|
388
|
+
schema_default_branch.process()
|
|
389
|
+
registry.schema.set_schema_branch(name=default_branch.name, schema=schema_default_branch)
|
|
390
|
+
|
|
391
|
+
async with db.start_transaction() as dbt:
|
|
392
|
+
await registry.schema.update_schema_branch(
|
|
393
|
+
schema=candidate_schema,
|
|
394
|
+
db=dbt,
|
|
395
|
+
branch=default_branch.name,
|
|
396
|
+
diff=result.diff,
|
|
397
|
+
limit=result.diff.all,
|
|
398
|
+
update_db=True,
|
|
399
|
+
)
|
|
400
|
+
default_branch.update_schema_hash()
|
|
401
|
+
rprint("The Core Schema has been updated")
|
|
402
|
+
if debug:
|
|
403
|
+
rprint(f"New schema hash: {default_branch.active_schema_hash.main}")
|
|
404
|
+
await default_branch.save(db=dbt)
|
|
405
|
+
|
|
406
|
+
# ----------------------------------------------------------
|
|
407
|
+
# Run the migrations
|
|
408
|
+
# ----------------------------------------------------------
|
|
409
|
+
apply_migration_data = SchemaApplyMigrationData(
|
|
410
|
+
branch=default_branch,
|
|
411
|
+
new_schema=candidate_schema,
|
|
412
|
+
previous_schema=origin_schema,
|
|
413
|
+
migrations=result.migrations,
|
|
414
|
+
)
|
|
415
|
+
migration_error_msgs = await schema_apply_migrations(message=apply_migration_data, service=service)
|
|
437
416
|
|
|
438
|
-
if
|
|
439
|
-
|
|
417
|
+
if migration_error_msgs:
|
|
418
|
+
rprint(f"{ERROR_BADGE} | Some error(s) happened while running the schema migrations")
|
|
419
|
+
for message in migration_error_msgs:
|
|
420
|
+
rprint(message)
|
|
421
|
+
raise typer.Exit(1)
|