infrahub-server 1.1.9__py3-none-any.whl → 1.2.0__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 +14 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/oauth2.py +0 -1
- infrahub/api/oidc.py +0 -1
- infrahub/api/query.py +18 -7
- infrahub/api/schema.py +33 -7
- infrahub/api/transformation.py +12 -5
- infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +6 -6
- infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +27 -28
- infrahub/cli/__init__.py +12 -10
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +166 -185
- infrahub/cli/events.py +8 -3
- infrahub/cli/git_agent.py +9 -7
- infrahub/cli/tasks.py +4 -6
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +174 -0
- infrahub/computed_attribute/models.py +202 -11
- infrahub/computed_attribute/tasks.py +103 -421
- infrahub/computed_attribute/triggers.py +56 -0
- infrahub/config.py +33 -33
- infrahub/context.py +53 -0
- infrahub/core/account.py +9 -12
- infrahub/core/attribute.py +104 -75
- infrahub/core/branch/models.py +4 -4
- infrahub/core/branch/tasks.py +133 -125
- infrahub/core/changelog/__init__.py +0 -0
- infrahub/core/changelog/diff.py +291 -0
- infrahub/core/changelog/models.py +662 -0
- infrahub/core/constants/__init__.py +47 -2
- infrahub/core/constants/infrahubkind.py +3 -0
- infrahub/core/constants/schema.py +2 -0
- infrahub/core/constraint/node/runner.py +2 -2
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/combiner.py +1 -1
- infrahub/core/diff/enricher/cardinality_one.py +1 -1
- infrahub/core/diff/enricher/hierarchy.py +5 -3
- infrahub/core/diff/enricher/labels.py +1 -1
- infrahub/core/diff/enricher/path_identifier.py +1 -2
- infrahub/core/diff/enricher/summary_counts.py +107 -0
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/merger/merger.py +3 -1
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +13 -13
- infrahub/core/diff/query/all_conflicts.py +1 -1
- infrahub/core/diff/query/artifact.py +1 -1
- infrahub/core/diff/query/delete_query.py +1 -1
- infrahub/core/diff/query/diff_get.py +1 -1
- infrahub/core/diff/query/diff_summary.py +1 -1
- infrahub/core/diff/query/field_specifiers.py +1 -1
- infrahub/core/diff/query/field_summary.py +1 -1
- infrahub/core/diff/query/filters.py +2 -2
- infrahub/core/diff/query/get_conflict_query.py +1 -1
- infrahub/core/diff/query/has_conflicts_query.py +1 -1
- infrahub/core/diff/query/merge.py +3 -3
- infrahub/core/diff/query/merge_tracking_id.py +1 -1
- infrahub/core/diff/query/roots_metadata.py +1 -1
- infrahub/core/diff/query/save.py +3 -3
- infrahub/core/diff/query/summary_counts_enricher.py +2 -2
- infrahub/core/diff/query/time_range_query.py +1 -1
- infrahub/core/diff/query/update_conflict_query.py +1 -1
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/diff/repository/deserializer.py +1 -1
- infrahub/core/diff/tasks.py +9 -8
- infrahub/core/enums.py +1 -1
- infrahub/core/initialization.py +1 -10
- infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +13 -13
- infrahub/core/ipam/tasks.py +2 -3
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +52 -47
- infrahub/core/merge.py +12 -9
- infrahub/core/migrations/__init__.py +1 -3
- infrahub/core/migrations/graph/__init__.py +5 -3
- 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 +2 -6
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +3 -3
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +4 -4
- infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -3
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +2 -2
- infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
- infrahub/core/migrations/query/attribute_add.py +3 -3
- 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 +3 -3
- infrahub/core/migrations/schema/models.py +19 -4
- 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 +7 -7
- infrahub/core/migrations/shared.py +10 -12
- infrahub/core/models.py +13 -14
- infrahub/core/node/__init__.py +172 -57
- infrahub/core/node/base.py +3 -5
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +5 -5
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +7 -9
- infrahub/core/node/ipam.py +10 -10
- 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 +14 -11
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/node/standard.py +3 -5
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +12 -12
- infrahub/core/protocols.py +11 -0
- infrahub/core/protocols_base.py +25 -23
- infrahub/core/query/__init__.py +35 -38
- infrahub/core/query/attribute.py +13 -13
- infrahub/core/query/branch.py +5 -5
- infrahub/core/query/delete.py +1 -1
- infrahub/core/query/diff.py +7 -7
- infrahub/core/query/ipam.py +4 -4
- infrahub/core/query/node.py +23 -24
- infrahub/core/query/relationship.py +143 -46
- infrahub/core/query/resource_manager.py +10 -10
- infrahub/core/query/standard_node.py +9 -9
- infrahub/core/query/subquery.py +9 -9
- 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 +13 -17
- infrahub/core/relationship/constraints/count.py +4 -5
- infrahub/core/relationship/constraints/peer_kind.py +4 -5
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +103 -67
- infrahub/core/schema/__init__.py +6 -4
- infrahub/core/schema/attribute_schema.py +16 -8
- infrahub/core/schema/basenode_schema.py +38 -26
- 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 +32 -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/genericnode_schema.py +5 -0
- infrahub/core/schema/generated/node_schema.py +8 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +6 -2
- infrahub/core/schema/manager.py +46 -43
- infrahub/core/schema/node_schema.py +6 -2
- infrahub/core/schema/profile_schema.py +4 -0
- infrahub/core/schema/relationship_schema.py +15 -7
- infrahub/core/schema/schema_branch.py +423 -89
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/schema/template_schema.py +36 -0
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +21 -19
- infrahub/core/timestamp.py +3 -3
- infrahub/core/utils.py +12 -12
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +3 -3
- infrahub/core/validators/attribute/enum.py +3 -3
- infrahub/core/validators/attribute/kind.py +3 -3
- infrahub/core/validators/attribute/length.py +3 -3
- infrahub/core/validators/attribute/optional.py +3 -3
- infrahub/core/validators/attribute/regex.py +3 -3
- infrahub/core/validators/attribute/unique.py +3 -3
- infrahub/core/validators/checks_runner.py +60 -0
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/model.py +1 -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 +3 -3
- infrahub/core/validators/node/hierarchy.py +3 -3
- infrahub/core/validators/node/inherit_from.py +2 -2
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/query.py +1 -1
- infrahub/core/validators/relationship/count.py +5 -5
- infrahub/core/validators/relationship/optional.py +3 -3
- infrahub/core/validators/relationship/peer.py +3 -3
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -6
- infrahub/core/validators/uniqueness/checker.py +5 -6
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/core/validators/uniqueness/query.py +1 -1
- infrahub/database/__init__.py +19 -23
- infrahub/database/memgraph.py +1 -1
- infrahub/dependencies/builder/diff/combiner.py +1 -1
- infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/builder/diff/enricher/summary_counts.py +8 -0
- infrahub/dependencies/builder/diff/parent_node_adder.py +1 -1
- 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 +57 -20
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +103 -0
- infrahub/events/models.py +160 -53
- infrahub/events/node_action.py +140 -23
- infrahub/events/repository_action.py +7 -20
- infrahub/events/schema_action.py +18 -10
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +12 -3
- infrahub/generators/models.py +2 -3
- infrahub/generators/tasks.py +34 -15
- infrahub/git/base.py +10 -12
- infrahub/git/constants.py +0 -1
- infrahub/git/integrator.py +82 -57
- infrahub/git/models.py +101 -9
- infrahub/git/repository.py +9 -10
- infrahub/git/tasks.py +450 -112
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/git_credential/helper.py +2 -3
- infrahub/graphql/analyzer.py +572 -11
- infrahub/graphql/app.py +47 -41
- 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/context.py +39 -0
- infrahub/graphql/enums.py +1 -1
- infrahub/graphql/initialization.py +5 -1
- infrahub/graphql/loaders/node.py +1 -1
- infrahub/graphql/loaders/shared.py +1 -1
- infrahub/graphql/manager.py +75 -72
- infrahub/graphql/mutations/account.py +20 -13
- infrahub/graphql/mutations/artifact_definition.py +18 -14
- infrahub/graphql/mutations/branch.py +86 -40
- infrahub/graphql/mutations/computed_attribute.py +26 -18
- infrahub/graphql/mutations/diff.py +17 -8
- infrahub/graphql/mutations/diff_conflict.py +14 -8
- infrahub/graphql/mutations/generator.py +83 -0
- infrahub/graphql/mutations/graphql_query.py +21 -13
- infrahub/graphql/mutations/ipam.py +41 -39
- infrahub/graphql/mutations/main.py +226 -66
- infrahub/graphql/mutations/menu.py +12 -12
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +1 -3
- 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 +39 -31
- infrahub/graphql/mutations/relationship.py +372 -129
- infrahub/graphql/mutations/repository.py +46 -40
- infrahub/graphql/mutations/resource_manager.py +26 -26
- infrahub/graphql/mutations/schema.py +70 -37
- infrahub/graphql/mutations/tasks.py +10 -7
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +5 -5
- infrahub/graphql/permissions.py +3 -10
- infrahub/graphql/queries/account.py +22 -18
- infrahub/graphql/queries/branch.py +6 -4
- infrahub/graphql/queries/diff/tree.py +67 -56
- infrahub/graphql/queries/event.py +115 -0
- infrahub/graphql/queries/internal.py +3 -3
- infrahub/graphql/queries/ipam.py +25 -20
- infrahub/graphql/queries/relationship.py +13 -12
- infrahub/graphql/queries/resource_manager.py +37 -25
- infrahub/graphql/queries/search.py +11 -10
- infrahub/graphql/queries/status.py +12 -9
- infrahub/graphql/queries/task.py +11 -9
- infrahub/graphql/resolvers/many_relationship.py +15 -15
- infrahub/graphql/resolvers/resolver.py +58 -37
- infrahub/graphql/resolvers/single_relationship.py +16 -10
- infrahub/graphql/schema.py +4 -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/context.py +12 -0
- infrahub/graphql/types/enums.py +2 -0
- infrahub/graphql/types/event.py +167 -0
- infrahub/graphql/types/interface.py +2 -2
- infrahub/graphql/types/node.py +5 -5
- 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 +30 -184
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/groups/tasks.py +2 -3
- infrahub/lock.py +21 -21
- infrahub/menu/generator.py +7 -8
- infrahub/menu/menu.py +107 -139
- infrahub/menu/models.py +121 -20
- 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 -25
- infrahub/message_bus/messages/check_generator_run.py +3 -3
- infrahub/message_bus/messages/event_branch_merge.py +3 -0
- 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/request_proposedchange_pipeline.py +2 -0
- infrahub/message_bus/messages/send_echo_request.py +1 -1
- infrahub/message_bus/operations/__init__.py +4 -15
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +2 -3
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/event/branch.py +7 -3
- infrahub/message_bus/operations/event/worker.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +52 -2
- 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 -4
- infrahub/message_bus/operations/requests/generator_definition.py +22 -24
- infrahub/message_bus/operations/requests/proposed_change.py +39 -20
- infrahub/message_bus/operations/send/echo.py +1 -1
- infrahub/message_bus/types.py +1 -1
- infrahub/permissions/globals.py +15 -0
- infrahub/pools/number.py +2 -4
- 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 +18 -1
- infrahub/proposed_change/tasks.py +204 -53
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +13 -12
- infrahub/services/__init__.py +148 -63
- infrahub/services/adapters/cache/__init__.py +11 -11
- infrahub/services/adapters/cache/nats.py +42 -25
- infrahub/services/adapters/cache/redis.py +3 -11
- infrahub/services/adapters/event/__init__.py +11 -19
- infrahub/services/adapters/http/__init__.py +0 -5
- infrahub/services/adapters/http/httpx.py +22 -15
- infrahub/services/adapters/message_bus/__init__.py +25 -8
- infrahub/services/adapters/message_bus/local.py +9 -7
- infrahub/services/adapters/message_bus/nats.py +14 -8
- infrahub/services/adapters/message_bus/rabbitmq.py +23 -10
- infrahub/services/adapters/workflow/__init__.py +11 -8
- infrahub/services/adapters/workflow/local.py +27 -6
- infrahub/services/adapters/workflow/worker.py +23 -7
- infrahub/services/component.py +43 -40
- infrahub/services/protocols.py +7 -7
- infrahub/services/scheduler.py +30 -29
- infrahub/storage.py +2 -4
- infrahub/task_manager/constants.py +1 -1
- infrahub/task_manager/event.py +275 -0
- infrahub/task_manager/models.py +147 -3
- infrahub/task_manager/task.py +1 -1
- infrahub/tasks/artifact.py +20 -21
- infrahub/tasks/registry.py +1 -1
- 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/telemetry/tasks.py +119 -0
- infrahub/telemetry/utils.py +11 -0
- infrahub/transformations/tasks.py +5 -7
- infrahub/trigger/__init__.py +0 -0
- infrahub/trigger/catalogue.py +13 -0
- infrahub/trigger/constants.py +1 -0
- infrahub/trigger/models.py +118 -0
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +36 -0
- infrahub/types.py +1 -1
- infrahub/utils.py +12 -2
- 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 +180 -42
- infrahub/webhook/tasks.py +149 -203
- infrahub/webhook/triggers.py +44 -0
- infrahub/workers/infrahub_async.py +38 -27
- infrahub/workers/utils.py +63 -0
- infrahub/workflows/catalogue.py +98 -71
- infrahub/workflows/initialization.py +12 -8
- infrahub/workflows/models.py +29 -5
- infrahub/workflows/utils.py +11 -2
- infrahub_sdk/client.py +19 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/utils.py +0 -16
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +3 -0
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +66 -20
- infrahub_sdk/protocols.py +21 -8
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/schema/__init__.py +14 -2
- infrahub_sdk/schema/main.py +7 -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/timestamp.py +142 -33
- infrahub_sdk/utils.py +29 -1
- {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/METADATA +8 -6
- infrahub_server-1.2.0.dist-info/RECORD +746 -0
- infrahub_testcontainers/container.py +5 -6
- infrahub_testcontainers/docker-compose.test.yml +2 -2
- infrahub_testcontainers/helpers.py +5 -1
- infrahub/core/branch/constants.py +0 -2
- infrahub/core/schema/definitions/core.py +0 -2275
- infrahub/graphql/query.py +0 -52
- 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_artifactdefinition_check.py +0 -17
- 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/artifact_definition.py +0 -148
- infrahub/message_bus/operations/requests/repository.py +0 -133
- infrahub/schema/constants.py +0 -1
- infrahub/schema/tasks.py +0 -76
- infrahub/services/adapters/database/__init__.py +0 -9
- infrahub/tasks/telemetry.py +0 -127
- infrahub/webhook/constants.py +0 -3
- infrahub_server-1.1.9.dist-info/RECORD +0 -688
- /infrahub/{schema → artifacts}/__init__.py +0 -0
- {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.1.9.dist-info → infrahub_server-1.2.0.dist-info}/entry_points.txt +0 -0
|
@@ -7,7 +7,7 @@ from pathlib import Path
|
|
|
7
7
|
from typing import TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
import pytest
|
|
10
|
-
from infrahub_sdk.protocols import CoreGeneratorDefinition, CoreProposedChange
|
|
10
|
+
from infrahub_sdk.protocols import CoreArtifactValidator, CoreGeneratorDefinition, CoreProposedChange
|
|
11
11
|
from prefect import flow, task
|
|
12
12
|
from prefect.cache_policies import NONE
|
|
13
13
|
from prefect.client.schemas.objects import (
|
|
@@ -17,6 +17,8 @@ from prefect.logging import get_run_logger
|
|
|
17
17
|
from prefect.states import Completed, Failed
|
|
18
18
|
|
|
19
19
|
from infrahub import config
|
|
20
|
+
from infrahub.artifacts.models import CheckArtifactCreate
|
|
21
|
+
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
|
|
20
22
|
from infrahub.core import registry
|
|
21
23
|
from infrahub.core.branch import Branch
|
|
22
24
|
from infrahub.core.branch.tasks import merge_branch
|
|
@@ -27,18 +29,21 @@ from infrahub.core.diff.model.path import NodeDiffFieldSummary
|
|
|
27
29
|
from infrahub.core.integrity.object_conflict.conflict_recorder import ObjectConflictValidatorRecorder
|
|
28
30
|
from infrahub.core.protocols import CoreDataCheck, CoreValidator
|
|
29
31
|
from infrahub.core.protocols import CoreProposedChange as InternalCoreProposedChange
|
|
32
|
+
from infrahub.core.validators.checks_runner import run_checks_and_update_validator
|
|
30
33
|
from infrahub.core.validators.determiner import ConstraintValidatorDeterminer
|
|
31
34
|
from infrahub.core.validators.models.validate_migration import SchemaValidateMigrationData
|
|
32
35
|
from infrahub.core.validators.tasks import schema_validate_migrations
|
|
33
36
|
from infrahub.dependencies.registry import get_component_registry
|
|
34
37
|
from infrahub.exceptions import MergeFailedError
|
|
35
38
|
from infrahub.generators.models import ProposedChangeGeneratorDefinition
|
|
39
|
+
from infrahub.git.models import TriggerRepositoryInternalChecks, TriggerRepositoryUserChecks
|
|
36
40
|
from infrahub.git.repository import get_initialized_repo
|
|
37
41
|
from infrahub.log import get_logger
|
|
38
42
|
from infrahub.message_bus import InfrahubMessage, messages
|
|
39
43
|
from infrahub.message_bus.operations.requests.proposed_change import DefinitionSelect
|
|
40
44
|
from infrahub.proposed_change.constants import ProposedChangeState
|
|
41
45
|
from infrahub.proposed_change.models import (
|
|
46
|
+
RequestArtifactDefinitionCheck,
|
|
42
47
|
RequestProposedChangeDataIntegrity,
|
|
43
48
|
RequestProposedChangeRepositoryChecks,
|
|
44
49
|
RequestProposedChangeRunGenerators,
|
|
@@ -46,8 +51,14 @@ from infrahub.proposed_change.models import (
|
|
|
46
51
|
RequestProposedChangeUserTests,
|
|
47
52
|
)
|
|
48
53
|
from infrahub.pytest_plugin import InfrahubBackendPlugin
|
|
49
|
-
from infrahub.services import
|
|
50
|
-
from infrahub.
|
|
54
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
55
|
+
from infrahub.validators.tasks import start_validator
|
|
56
|
+
from infrahub.workflows.catalogue import (
|
|
57
|
+
GIT_REPOSITORIES_CHECK_ARTIFACT_CREATE,
|
|
58
|
+
GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER,
|
|
59
|
+
GIT_REPOSITORY_USER_CHECKS_TRIGGER,
|
|
60
|
+
REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
61
|
+
)
|
|
51
62
|
from infrahub.workflows.utils import add_tags
|
|
52
63
|
|
|
53
64
|
if TYPE_CHECKING:
|
|
@@ -60,10 +71,10 @@ if TYPE_CHECKING:
|
|
|
60
71
|
|
|
61
72
|
async def _proposed_change_transition_state(
|
|
62
73
|
state: ProposedChangeState,
|
|
74
|
+
service: InfrahubServices,
|
|
63
75
|
proposed_change: InternalCoreProposedChange | None = None,
|
|
64
76
|
proposed_change_id: str | None = None,
|
|
65
77
|
) -> None:
|
|
66
|
-
service = services.service
|
|
67
78
|
async with service.database.start_session() as db:
|
|
68
79
|
if proposed_change is None and proposed_change_id:
|
|
69
80
|
proposed_change = await registry.manager.get_one(
|
|
@@ -96,8 +107,12 @@ async def _proposed_change_transition_state(
|
|
|
96
107
|
# on_crashed=[proposed_change_transition_open], # type: ignore
|
|
97
108
|
# on_cancellation=[proposed_change_transition_open], # type: ignore
|
|
98
109
|
)
|
|
99
|
-
async def merge_proposed_change(
|
|
100
|
-
|
|
110
|
+
async def merge_proposed_change(
|
|
111
|
+
proposed_change_id: str,
|
|
112
|
+
proposed_change_name: str, # noqa: ARG001
|
|
113
|
+
context: InfrahubContext,
|
|
114
|
+
service: InfrahubServices,
|
|
115
|
+
) -> State:
|
|
101
116
|
log = get_run_logger()
|
|
102
117
|
|
|
103
118
|
await add_tags(nodes=[proposed_change_id])
|
|
@@ -118,14 +133,16 @@ async def merge_proposed_change(proposed_change_id: str, proposed_change_name: s
|
|
|
118
133
|
and validation.conclusion.value.value != ValidatorConclusion.SUCCESS.value
|
|
119
134
|
):
|
|
120
135
|
# Ignoring Data integrity checks as they are handled again later
|
|
121
|
-
await _proposed_change_transition_state(
|
|
136
|
+
await _proposed_change_transition_state(
|
|
137
|
+
proposed_change=proposed_change, state=ProposedChangeState.OPEN, service=service
|
|
138
|
+
)
|
|
122
139
|
return Failed(message="Unable to merge proposed change containing failing checks")
|
|
123
140
|
if validator_kind == InfrahubKind.DATAVALIDATOR:
|
|
124
141
|
data_checks = await validation.checks.get_peers(db=db, peer_type=CoreDataCheck)
|
|
125
142
|
for check in data_checks.values():
|
|
126
143
|
if check.conflicts.value and not check.keep_branch.value:
|
|
127
144
|
await _proposed_change_transition_state(
|
|
128
|
-
proposed_change=proposed_change, state=ProposedChangeState.OPEN
|
|
145
|
+
proposed_change=proposed_change, state=ProposedChangeState.OPEN, service=service
|
|
129
146
|
)
|
|
130
147
|
return Failed(
|
|
131
148
|
message="Data conflicts found on branch and missing decisions about what branch to keep"
|
|
@@ -133,15 +150,20 @@ async def merge_proposed_change(proposed_change_id: str, proposed_change_name: s
|
|
|
133
150
|
|
|
134
151
|
log.info("Proposed change is eligible to be merged")
|
|
135
152
|
try:
|
|
136
|
-
await merge_branch(
|
|
153
|
+
await merge_branch(
|
|
154
|
+
branch=source_branch.name, context=context, service=service, proposed_change_id=proposed_change_id
|
|
155
|
+
)
|
|
137
156
|
except MergeFailedError as exc:
|
|
138
|
-
await _proposed_change_transition_state(
|
|
157
|
+
await _proposed_change_transition_state(
|
|
158
|
+
proposed_change=proposed_change, state=ProposedChangeState.OPEN, service=service
|
|
159
|
+
)
|
|
139
160
|
return Failed(message=f"Merge failure when trying to merge {exc.message}")
|
|
140
161
|
|
|
141
162
|
log.info(f"Branch {source_branch.name} has been merged successfully")
|
|
142
163
|
|
|
143
|
-
await _proposed_change_transition_state(
|
|
144
|
-
|
|
164
|
+
await _proposed_change_transition_state(
|
|
165
|
+
proposed_change=proposed_change, state=ProposedChangeState.MERGED, service=service
|
|
166
|
+
)
|
|
145
167
|
return Completed(message="proposed change merged successfully")
|
|
146
168
|
|
|
147
169
|
|
|
@@ -150,9 +172,7 @@ async def merge_proposed_change(proposed_change_id: str, proposed_change_name: s
|
|
|
150
172
|
flow_run_name="Cancel all proposed change associated with branch {branch_name}",
|
|
151
173
|
description="Cancel all Proposed change associated with a branch.",
|
|
152
174
|
)
|
|
153
|
-
async def cancel_proposed_changes_branch(branch_name: str) -> None:
|
|
154
|
-
service = services.service
|
|
155
|
-
|
|
175
|
+
async def cancel_proposed_changes_branch(branch_name: str, service: InfrahubServices) -> None:
|
|
156
176
|
await add_tags(branches=[branch_name])
|
|
157
177
|
|
|
158
178
|
proposed_changed_opened = await service.client.filters(
|
|
@@ -169,13 +189,11 @@ async def cancel_proposed_changes_branch(branch_name: str) -> None:
|
|
|
169
189
|
)
|
|
170
190
|
|
|
171
191
|
for proposed_change in proposed_changed_opened + proposed_changed_closed:
|
|
172
|
-
await cancel_proposed_change(proposed_change=proposed_change)
|
|
192
|
+
await cancel_proposed_change(proposed_change=proposed_change, service=service)
|
|
173
193
|
|
|
174
194
|
|
|
175
|
-
@task(name="Cancel a propose change", description="Cancel a propose change", cache_policy=NONE)
|
|
176
|
-
async def cancel_proposed_change(proposed_change: CoreProposedChange) -> None:
|
|
177
|
-
service = services.service
|
|
178
|
-
|
|
195
|
+
@task(name="Cancel a propose change", description="Cancel a propose change", cache_policy=NONE) # type: ignore[arg-type]
|
|
196
|
+
async def cancel_proposed_change(proposed_change: CoreProposedChange, service: InfrahubServices) -> None:
|
|
179
197
|
await add_tags(nodes=[proposed_change.id])
|
|
180
198
|
log = get_run_logger()
|
|
181
199
|
|
|
@@ -189,11 +207,12 @@ async def cancel_proposed_change(proposed_change: CoreProposedChange) -> None:
|
|
|
189
207
|
name="proposed-changed-data-integrity",
|
|
190
208
|
flow_run_name="Triggers data integrity check",
|
|
191
209
|
)
|
|
192
|
-
async def run_proposed_change_data_integrity_check(
|
|
210
|
+
async def run_proposed_change_data_integrity_check(
|
|
211
|
+
model: RequestProposedChangeDataIntegrity, service: InfrahubServices
|
|
212
|
+
) -> None:
|
|
193
213
|
"""Triggers a data integrity validation check on the provided proposed change to start."""
|
|
194
214
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
|
|
195
215
|
|
|
196
|
-
service = services.service
|
|
197
216
|
async with service.database.start_transaction() as dbt:
|
|
198
217
|
destination_branch = await registry.get_branch(db=dbt, branch=model.destination_branch)
|
|
199
218
|
source_branch = await registry.get_branch(db=dbt, branch=model.source_branch)
|
|
@@ -207,8 +226,9 @@ async def run_proposed_change_data_integrity_check(model: RequestProposedChangeD
|
|
|
207
226
|
name="proposed-changed-run-generator",
|
|
208
227
|
flow_run_name="Run generators",
|
|
209
228
|
)
|
|
210
|
-
async def run_generators(
|
|
211
|
-
|
|
229
|
+
async def run_generators(
|
|
230
|
+
model: RequestProposedChangeRunGenerators, context: InfrahubContext, service: InfrahubServices
|
|
231
|
+
) -> None:
|
|
212
232
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change], db_change=True)
|
|
213
233
|
|
|
214
234
|
generators = await service.client.filters(
|
|
@@ -256,6 +276,7 @@ async def run_generators(model: RequestProposedChangeRunGenerators) -> None:
|
|
|
256
276
|
|
|
257
277
|
if select:
|
|
258
278
|
msg = messages.RequestGeneratorDefinitionCheck(
|
|
279
|
+
context=context,
|
|
259
280
|
generator_definition=generator_definition,
|
|
260
281
|
branch_diff=model.branch_diff,
|
|
261
282
|
proposed_change=model.proposed_change,
|
|
@@ -264,12 +285,13 @@ async def run_generators(model: RequestProposedChangeRunGenerators) -> None:
|
|
|
264
285
|
destination_branch=model.destination_branch,
|
|
265
286
|
)
|
|
266
287
|
msg.assign_meta(parent=model)
|
|
267
|
-
await service.send(message=msg)
|
|
288
|
+
await service.message_bus.send(message=msg)
|
|
268
289
|
|
|
269
290
|
next_messages: list[InfrahubMessage] = []
|
|
270
291
|
if model.refresh_artifacts:
|
|
271
292
|
next_messages.append(
|
|
272
293
|
messages.RequestProposedChangeRefreshArtifacts(
|
|
294
|
+
context=context,
|
|
273
295
|
proposed_change=model.proposed_change,
|
|
274
296
|
source_branch=model.source_branch,
|
|
275
297
|
source_branch_sync_with_git=model.source_branch_sync_with_git,
|
|
@@ -287,12 +309,14 @@ async def run_generators(model: RequestProposedChangeRunGenerators) -> None:
|
|
|
287
309
|
branch_diff=model.branch_diff,
|
|
288
310
|
)
|
|
289
311
|
await service.workflow.submit_workflow(
|
|
290
|
-
workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
312
|
+
workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
313
|
+
context=context,
|
|
314
|
+
parameters={"model": model_proposed_change_repo_checks},
|
|
291
315
|
)
|
|
292
316
|
|
|
293
317
|
for next_msg in next_messages:
|
|
294
318
|
next_msg.assign_meta(parent=model)
|
|
295
|
-
await service.send(message=next_msg)
|
|
319
|
+
await service.message_bus.send(message=next_msg)
|
|
296
320
|
|
|
297
321
|
|
|
298
322
|
@flow(
|
|
@@ -300,11 +324,10 @@ async def run_generators(model: RequestProposedChangeRunGenerators) -> None:
|
|
|
300
324
|
flow_run_name="Process schema integrity",
|
|
301
325
|
)
|
|
302
326
|
async def run_proposed_change_schema_integrity_check(
|
|
303
|
-
model: RequestProposedChangeSchemaIntegrity,
|
|
327
|
+
model: RequestProposedChangeSchemaIntegrity, service: InfrahubServices
|
|
304
328
|
) -> None:
|
|
305
329
|
# For now, we retrieve the latest schema for each branch from the registry
|
|
306
330
|
# In the future it would be good to generate the object SchemaUpdateValidationResult from message.branch_diff
|
|
307
|
-
service = services.service
|
|
308
331
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
|
|
309
332
|
|
|
310
333
|
source_schema = registry.schema.get_schema_branch(name=model.source_branch).duplicate()
|
|
@@ -331,7 +354,8 @@ async def run_proposed_change_schema_integrity_check(
|
|
|
331
354
|
responses = await schema_validate_migrations(
|
|
332
355
|
message=SchemaValidateMigrationData(
|
|
333
356
|
branch=source_branch, schema_branch=candidate_schema, constraints=list(constraints)
|
|
334
|
-
)
|
|
357
|
+
),
|
|
358
|
+
service=service,
|
|
335
359
|
)
|
|
336
360
|
|
|
337
361
|
# TODO we need to report a failure if an error happened during the execution of a validator
|
|
@@ -393,48 +417,50 @@ async def _get_proposed_change_schema_integrity_constraints(
|
|
|
393
417
|
name="proposed-changed-repository-checks",
|
|
394
418
|
flow_run_name="Process user defined checks",
|
|
395
419
|
)
|
|
396
|
-
async def repository_checks(
|
|
397
|
-
service
|
|
420
|
+
async def repository_checks(
|
|
421
|
+
model: RequestProposedChangeRepositoryChecks, service: InfrahubServices, context: InfrahubContext
|
|
422
|
+
) -> None:
|
|
398
423
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
|
|
399
424
|
|
|
400
|
-
events: list[InfrahubMessage] = []
|
|
401
425
|
for repository in model.branch_diff.repositories:
|
|
402
426
|
if (
|
|
403
427
|
model.source_branch_sync_with_git
|
|
404
428
|
and not repository.read_only
|
|
405
429
|
and repository.internal_status == RepositoryInternalStatus.ACTIVE.value
|
|
406
430
|
):
|
|
407
|
-
|
|
408
|
-
messages.RequestRepositoryChecks(
|
|
409
|
-
proposed_change=model.proposed_change,
|
|
410
|
-
repository=repository.repository_id,
|
|
411
|
-
source_branch=model.source_branch,
|
|
412
|
-
target_branch=model.destination_branch,
|
|
413
|
-
)
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
events.append(
|
|
417
|
-
messages.RequestRepositoryUserChecks(
|
|
431
|
+
trigger_internal_checks_model = TriggerRepositoryInternalChecks(
|
|
418
432
|
proposed_change=model.proposed_change,
|
|
419
|
-
|
|
420
|
-
repository_name=repository.repository_name,
|
|
433
|
+
repository=repository.repository_id,
|
|
421
434
|
source_branch=model.source_branch,
|
|
422
|
-
source_branch_sync_with_git=model.source_branch_sync_with_git,
|
|
423
435
|
target_branch=model.destination_branch,
|
|
424
|
-
branch_diff=model.branch_diff,
|
|
425
436
|
)
|
|
437
|
+
await service.workflow.submit_workflow(
|
|
438
|
+
workflow=GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER,
|
|
439
|
+
context=context,
|
|
440
|
+
parameters={"model": trigger_internal_checks_model},
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
trigger_user_checks_model = TriggerRepositoryUserChecks(
|
|
444
|
+
proposed_change=model.proposed_change,
|
|
445
|
+
repository_id=repository.repository_id,
|
|
446
|
+
repository_name=repository.repository_name,
|
|
447
|
+
source_branch=model.source_branch,
|
|
448
|
+
source_branch_sync_with_git=model.source_branch_sync_with_git,
|
|
449
|
+
target_branch=model.destination_branch,
|
|
450
|
+
branch_diff=model.branch_diff,
|
|
451
|
+
)
|
|
452
|
+
await service.workflow.submit_workflow(
|
|
453
|
+
workflow=GIT_REPOSITORY_USER_CHECKS_TRIGGER,
|
|
454
|
+
context=context,
|
|
455
|
+
parameters={"model": trigger_user_checks_model},
|
|
426
456
|
)
|
|
427
|
-
for event in events:
|
|
428
|
-
event.assign_meta(parent=model)
|
|
429
|
-
await service.send(message=event)
|
|
430
457
|
|
|
431
458
|
|
|
432
459
|
@flow(
|
|
433
460
|
name="proposed-changed-user-tests",
|
|
434
461
|
flow_run_name="Run unit tests in repositories",
|
|
435
462
|
)
|
|
436
|
-
async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests) -> None:
|
|
437
|
-
service = services.service
|
|
463
|
+
async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests, service: InfrahubServices) -> None:
|
|
438
464
|
log = get_run_logger()
|
|
439
465
|
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change])
|
|
440
466
|
proposed_change = await service.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
|
|
@@ -493,3 +519,128 @@ async def run_proposed_change_user_tests(model: RequestProposedChangeUserTests)
|
|
|
493
519
|
|
|
494
520
|
return_code = await asyncio.to_thread(_execute, worktree_directory, repository, proposed_change)
|
|
495
521
|
log.info(msg=f"repository_tests_completed return_code={return_code}")
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
@flow(
|
|
525
|
+
name="artifacts-generation-validation",
|
|
526
|
+
flow_run_name="Validating generation of artifacts for {model.artifact_definition.definition_name}",
|
|
527
|
+
)
|
|
528
|
+
async def validate_artifacts_generation(model: RequestArtifactDefinitionCheck, service: InfrahubServices) -> None:
|
|
529
|
+
await add_tags(branches=[model.source_branch], nodes=[model.proposed_change], db_change=True)
|
|
530
|
+
|
|
531
|
+
log = get_run_logger()
|
|
532
|
+
artifact_definition = await service.client.get(
|
|
533
|
+
kind=InfrahubKind.ARTIFACTDEFINITION,
|
|
534
|
+
id=model.artifact_definition.definition_id,
|
|
535
|
+
branch=model.source_branch,
|
|
536
|
+
)
|
|
537
|
+
proposed_change = await service.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=model.proposed_change)
|
|
538
|
+
|
|
539
|
+
validator_name = f"Artifact Validator: {model.artifact_definition.definition_name}"
|
|
540
|
+
|
|
541
|
+
await proposed_change.validations.fetch()
|
|
542
|
+
|
|
543
|
+
previous_validator: CoreArtifactValidator | None = None
|
|
544
|
+
for relationship in proposed_change.validations.peers:
|
|
545
|
+
existing_validator = relationship.peer
|
|
546
|
+
if (
|
|
547
|
+
existing_validator.typename == InfrahubKind.ARTIFACTVALIDATOR
|
|
548
|
+
and existing_validator.definition.id == model.artifact_definition.definition_id
|
|
549
|
+
):
|
|
550
|
+
previous_validator = existing_validator
|
|
551
|
+
|
|
552
|
+
validator = await start_validator(
|
|
553
|
+
service=service,
|
|
554
|
+
validator=previous_validator,
|
|
555
|
+
validator_type=CoreArtifactValidator,
|
|
556
|
+
proposed_change=model.proposed_change,
|
|
557
|
+
data={
|
|
558
|
+
"label": validator_name,
|
|
559
|
+
"definition": model.artifact_definition.definition_id,
|
|
560
|
+
},
|
|
561
|
+
context=model.context,
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
await artifact_definition.targets.fetch()
|
|
565
|
+
group = artifact_definition.targets.peer
|
|
566
|
+
await group.members.fetch()
|
|
567
|
+
|
|
568
|
+
existing_artifacts = await service.client.filters(
|
|
569
|
+
kind=InfrahubKind.ARTIFACT,
|
|
570
|
+
definition__ids=[model.artifact_definition.definition_id],
|
|
571
|
+
include=["object"],
|
|
572
|
+
branch=model.source_branch,
|
|
573
|
+
)
|
|
574
|
+
artifacts_by_member = {}
|
|
575
|
+
for artifact in existing_artifacts:
|
|
576
|
+
artifacts_by_member[artifact.object.peer.id] = artifact.id
|
|
577
|
+
|
|
578
|
+
repository = model.branch_diff.get_repository(repository_id=model.artifact_definition.repository_id)
|
|
579
|
+
impacted_artifacts = model.branch_diff.get_subscribers_ids(kind=InfrahubKind.ARTIFACT)
|
|
580
|
+
|
|
581
|
+
checks = []
|
|
582
|
+
|
|
583
|
+
for relationship in group.members.peers:
|
|
584
|
+
member = relationship.peer
|
|
585
|
+
artifact_id = artifacts_by_member.get(member.id)
|
|
586
|
+
if _should_render_artifact(
|
|
587
|
+
artifact_id=artifact_id,
|
|
588
|
+
managed_branch=model.source_branch_sync_with_git,
|
|
589
|
+
impacted_artifacts=impacted_artifacts,
|
|
590
|
+
):
|
|
591
|
+
log.info(f"Trigger Artifact processing for {member.display_label}")
|
|
592
|
+
|
|
593
|
+
check_model = CheckArtifactCreate(
|
|
594
|
+
context=model.context,
|
|
595
|
+
artifact_name=model.artifact_definition.artifact_name,
|
|
596
|
+
artifact_id=artifact_id,
|
|
597
|
+
artifact_definition=model.artifact_definition.definition_id,
|
|
598
|
+
commit=repository.source_commit,
|
|
599
|
+
content_type=model.artifact_definition.content_type,
|
|
600
|
+
transform_type=model.artifact_definition.transform_kind,
|
|
601
|
+
transform_location=model.artifact_definition.transform_location,
|
|
602
|
+
repository_id=repository.repository_id,
|
|
603
|
+
repository_name=repository.repository_name,
|
|
604
|
+
repository_kind=repository.kind,
|
|
605
|
+
branch_name=model.source_branch,
|
|
606
|
+
query=model.artifact_definition.query_name,
|
|
607
|
+
variables=member.extract(params=artifact_definition.parameters.value),
|
|
608
|
+
target_id=member.id,
|
|
609
|
+
target_kind=member.get_kind(),
|
|
610
|
+
target_name=member.display_label,
|
|
611
|
+
timeout=model.artifact_definition.timeout,
|
|
612
|
+
validator_id=validator.id,
|
|
613
|
+
)
|
|
614
|
+
|
|
615
|
+
checks.append(
|
|
616
|
+
service.workflow.execute_workflow(
|
|
617
|
+
workflow=GIT_REPOSITORIES_CHECK_ARTIFACT_CREATE,
|
|
618
|
+
parameters={"model": check_model},
|
|
619
|
+
expected_return=ValidatorConclusion,
|
|
620
|
+
)
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
await run_checks_and_update_validator(
|
|
624
|
+
checks=checks,
|
|
625
|
+
validator=validator,
|
|
626
|
+
proposed_change_id=model.proposed_change,
|
|
627
|
+
context=model.context,
|
|
628
|
+
service=service,
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
def _should_render_artifact(artifact_id: str | None, managed_branch: bool, impacted_artifacts: list[str]) -> bool: # noqa: ARG001
|
|
633
|
+
"""Returns a boolean to indicate if an artifact should be generated or not.
|
|
634
|
+
Will return true if:
|
|
635
|
+
* The artifact_id wasn't set which could be that it's a new object that doesn't have a previous artifact
|
|
636
|
+
* The source brance is not data only which would indicate that it could contain updates in git to the transform
|
|
637
|
+
* The artifact_id exists in the impacted_artifacts list
|
|
638
|
+
Will return false if:
|
|
639
|
+
* The source branch is a data only branch and the artifact_id exists and is not in the impacted list
|
|
640
|
+
"""
|
|
641
|
+
|
|
642
|
+
# if not artifact_id or managed_branch:
|
|
643
|
+
# return True
|
|
644
|
+
# return artifact_id in impacted_artifacts
|
|
645
|
+
# Temporary workaround tracked in https://github.com/opsmill/infrahub/issues/4991
|
|
646
|
+
return True
|
infrahub/pytest_plugin.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import pytest
|
|
3
2
|
from infrahub_sdk.client import Config as InfrahubClientConfig
|
|
4
3
|
from infrahub_sdk.client import InfrahubClientSync
|
|
5
4
|
from infrahub_sdk.node import InfrahubNodeSync
|
|
6
|
-
from pytest import Config, Item, Session, TestReport
|
|
7
5
|
|
|
8
6
|
from infrahub.core.constants import InfrahubKind
|
|
9
7
|
from infrahub.core.timestamp import Timestamp
|
|
@@ -52,7 +50,12 @@ class InfrahubBackendPlugin:
|
|
|
52
50
|
|
|
53
51
|
return validator, True
|
|
54
52
|
|
|
55
|
-
def pytest_collection_modifyitems(
|
|
53
|
+
def pytest_collection_modifyitems(
|
|
54
|
+
self,
|
|
55
|
+
session: pytest.Session, # noqa: ARG002
|
|
56
|
+
config: pytest.Config, # noqa: ARG002
|
|
57
|
+
items: list[pytest.Item],
|
|
58
|
+
) -> None:
|
|
56
59
|
"""This function is called after item collection and gives the opportunity to work on the collection before sending the items for testing.
|
|
57
60
|
|
|
58
61
|
All items without an "infrahub" marker will be discarded. Items will also be re-ordered to be run in a specific order:
|
|
@@ -64,7 +67,7 @@ class InfrahubBackendPlugin:
|
|
|
64
67
|
"""
|
|
65
68
|
filtered_items = [i for i in items if i.get_closest_marker("infrahub")]
|
|
66
69
|
|
|
67
|
-
def sort_key(item: Item) -> tuple[int, int]:
|
|
70
|
+
def sort_key(item: pytest.Item) -> tuple[int, int]:
|
|
68
71
|
type_cost = 99
|
|
69
72
|
for marker_name, priority in ORDER_TYPE_MAP.items():
|
|
70
73
|
if item.get_closest_marker(marker_name):
|
|
@@ -82,7 +85,7 @@ class InfrahubBackendPlugin:
|
|
|
82
85
|
filtered_items.sort(key=sort_key)
|
|
83
86
|
items[:] = filtered_items
|
|
84
87
|
|
|
85
|
-
def pytest_collection_finish(self, session: Session) -> None: #
|
|
88
|
+
def pytest_collection_finish(self, session: pytest.Session) -> None: # noqa: ARG002
|
|
86
89
|
"""This function is called when tests have been collected and modified, meaning they are ready to be run."""
|
|
87
90
|
self.proposed_change = self.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=self.proposed_change_id)
|
|
88
91
|
self.proposed_change.validations.fetch()
|
|
@@ -95,7 +98,7 @@ class InfrahubBackendPlugin:
|
|
|
95
98
|
check = relationship.peer
|
|
96
99
|
self.checks[check.origin.value] = check
|
|
97
100
|
|
|
98
|
-
def pytest_runtestloop(self, session: Session) ->
|
|
101
|
+
def pytest_runtestloop(self, session: pytest.Session) -> object | None: # noqa: ARG002
|
|
99
102
|
"""This function is called when the test loop is being run."""
|
|
100
103
|
self.validator.conclusion.value = "unknown"
|
|
101
104
|
self.validator.state.value = "in_progress"
|
|
@@ -104,7 +107,7 @@ class InfrahubBackendPlugin:
|
|
|
104
107
|
|
|
105
108
|
return None
|
|
106
109
|
|
|
107
|
-
def pytest_runtest_setup(self, item: Item) -> None:
|
|
110
|
+
def pytest_runtest_setup(self, item: pytest.Item) -> None:
|
|
108
111
|
"""Create a StandardCheck for each test item to later record its details.
|
|
109
112
|
|
|
110
113
|
If a check already exists, reset it to its default values.
|
|
@@ -132,7 +135,7 @@ class InfrahubBackendPlugin:
|
|
|
132
135
|
|
|
133
136
|
check.save()
|
|
134
137
|
|
|
135
|
-
def pytest_runtest_logreport(self, report: TestReport) -> None:
|
|
138
|
+
def pytest_runtest_logreport(self, report: pytest.TestReport) -> None:
|
|
136
139
|
"""This function is called 3 times per test: setup, call, teardown."""
|
|
137
140
|
if report.when != "call":
|
|
138
141
|
return
|
|
@@ -144,7 +147,7 @@ class InfrahubBackendPlugin:
|
|
|
144
147
|
# Workaround for https://github.com/opsmill/infrahub/issues/2184
|
|
145
148
|
check.update(do_full_update=True)
|
|
146
149
|
|
|
147
|
-
def pytest_sessionfinish(self, session: Session) -> None: #
|
|
150
|
+
def pytest_sessionfinish(self, session: pytest.Session) -> None: # noqa: ARG002
|
|
148
151
|
"""Set the final RepositoryValidator details after completing the test session."""
|
|
149
152
|
conclusion = "success"
|
|
150
153
|
|
infrahub/server.py
CHANGED
|
@@ -14,7 +14,7 @@ from fastapi.middleware.gzip import GZipMiddleware
|
|
|
14
14
|
from fastapi.responses import RedirectResponse
|
|
15
15
|
from fastapi.staticfiles import StaticFiles
|
|
16
16
|
from fastapi.templating import Jinja2Templates
|
|
17
|
-
from infrahub_sdk.
|
|
17
|
+
from infrahub_sdk.exceptions import TimestampFormatError
|
|
18
18
|
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
|
|
19
19
|
from opentelemetry.trace import Span
|
|
20
20
|
from pydantic import ValidationError
|
|
@@ -33,7 +33,7 @@ from infrahub.graphql.api.endpoints import router as graphql_router
|
|
|
33
33
|
from infrahub.lock import initialize_lock
|
|
34
34
|
from infrahub.log import clear_log_context, get_logger, set_log_data
|
|
35
35
|
from infrahub.middleware import InfrahubCORSMiddleware
|
|
36
|
-
from infrahub.services import InfrahubServices
|
|
36
|
+
from infrahub.services import InfrahubServices
|
|
37
37
|
from infrahub.services.adapters.cache.nats import NATSCache
|
|
38
38
|
from infrahub.services.adapters.cache.redis import RedisCache
|
|
39
39
|
from infrahub.services.adapters.message_bus.nats import NATSMessageBus
|
|
@@ -70,26 +70,27 @@ async def app_initialization(application: FastAPI, enable_scheduler: bool = True
|
|
|
70
70
|
if config.SETTINGS.workflow.driver == config.WorkflowDriver.WORKER
|
|
71
71
|
else WorkflowLocalExecution()
|
|
72
72
|
)
|
|
73
|
-
|
|
73
|
+
component_type = ComponentType.API_SERVER
|
|
74
74
|
message_bus = config.OVERRIDE.message_bus or (
|
|
75
|
-
NATSMessageBus
|
|
75
|
+
await NATSMessageBus.new(component_type=component_type)
|
|
76
|
+
if config.SETTINGS.broker.driver == config.BrokerDriver.NATS
|
|
77
|
+
else await RabbitMQMessageBus.new(component_type=component_type)
|
|
76
78
|
)
|
|
77
79
|
cache = config.OVERRIDE.cache or (
|
|
78
|
-
NATSCache() if config.SETTINGS.cache.driver == config.CacheDriver.NATS else RedisCache()
|
|
80
|
+
await NATSCache.new() if config.SETTINGS.cache.driver == config.CacheDriver.NATS else RedisCache()
|
|
79
81
|
)
|
|
80
|
-
service = InfrahubServices(
|
|
82
|
+
service = await InfrahubServices.new(
|
|
81
83
|
cache=cache,
|
|
82
84
|
database=database,
|
|
83
85
|
message_bus=message_bus,
|
|
84
86
|
workflow=workflow,
|
|
85
|
-
component_type=
|
|
87
|
+
component_type=component_type,
|
|
86
88
|
)
|
|
87
|
-
await service.initialize()
|
|
88
89
|
initialize_lock(service=service)
|
|
89
90
|
# We must initialize DB after initialize lock and initialize lock depends on cache initialization
|
|
90
91
|
async with application.state.db.start_session() as db:
|
|
91
92
|
await initialization(db=db)
|
|
92
|
-
|
|
93
|
+
|
|
93
94
|
application.state.service = service
|
|
94
95
|
application.state.response_delay = config.SETTINGS.miscellaneous.response_delay
|
|
95
96
|
if enable_scheduler:
|
|
@@ -97,7 +98,7 @@ async def app_initialization(application: FastAPI, enable_scheduler: bool = True
|
|
|
97
98
|
|
|
98
99
|
|
|
99
100
|
async def shutdown(application: FastAPI) -> None:
|
|
100
|
-
await
|
|
101
|
+
await application.state.service.shutdown()
|
|
101
102
|
await application.state.db.close()
|
|
102
103
|
|
|
103
104
|
|
|
@@ -118,7 +119,7 @@ app = FastAPI(
|
|
|
118
119
|
)
|
|
119
120
|
|
|
120
121
|
|
|
121
|
-
def server_request_hook(span: Span, scope: dict) -> None: #
|
|
122
|
+
def server_request_hook(span: Span, scope: dict) -> None: # noqa: ARG001
|
|
122
123
|
if span and span.is_recording():
|
|
123
124
|
span.set_attribute("worker", WORKER_IDENTITY)
|
|
124
125
|
|
|
@@ -217,5 +218,5 @@ async def documentation() -> RedirectResponse:
|
|
|
217
218
|
|
|
218
219
|
|
|
219
220
|
@app.get("/{rest_of_path:path}", include_in_schema=False)
|
|
220
|
-
async def react_app(req: Request, rest_of_path: str) -> Response: #
|
|
221
|
+
async def react_app(req: Request, rest_of_path: str) -> Response: # noqa: ARG001
|
|
221
222
|
return templates.TemplateResponse("index.html", {"request": req})
|