infrahub-server 1.1.7__py3-none-any.whl → 1.2.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/api/artifact.py +16 -4
- infrahub/api/dependencies.py +8 -0
- infrahub/api/oauth2.py +0 -1
- infrahub/api/oidc.py +0 -1
- infrahub/api/query.py +18 -7
- infrahub/api/schema.py +32 -6
- infrahub/api/transformation.py +12 -5
- infrahub/{message_bus/messages/check_artifact_create.py → artifacts/models.py} +5 -3
- infrahub/{message_bus/operations/check/artifact.py → artifacts/tasks.py} +26 -25
- infrahub/cli/__init__.py +0 -2
- infrahub/cli/db.py +6 -7
- infrahub/cli/events.py +8 -3
- infrahub/cli/git_agent.py +9 -7
- infrahub/cli/tasks.py +4 -6
- infrahub/computed_attribute/models.py +1 -1
- infrahub/computed_attribute/tasks.py +64 -17
- infrahub/computed_attribute/triggers.py +90 -0
- infrahub/config.py +1 -1
- infrahub/context.py +39 -0
- infrahub/core/account.py +5 -8
- infrahub/core/attribute.py +50 -21
- infrahub/core/branch/models.py +4 -4
- infrahub/core/branch/tasks.py +130 -125
- infrahub/core/changelog/__init__.py +0 -0
- infrahub/core/changelog/diff.py +283 -0
- infrahub/core/changelog/models.py +499 -0
- infrahub/core/constants/__init__.py +43 -2
- infrahub/core/constants/infrahubkind.py +1 -0
- infrahub/core/constants/schema.py +2 -0
- infrahub/core/diff/combiner.py +1 -1
- infrahub/core/diff/enricher/cardinality_one.py +6 -1
- infrahub/core/diff/enricher/hierarchy.py +22 -7
- infrahub/core/diff/enricher/labels.py +6 -1
- infrahub/core/diff/enricher/path_identifier.py +5 -1
- infrahub/core/diff/enricher/summary_counts.py +107 -0
- infrahub/core/diff/merger/merger.py +3 -1
- infrahub/core/diff/model/path.py +34 -11
- infrahub/core/diff/parent_node_adder.py +78 -0
- infrahub/core/diff/payload_builder.py +13 -2
- 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 +191 -185
- infrahub/core/diff/query/summary_counts_enricher.py +52 -5
- infrahub/core/diff/query/time_range_query.py +1 -1
- infrahub/core/diff/query/update_conflict_query.py +1 -1
- infrahub/core/diff/repository/deserializer.py +9 -4
- infrahub/core/diff/repository/repository.py +156 -38
- infrahub/core/diff/tasks.py +13 -12
- infrahub/core/enums.py +1 -1
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/index.py +3 -0
- infrahub/core/integrity/object_conflict/conflict_recorder.py +1 -1
- infrahub/core/ipam/reconciler.py +1 -1
- infrahub/core/ipam/tasks.py +2 -3
- infrahub/core/manager.py +20 -15
- infrahub/core/merge.py +5 -2
- infrahub/core/migrations/graph/__init__.py +4 -0
- infrahub/core/migrations/graph/m001_add_version_to_graph.py +1 -1
- infrahub/core/migrations/graph/m002_attribute_is_default.py +2 -2
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +2 -2
- infrahub/core/migrations/graph/m004_add_attr_documentation.py +1 -1
- infrahub/core/migrations/graph/m005_add_rel_read_only.py +1 -1
- infrahub/core/migrations/graph/m006_add_rel_on_delete.py +1 -1
- infrahub/core/migrations/graph/m007_add_rel_allow_override.py +1 -1
- infrahub/core/migrations/graph/m008_add_human_friendly_id.py +1 -1
- infrahub/core/migrations/graph/m009_add_generate_profile_attr.py +1 -1
- infrahub/core/migrations/graph/m010_add_generate_profile_attr_generic.py +1 -1
- infrahub/core/migrations/graph/m011_remove_profile_relationship_schema.py +2 -2
- infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -23
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -11
- infrahub/core/migrations/graph/m014_remove_index_attr_value.py +2 -2
- infrahub/core/migrations/graph/m015_diff_format_update.py +1 -1
- infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -1
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -1
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -2
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
- infrahub/core/migrations/graph/m020_add_generate_template_attr.py +48 -0
- infrahub/core/migrations/query/attribute_add.py +1 -1
- infrahub/core/migrations/query/attribute_rename.py +1 -1
- infrahub/core/migrations/query/delete_element_in_schema.py +1 -1
- infrahub/core/migrations/query/node_duplicate.py +39 -19
- infrahub/core/migrations/query/relationship_duplicate.py +1 -1
- infrahub/core/migrations/query/schema_attribute_update.py +1 -1
- infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
- infrahub/core/migrations/schema/node_remove.py +27 -13
- infrahub/core/migrations/schema/tasks.py +5 -5
- infrahub/core/migrations/shared.py +4 -4
- infrahub/core/models.py +7 -8
- infrahub/core/node/__init__.py +164 -45
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/delete_validator.py +4 -4
- infrahub/core/node/ipam.py +7 -7
- infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
- infrahub/core/node/standard.py +3 -5
- infrahub/core/property.py +1 -1
- infrahub/core/protocols.py +6 -0
- infrahub/core/protocols_base.py +4 -2
- infrahub/core/query/__init__.py +2 -5
- infrahub/core/query/attribute.py +9 -9
- infrahub/core/query/branch.py +5 -5
- infrahub/core/query/delete.py +1 -1
- infrahub/core/query/diff.py +4 -4
- infrahub/core/query/ipam.py +4 -4
- infrahub/core/query/node.py +11 -12
- infrahub/core/query/relationship.py +211 -25
- infrahub/core/query/resource_manager.py +10 -10
- infrahub/core/query/standard_node.py +6 -6
- infrahub/core/query/task.py +3 -3
- infrahub/core/query/task_log.py +1 -1
- infrahub/core/query/utils.py +5 -5
- infrahub/core/registry.py +0 -2
- infrahub/core/relationship/constraints/count.py +1 -1
- infrahub/core/relationship/constraints/peer_kind.py +1 -1
- infrahub/core/relationship/model.py +76 -38
- infrahub/core/schema/__init__.py +6 -4
- infrahub/core/schema/attribute_schema.py +8 -0
- infrahub/core/schema/basenode_schema.py +13 -3
- infrahub/core/schema/definitions/core/__init__.py +153 -0
- infrahub/core/schema/definitions/core/account.py +168 -0
- infrahub/core/schema/definitions/core/artifact.py +127 -0
- infrahub/core/schema/definitions/core/builtin.py +21 -0
- infrahub/core/schema/definitions/core/check.py +60 -0
- infrahub/core/schema/definitions/core/generator.py +96 -0
- infrahub/core/schema/definitions/core/graphql_query.py +77 -0
- infrahub/core/schema/definitions/core/group.py +105 -0
- infrahub/core/schema/definitions/core/ipam.py +252 -0
- infrahub/core/schema/definitions/core/lineage.py +17 -0
- infrahub/core/schema/definitions/core/menu.py +46 -0
- infrahub/core/schema/definitions/core/permission.py +161 -0
- infrahub/core/schema/definitions/core/profile.py +29 -0
- infrahub/core/schema/definitions/core/propose_change.py +88 -0
- infrahub/core/schema/definitions/core/propose_change_comment.py +188 -0
- infrahub/core/schema/definitions/core/propose_change_validator.py +326 -0
- infrahub/core/schema/definitions/core/repository.py +280 -0
- infrahub/core/schema/definitions/core/resource_pool.py +180 -0
- infrahub/core/schema/definitions/core/template.py +12 -0
- infrahub/core/schema/definitions/core/transform.py +87 -0
- infrahub/core/schema/definitions/core/webhook.py +108 -0
- infrahub/core/schema/definitions/internal.py +16 -0
- infrahub/core/schema/generated/genericnode_schema.py +5 -0
- infrahub/core/schema/generated/node_schema.py +5 -0
- infrahub/core/schema/generic_schema.py +5 -1
- infrahub/core/schema/manager.py +45 -42
- infrahub/core/schema/node_schema.py +4 -0
- infrahub/core/schema/profile_schema.py +4 -0
- infrahub/core/schema/relationship_schema.py +10 -2
- infrahub/core/schema/schema_branch.py +260 -16
- infrahub/core/schema/template_schema.py +36 -0
- infrahub/core/task/user_task.py +7 -5
- infrahub/core/timestamp.py +3 -3
- infrahub/core/utils.py +2 -2
- infrahub/core/validators/attribute/choices.py +1 -1
- infrahub/core/validators/attribute/enum.py +1 -1
- infrahub/core/validators/attribute/kind.py +1 -1
- infrahub/core/validators/attribute/length.py +1 -1
- infrahub/core/validators/attribute/optional.py +1 -1
- infrahub/core/validators/attribute/regex.py +1 -1
- infrahub/core/validators/attribute/unique.py +1 -1
- infrahub/core/validators/checks_runner.py +37 -0
- infrahub/core/validators/node/generate_profile.py +1 -1
- infrahub/core/validators/node/hierarchy.py +1 -1
- infrahub/core/validators/query.py +1 -1
- infrahub/core/validators/relationship/count.py +1 -1
- infrahub/core/validators/relationship/optional.py +1 -1
- infrahub/core/validators/relationship/peer.py +1 -1
- infrahub/core/validators/tasks.py +8 -6
- infrahub/core/validators/uniqueness/query.py +1 -1
- infrahub/database/__init__.py +3 -2
- 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 +4 -2
- infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
- infrahub/dependencies/builder/diff/enricher/summary_counts.py +8 -0
- infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
- infrahub/events/artifact_action.py +76 -0
- infrahub/events/branch_action.py +50 -21
- infrahub/events/group_action.py +117 -0
- infrahub/events/models.py +164 -51
- infrahub/events/node_action.py +70 -8
- infrahub/events/repository_action.py +8 -8
- infrahub/events/schema_action.py +21 -8
- infrahub/exceptions.py +9 -0
- infrahub/generators/models.py +1 -0
- infrahub/generators/tasks.py +34 -15
- infrahub/git/base.py +3 -5
- infrahub/git/constants.py +0 -1
- infrahub/git/integrator.py +60 -36
- infrahub/git/models.py +80 -1
- infrahub/git/repository.py +7 -8
- infrahub/git/tasks.py +432 -112
- infrahub/git_credential/helper.py +2 -3
- infrahub/graphql/analyzer.py +572 -11
- infrahub/graphql/app.py +34 -26
- infrahub/graphql/auth/query_permission_checker/anonymous_checker.py +5 -5
- infrahub/graphql/auth/query_permission_checker/default_branch_checker.py +4 -4
- infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py +4 -4
- infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +28 -35
- infrahub/graphql/auth/query_permission_checker/super_admin_checker.py +5 -5
- infrahub/graphql/context.py +33 -0
- infrahub/graphql/enums.py +1 -1
- infrahub/graphql/initialization.py +5 -1
- infrahub/graphql/loaders/node.py +2 -2
- infrahub/graphql/manager.py +63 -63
- infrahub/graphql/mutations/account.py +20 -13
- infrahub/graphql/mutations/artifact_definition.py +16 -12
- infrahub/graphql/mutations/branch.py +86 -40
- infrahub/graphql/mutations/computed_attribute.py +24 -15
- infrahub/graphql/mutations/diff.py +33 -17
- infrahub/graphql/mutations/diff_conflict.py +14 -8
- infrahub/graphql/mutations/generator.py +83 -0
- infrahub/graphql/mutations/graphql_query.py +19 -11
- infrahub/graphql/mutations/ipam.py +25 -23
- infrahub/graphql/mutations/main.py +233 -45
- infrahub/graphql/mutations/menu.py +10 -10
- infrahub/graphql/mutations/proposed_change.py +36 -28
- infrahub/graphql/mutations/relationship.py +341 -130
- infrahub/graphql/mutations/repository.py +41 -35
- infrahub/graphql/mutations/resource_manager.py +26 -26
- infrahub/graphql/mutations/schema.py +66 -33
- infrahub/graphql/mutations/tasks.py +10 -7
- infrahub/graphql/parser.py +1 -1
- 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 +63 -52
- infrahub/graphql/queries/event.py +115 -0
- infrahub/graphql/queries/internal.py +3 -3
- infrahub/graphql/queries/ipam.py +23 -18
- infrahub/graphql/queries/relationship.py +11 -10
- infrahub/graphql/queries/resource_manager.py +37 -25
- infrahub/graphql/queries/search.py +9 -8
- infrahub/graphql/queries/status.py +12 -9
- infrahub/graphql/queries/task.py +11 -9
- infrahub/graphql/resolvers/resolver.py +69 -43
- infrahub/graphql/resolvers/single_relationship.py +16 -10
- infrahub/graphql/schema.py +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 +158 -0
- infrahub/graphql/types/interface.py +2 -2
- infrahub/graphql/types/node.py +3 -3
- infrahub/graphql/types/permission.py +2 -2
- infrahub/graphql/types/relationship.py +3 -3
- infrahub/graphql/types/standard_node.py +9 -11
- infrahub/graphql/utils.py +28 -182
- infrahub/groups/tasks.py +2 -3
- infrahub/lock.py +21 -21
- infrahub/menu/generator.py +0 -1
- infrahub/menu/menu.py +116 -138
- infrahub/menu/models.py +4 -4
- infrahub/message_bus/__init__.py +11 -13
- infrahub/message_bus/messages/__init__.py +0 -14
- infrahub/message_bus/messages/check_generator_run.py +1 -3
- infrahub/message_bus/messages/event_branch_merge.py +3 -0
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -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 -13
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -3
- infrahub/message_bus/operations/event/branch.py +7 -3
- infrahub/message_bus/operations/event/schema.py +1 -1
- infrahub/message_bus/operations/event/worker.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +1 -1
- infrahub/message_bus/operations/git/file.py +2 -2
- infrahub/message_bus/operations/git/repository.py +1 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -4
- infrahub/message_bus/operations/requests/generator_definition.py +2 -4
- infrahub/message_bus/operations/requests/proposed_change.py +37 -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/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 +195 -53
- infrahub/pytest_plugin.py +4 -4
- 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 +10 -18
- infrahub/services/adapters/http/__init__.py +0 -5
- infrahub/services/adapters/http/httpx.py +22 -15
- infrahub/services/adapters/message_bus/__init__.py +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 +261 -0
- infrahub/task_manager/models.py +147 -3
- infrahub/task_manager/task.py +1 -1
- infrahub/tasks/artifact.py +19 -18
- infrahub/tasks/registry.py +1 -1
- infrahub/tasks/telemetry.py +13 -14
- infrahub/transformations/tasks.py +3 -5
- infrahub/trigger/__init__.py +0 -0
- infrahub/trigger/catalogue.py +16 -0
- infrahub/trigger/constants.py +9 -0
- infrahub/trigger/models.py +105 -0
- infrahub/trigger/tasks.py +91 -0
- infrahub/types.py +1 -1
- infrahub/utils.py +1 -1
- infrahub/webhook/constants.py +0 -2
- infrahub/webhook/models.py +161 -40
- infrahub/webhook/tasks.py +123 -202
- infrahub/webhook/triggers.py +27 -0
- infrahub/workers/infrahub_async.py +36 -25
- infrahub/workers/utils.py +63 -0
- infrahub/workflows/catalogue.py +71 -52
- infrahub/workflows/initialization.py +14 -8
- infrahub/workflows/models.py +28 -4
- infrahub/workflows/utils.py +1 -1
- infrahub_sdk/batch.py +2 -2
- infrahub_sdk/client.py +8 -0
- infrahub_sdk/config.py +1 -1
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/check.py +4 -4
- infrahub_sdk/ctl/cli_commands.py +16 -11
- infrahub_sdk/ctl/exceptions.py +0 -6
- infrahub_sdk/ctl/exporter.py +1 -1
- infrahub_sdk/ctl/generator.py +5 -5
- infrahub_sdk/ctl/importer.py +3 -2
- infrahub_sdk/ctl/menu.py +1 -1
- infrahub_sdk/ctl/object.py +1 -1
- infrahub_sdk/ctl/repository.py +23 -15
- infrahub_sdk/ctl/schema.py +2 -2
- infrahub_sdk/ctl/utils.py +6 -21
- infrahub_sdk/ctl/validate.py +2 -1
- infrahub_sdk/data.py +1 -1
- infrahub_sdk/exceptions.py +12 -0
- infrahub_sdk/generator.py +3 -0
- infrahub_sdk/node.py +5 -8
- infrahub_sdk/protocols.py +20 -8
- infrahub_sdk/schema/__init__.py +14 -5
- infrahub_sdk/schema/main.py +7 -0
- infrahub_sdk/task/__init__.py +1 -0
- infrahub_sdk/task/constants.py +3 -0
- infrahub_sdk/task/exceptions.py +25 -0
- infrahub_sdk/task/manager.py +545 -0
- infrahub_sdk/task/models.py +74 -0
- infrahub_sdk/testing/docker.py +30 -0
- infrahub_sdk/timestamp.py +134 -33
- infrahub_sdk/transfer/exporter/json.py +1 -1
- infrahub_sdk/utils.py +39 -1
- infrahub_sdk/yaml.py +2 -3
- {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +7 -6
- {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/RECORD +383 -339
- infrahub_testcontainers/container.py +2 -3
- infrahub_testcontainers/docker-compose.test.yml +2 -2
- infrahub/core/branch/constants.py +0 -2
- infrahub/core/schema/definitions/core.py +0 -2274
- 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/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/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_sdk/ctl/_file.py +0 -13
- /infrahub/{schema → artifacts}/__init__.py +0 -0
- {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
- {infrahub_server-1.1.7.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
infrahub/services/scheduler.py
CHANGED
|
@@ -7,12 +7,15 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
|
|
8
8
|
from infrahub import config
|
|
9
9
|
from infrahub.components import ComponentType
|
|
10
|
+
from infrahub.log import get_logger
|
|
10
11
|
from infrahub.tasks.keepalive import refresh_heartbeat
|
|
11
12
|
from infrahub.tasks.recurring import trigger_branch_refresh
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
14
15
|
from infrahub.services import InfrahubServices, ServiceFunction
|
|
15
16
|
|
|
17
|
+
log = get_logger()
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
@dataclass
|
|
18
21
|
class Schedule:
|
|
@@ -23,18 +26,17 @@ class Schedule:
|
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
class InfrahubScheduler:
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
# TODO we could remove service dependency by adding kwargs to Schedule instead of passing services
|
|
30
|
+
service: InfrahubServices | None
|
|
31
|
+
|
|
32
|
+
def __init__(self, component_type: ComponentType) -> None:
|
|
28
33
|
self.running: bool = False
|
|
29
34
|
self.schedules: list[Schedule] = []
|
|
30
35
|
|
|
31
|
-
async def initialize(self, service: InfrahubServices) -> None:
|
|
32
|
-
self.service = service
|
|
33
|
-
|
|
34
36
|
self.running = config.SETTINGS.miscellaneous.start_background_runner
|
|
35
37
|
# Add some randomness to the interval to avoid having all workers pulling the latest update at the same time
|
|
36
38
|
random_number = random.randint(0, 5)
|
|
37
|
-
if
|
|
39
|
+
if component_type == ComponentType.API_SERVER:
|
|
38
40
|
schedules = [
|
|
39
41
|
Schedule(name="refresh_api_components", interval=10, function=refresh_heartbeat, start_delay=0),
|
|
40
42
|
Schedule(
|
|
@@ -43,7 +45,7 @@ class InfrahubScheduler:
|
|
|
43
45
|
]
|
|
44
46
|
self.schedules.extend(schedules)
|
|
45
47
|
|
|
46
|
-
if
|
|
48
|
+
if component_type == ComponentType.GIT_AGENT:
|
|
47
49
|
schedules = [
|
|
48
50
|
Schedule(name="refresh_components", interval=10, function=refresh_heartbeat),
|
|
49
51
|
Schedule(
|
|
@@ -54,32 +56,31 @@ class InfrahubScheduler:
|
|
|
54
56
|
|
|
55
57
|
async def start_schedule(self) -> None:
|
|
56
58
|
for schedule in self.schedules:
|
|
57
|
-
asyncio.create_task(
|
|
58
|
-
run_schedule(schedule=schedule, service=self.service), name=f"scheduled_task_{schedule.name}"
|
|
59
|
-
)
|
|
59
|
+
asyncio.create_task(self.run_schedule(schedule=schedule), name=f"scheduled_task_{schedule.name}")
|
|
60
60
|
|
|
61
61
|
async def shutdown(self) -> None:
|
|
62
62
|
self.running = False
|
|
63
63
|
|
|
64
|
+
async def run_schedule(self, schedule: Schedule) -> None:
|
|
65
|
+
"""Execute the task provided in the schedule as per the defined interval
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"""
|
|
70
|
-
for _ in range(schedule.start_delay):
|
|
71
|
-
if not service.scheduler.running:
|
|
72
|
-
return
|
|
73
|
-
await asyncio.sleep(delay=1)
|
|
74
|
-
|
|
75
|
-
service.log.info("Started recurring task", task=schedule.name)
|
|
76
|
-
|
|
77
|
-
while service.scheduler.running:
|
|
78
|
-
try:
|
|
79
|
-
await schedule.function(service)
|
|
80
|
-
except Exception as exc: # pylint: disable=broad-exception-caught
|
|
81
|
-
service.log.error(str(exc))
|
|
82
|
-
for _ in range(schedule.interval):
|
|
83
|
-
if not service.scheduler.running:
|
|
67
|
+
Once the service is marked to be shutdown the scheduler will stop executing tasks.
|
|
68
|
+
"""
|
|
69
|
+
for _ in range(schedule.start_delay):
|
|
70
|
+
if not self.running:
|
|
84
71
|
return
|
|
85
72
|
await asyncio.sleep(delay=1)
|
|
73
|
+
|
|
74
|
+
if self.service is None:
|
|
75
|
+
raise ValueError("InfrahubScheduler.service is None")
|
|
76
|
+
|
|
77
|
+
self.service.log.info("Started recurring task", task=schedule.name)
|
|
78
|
+
while self.running:
|
|
79
|
+
try:
|
|
80
|
+
await schedule.function(self.service)
|
|
81
|
+
except Exception as exc:
|
|
82
|
+
self.service.log.error(str(exc))
|
|
83
|
+
for _ in range(schedule.interval):
|
|
84
|
+
if not self.running:
|
|
85
|
+
return
|
|
86
|
+
await asyncio.sleep(delay=1)
|
infrahub/storage.py
CHANGED
|
@@ -53,7 +53,5 @@ class InfrahubObjectStorage:
|
|
|
53
53
|
try:
|
|
54
54
|
with self._storage.open(identifier) as f:
|
|
55
55
|
return f.read().decode()
|
|
56
|
-
except (FileNotFoundError, botocore.exceptions.ClientError):
|
|
57
|
-
raise NodeNotFoundError(
|
|
58
|
-
node_type="StorageObject", identifier=identifier
|
|
59
|
-
)
|
|
56
|
+
except (FileNotFoundError, botocore.exceptions.ClientError) as err:
|
|
57
|
+
raise NodeNotFoundError(node_type="StorageObject", identifier=identifier) from err
|
|
@@ -2,7 +2,7 @@ from infrahub.core.constants import TaskConclusion
|
|
|
2
2
|
|
|
3
3
|
LOG_LEVEL_MAPPING = {10: "debug", 20: "info", 30: "warning", 40: "error", 50: "critical"}
|
|
4
4
|
|
|
5
|
-
CONCLUSION_STATE_MAPPING = {
|
|
5
|
+
CONCLUSION_STATE_MAPPING: dict[str, TaskConclusion] = {
|
|
6
6
|
"Scheduled": TaskConclusion.UNKNOWN,
|
|
7
7
|
"Pending": TaskConclusion.UNKNOWN,
|
|
8
8
|
"Running": TaskConclusion.UNKNOWN,
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
from prefect.client.orchestration import PrefectClient, get_client
|
|
7
|
+
from prefect.events.schemas.events import Event as PrefectEventModel
|
|
8
|
+
from pydantic import BaseModel, Field, TypeAdapter
|
|
9
|
+
|
|
10
|
+
from infrahub.core.constants import GLOBAL_BRANCH_NAME
|
|
11
|
+
from infrahub.exceptions import ServiceUnavailableError
|
|
12
|
+
from infrahub.log import get_logger
|
|
13
|
+
from infrahub.utils import get_nested_dict
|
|
14
|
+
|
|
15
|
+
log = get_logger()
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .models import InfrahubEventFilter
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PrefectEventData(PrefectEventModel):
|
|
22
|
+
def get_branch(self) -> str | None:
|
|
23
|
+
for resource in self.related:
|
|
24
|
+
if resource.get("prefect.resource.role") != "infrahub.branch":
|
|
25
|
+
continue
|
|
26
|
+
if "infrahub.resource.label" not in resource:
|
|
27
|
+
continue
|
|
28
|
+
if resource.get("infrahub.resource.label") == GLOBAL_BRANCH_NAME:
|
|
29
|
+
return None
|
|
30
|
+
return resource.get("infrahub.resource.label")
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
def get_level(self) -> int:
|
|
34
|
+
for resource in self.related:
|
|
35
|
+
level = resource.get("infrahub.event.level")
|
|
36
|
+
if level is None:
|
|
37
|
+
continue
|
|
38
|
+
try:
|
|
39
|
+
return int(level)
|
|
40
|
+
except ValueError:
|
|
41
|
+
return 0
|
|
42
|
+
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
def get_parent(self) -> str | None:
|
|
46
|
+
for resource in self.related:
|
|
47
|
+
if resource.get("prefect.resource.role") != "infrahub.child_event":
|
|
48
|
+
continue
|
|
49
|
+
return resource.get("infrahub.event_parent.id")
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
def get_primary_node(self) -> dict[str, str] | None:
|
|
53
|
+
node_id = self.resource.get("infrahub.node.id")
|
|
54
|
+
node_kind = self.resource.get("infrahub.node.kind")
|
|
55
|
+
if node_id and node_kind:
|
|
56
|
+
return {"id": node_id, "kind": node_kind}
|
|
57
|
+
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
def get_related_nodes(self) -> list[dict[str, str]]:
|
|
61
|
+
related_nodes = []
|
|
62
|
+
for resource in self.related:
|
|
63
|
+
if resource.get("prefect.resource.role") != "infrahub.related.node":
|
|
64
|
+
continue
|
|
65
|
+
|
|
66
|
+
node_id = resource.get("prefect.resource.id")
|
|
67
|
+
node_kind = resource.get("infrahub.node.kind")
|
|
68
|
+
if node_id == self.resource.get("infrahub.node.id"):
|
|
69
|
+
# Don't include the primary node as a related node.
|
|
70
|
+
continue
|
|
71
|
+
if node_id and node_kind:
|
|
72
|
+
related_nodes.append({"id": node_id, "kind": node_kind})
|
|
73
|
+
|
|
74
|
+
return related_nodes
|
|
75
|
+
|
|
76
|
+
def get_account_id(self) -> str | None:
|
|
77
|
+
for resource in self.related:
|
|
78
|
+
if resource.get("prefect.resource.role") != "infrahub.account":
|
|
79
|
+
continue
|
|
80
|
+
return resource.get("infrahub.resource.id")
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
def has_children(self) -> bool:
|
|
84
|
+
for resource in self.related:
|
|
85
|
+
if resource.get("prefect.resource.role") != "infrahub.event":
|
|
86
|
+
continue
|
|
87
|
+
if resource.get("infrahub.event.has_children") == "true":
|
|
88
|
+
return True
|
|
89
|
+
return False
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
def _return_node_mutation(self) -> dict[str, Any]:
|
|
93
|
+
attributes = []
|
|
94
|
+
|
|
95
|
+
for resource in self.related:
|
|
96
|
+
if resource.get("prefect.resource.role") == "infrahub.node.field_update" and resource.get(
|
|
97
|
+
"infrahub.attribute.name"
|
|
98
|
+
):
|
|
99
|
+
attributes.append(
|
|
100
|
+
{
|
|
101
|
+
"name": resource.get("infrahub.attribute.name", ""),
|
|
102
|
+
"kind": resource.get("infrahub.attribute.kind", ""),
|
|
103
|
+
"value": None
|
|
104
|
+
if resource.get("infrahub.attribute.value") == "NULL"
|
|
105
|
+
else resource.get("infrahub.attribute.value"),
|
|
106
|
+
"value_previous": None
|
|
107
|
+
if resource.get("infrahub.attribute.value_previous") == "NULL"
|
|
108
|
+
else resource.get("infrahub.attribute.value_previous"),
|
|
109
|
+
"action": resource.get("infrahub.attribute.action", "unchanged"),
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return {"attributes": attributes}
|
|
114
|
+
|
|
115
|
+
def _get_branch_name_from_resource(self) -> str:
|
|
116
|
+
return self.resource.get("infrahub.branch.name") or ""
|
|
117
|
+
|
|
118
|
+
def _return_artifact_event(self) -> dict[str, Any]:
|
|
119
|
+
checksum = ""
|
|
120
|
+
checksum_previous: str | None = None
|
|
121
|
+
storage_id = ""
|
|
122
|
+
storage_id_previous: str | None = None
|
|
123
|
+
artifact_definition_id = ""
|
|
124
|
+
for resource in self.related:
|
|
125
|
+
if resource.role == "infrahub.artifact":
|
|
126
|
+
checksum = resource.get("infrahub.artifact.checksum") or ""
|
|
127
|
+
checksum_previous = resource.get("infrahub.artifact.checksum_previous")
|
|
128
|
+
storage_id = resource.get("infrahub.artifact.storage_id") or ""
|
|
129
|
+
storage_id_previous = resource.get("infrahub.artifact.storage_id_previous")
|
|
130
|
+
artifact_definition_id = resource.get("infrahub.artifact.artifact_definition_id") or ""
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
"checksum": checksum,
|
|
134
|
+
"checksum_previous": checksum_previous,
|
|
135
|
+
"storage_id": storage_id,
|
|
136
|
+
"storage_id_previous": storage_id_previous,
|
|
137
|
+
"artifact_definition_id": artifact_definition_id,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
def _return_branch_created(self) -> dict[str, Any]:
|
|
141
|
+
return {"created_branch": self._get_branch_name_from_resource()}
|
|
142
|
+
|
|
143
|
+
def _return_branch_deleted(self) -> dict[str, Any]:
|
|
144
|
+
return {"deleted_branch": self._get_branch_name_from_resource()}
|
|
145
|
+
|
|
146
|
+
def _return_branch_merged(self) -> dict[str, Any]:
|
|
147
|
+
return {"source_branch": self._get_branch_name_from_resource()}
|
|
148
|
+
|
|
149
|
+
def _return_branch_rebased(self) -> dict[str, Any]:
|
|
150
|
+
return {"rebased_branch": self._get_branch_name_from_resource()}
|
|
151
|
+
|
|
152
|
+
def _return_group_event(self) -> dict[str, Any]:
|
|
153
|
+
members = []
|
|
154
|
+
ancestors = []
|
|
155
|
+
|
|
156
|
+
for resource in self.related:
|
|
157
|
+
if resource.role == "infrahub.group.member" and resource.get("infrahub.node.kind"):
|
|
158
|
+
members.append({"id": resource.id, "kind": resource.get("infrahub.node.kind")})
|
|
159
|
+
elif resource.role == "infrahub.group.ancestor" and resource.get("infrahub.node.kind"):
|
|
160
|
+
ancestors.append({"id": resource.id, "kind": resource.get("infrahub.node.kind")})
|
|
161
|
+
|
|
162
|
+
return {"members": members, "ancestors": ancestors}
|
|
163
|
+
|
|
164
|
+
def _return_event_specifics(self) -> dict[str, Any]:
|
|
165
|
+
"""Return event specific data based on the type of event being processed"""
|
|
166
|
+
|
|
167
|
+
event_specifics = {}
|
|
168
|
+
|
|
169
|
+
match self.event:
|
|
170
|
+
case "infrahub.artifact.created" | "infrahub.artifact.updated":
|
|
171
|
+
event_specifics = self._return_artifact_event()
|
|
172
|
+
case "infrahub.node.created" | "infrahub.node.updated" | "infrahub.node.deleted":
|
|
173
|
+
event_specifics = self._return_node_mutation()
|
|
174
|
+
case "infrahub.branch.created":
|
|
175
|
+
event_specifics = self._return_branch_created()
|
|
176
|
+
case "infrahub.branch.deleted":
|
|
177
|
+
event_specifics = self._return_branch_deleted()
|
|
178
|
+
case "infrahub.branch.merged":
|
|
179
|
+
event_specifics = self._return_branch_merged()
|
|
180
|
+
case "infrahub.branch.rebased":
|
|
181
|
+
event_specifics = self._return_branch_rebased()
|
|
182
|
+
case "infrahub.group.member_added" | "infrahub.group.member_removed":
|
|
183
|
+
event_specifics = self._return_group_event()
|
|
184
|
+
|
|
185
|
+
return event_specifics
|
|
186
|
+
|
|
187
|
+
def to_graphql(self) -> dict[str, Any]:
|
|
188
|
+
response = {
|
|
189
|
+
"id": str(self.id),
|
|
190
|
+
"event": self.event,
|
|
191
|
+
"branch": self.get_branch(),
|
|
192
|
+
"account_id": self.get_account_id(),
|
|
193
|
+
"occurred_at": self.occurred,
|
|
194
|
+
"has_children": self.has_children(),
|
|
195
|
+
"payload": self.payload,
|
|
196
|
+
"level": self.get_level(),
|
|
197
|
+
"primary_node": self.get_primary_node(),
|
|
198
|
+
"parent_id": self.get_parent(),
|
|
199
|
+
"related_nodes": self.get_related_nodes(),
|
|
200
|
+
}
|
|
201
|
+
response.update(self._return_event_specifics())
|
|
202
|
+
return response
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class PrefectEventResponse(BaseModel):
|
|
206
|
+
count: int = Field(..., description="Number of matching events")
|
|
207
|
+
events: list[PrefectEventData] = Field(..., description="Returned events")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class PrefectEvent:
|
|
211
|
+
@classmethod
|
|
212
|
+
async def query_events(
|
|
213
|
+
cls,
|
|
214
|
+
client: PrefectClient,
|
|
215
|
+
limit: int,
|
|
216
|
+
filters: InfrahubEventFilter,
|
|
217
|
+
offset: int | None = None,
|
|
218
|
+
) -> PrefectEventResponse:
|
|
219
|
+
body = {"limit": limit, "filter": filters.model_dump(mode="json", exclude_none=True), "offset": offset}
|
|
220
|
+
|
|
221
|
+
# Retry due to https://github.com/PrefectHQ/prefect/issues/16299
|
|
222
|
+
for _ in range(1, 5):
|
|
223
|
+
response = await client._client.post("/infrahub/events/filter", json=body)
|
|
224
|
+
if response.status_code == 200:
|
|
225
|
+
break
|
|
226
|
+
await asyncio.sleep(0.1)
|
|
227
|
+
|
|
228
|
+
if response.status_code != 200:
|
|
229
|
+
raise ServiceUnavailableError(
|
|
230
|
+
message=f"Unable to query prefect due to invalid response from the server (status_code={response.status_code})"
|
|
231
|
+
)
|
|
232
|
+
data: dict[str, Any] = response.json()
|
|
233
|
+
|
|
234
|
+
return PrefectEventResponse(
|
|
235
|
+
count=data.get("total", 0),
|
|
236
|
+
events=TypeAdapter(list[PrefectEventData]).validate_python(data.get("events")),
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
@classmethod
|
|
240
|
+
async def query(
|
|
241
|
+
cls,
|
|
242
|
+
fields: dict[str, Any],
|
|
243
|
+
event_filter: InfrahubEventFilter,
|
|
244
|
+
limit: int | None = None,
|
|
245
|
+
offset: int | None = None,
|
|
246
|
+
) -> dict[str, Any]:
|
|
247
|
+
nodes: list[dict] = []
|
|
248
|
+
limit = limit or 50
|
|
249
|
+
|
|
250
|
+
node_fields = get_nested_dict(nested_dict=fields, keys=["edges", "node"])
|
|
251
|
+
|
|
252
|
+
if not node_fields:
|
|
253
|
+
# This means that it's purely a count query and as such we can override the limit to avoid
|
|
254
|
+
# returning data that will only be discarded
|
|
255
|
+
limit = 1
|
|
256
|
+
|
|
257
|
+
async with get_client(sync_client=False) as client:
|
|
258
|
+
response = await cls.query_events(client=client, filters=event_filter, limit=limit, offset=offset)
|
|
259
|
+
nodes = [{"node": event.to_graphql()} for event in response.events]
|
|
260
|
+
|
|
261
|
+
return {"count": response.count, "edges": nodes}
|
infrahub/task_manager/models.py
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
1
4
|
from collections import defaultdict
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
2
6
|
from uuid import UUID
|
|
3
7
|
|
|
4
|
-
from prefect.client.schemas.objects import Log as PrefectLog
|
|
8
|
+
from prefect.client.schemas.objects import Log as PrefectLog # noqa: TC002
|
|
9
|
+
from prefect.events.filters import (
|
|
10
|
+
EventFilter,
|
|
11
|
+
EventIDFilter,
|
|
12
|
+
EventNameFilter,
|
|
13
|
+
EventOccurredFilter,
|
|
14
|
+
EventRelatedFilter,
|
|
15
|
+
EventResourceFilter,
|
|
16
|
+
)
|
|
17
|
+
from prefect.events.schemas.events import ResourceSpecification
|
|
5
18
|
from pydantic import BaseModel, Field
|
|
6
19
|
|
|
20
|
+
from infrahub.core.timestamp import Timestamp
|
|
21
|
+
|
|
7
22
|
from .constants import LOG_LEVEL_MAPPING
|
|
8
23
|
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from datetime import datetime
|
|
26
|
+
|
|
9
27
|
|
|
10
28
|
class RelatedNodeInfo(BaseModel):
|
|
11
29
|
id: str
|
|
@@ -13,7 +31,7 @@ class RelatedNodeInfo(BaseModel):
|
|
|
13
31
|
|
|
14
32
|
|
|
15
33
|
class RelatedNodesInfo(BaseModel):
|
|
16
|
-
flows: dict[UUID, dict[str, RelatedNodeInfo]] = Field(default_factory=lambda: defaultdict(dict))
|
|
34
|
+
flows: dict[UUID, dict[str, RelatedNodeInfo]] = Field(default_factory=lambda: defaultdict(dict)) # type: ignore[arg-type]
|
|
17
35
|
nodes: dict[str, RelatedNodeInfo] = Field(default_factory=dict)
|
|
18
36
|
|
|
19
37
|
def add_nodes(self, flow_id: UUID, node_ids: list[str]) -> None:
|
|
@@ -46,7 +64,7 @@ class RelatedNodesInfo(BaseModel):
|
|
|
46
64
|
|
|
47
65
|
|
|
48
66
|
class FlowLogs(BaseModel):
|
|
49
|
-
logs: defaultdict[UUID, list[PrefectLog]] = Field(default_factory=lambda: defaultdict(list))
|
|
67
|
+
logs: defaultdict[UUID, list[PrefectLog]] = Field(default_factory=lambda: defaultdict(list)) # type: ignore[arg-type]
|
|
50
68
|
|
|
51
69
|
def to_graphql(self, flow_id: UUID) -> list[dict]:
|
|
52
70
|
return [
|
|
@@ -63,3 +81,129 @@ class FlowLogs(BaseModel):
|
|
|
63
81
|
|
|
64
82
|
class FlowProgress(BaseModel):
|
|
65
83
|
data: dict[UUID, float] = Field(default_factory=dict)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class InfrahubEventFilter(EventFilter):
|
|
87
|
+
matching_related: list[EventRelatedFilter] = Field(default_factory=list)
|
|
88
|
+
|
|
89
|
+
def add_account_filter(self, account__ids: list[str] | None) -> None:
|
|
90
|
+
if account__ids:
|
|
91
|
+
self.matching_related.append(
|
|
92
|
+
EventRelatedFilter(
|
|
93
|
+
labels=ResourceSpecification(
|
|
94
|
+
{"prefect.resource.role": "infrahub.account", "infrahub.resource.id": account__ids}
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def add_branch_filter(self, branches: list[str] | None = None) -> None:
|
|
100
|
+
if branches:
|
|
101
|
+
self.matching_related.append(
|
|
102
|
+
EventRelatedFilter(
|
|
103
|
+
labels=ResourceSpecification(
|
|
104
|
+
{"prefect.resource.role": "infrahub.branch", "infrahub.resource.label": branches}
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def add_event_filter(self, level: int | None = None, has_children: bool | None = None) -> None:
|
|
110
|
+
event_filter: dict[str, list[str] | str] = {}
|
|
111
|
+
if level is not None:
|
|
112
|
+
event_filter["infrahub.event.level"] = str(level)
|
|
113
|
+
|
|
114
|
+
if has_children is not None:
|
|
115
|
+
event_filter["infrahub.event.has_children"] = str(has_children).lower()
|
|
116
|
+
|
|
117
|
+
if event_filter:
|
|
118
|
+
event_filter["prefect.resource.role"] = "infrahub.event"
|
|
119
|
+
self.matching_related.append(EventRelatedFilter(labels=ResourceSpecification(event_filter)))
|
|
120
|
+
|
|
121
|
+
def add_event_id_filter(self, ids: list[str] | None = None) -> None:
|
|
122
|
+
if ids:
|
|
123
|
+
self.id = EventIDFilter(id=[uuid.UUID(id) for id in ids])
|
|
124
|
+
|
|
125
|
+
def add_event_type_filter(
|
|
126
|
+
self, event_type: list[str] | None = None, event_type_filter: dict[str, Any] | None = None
|
|
127
|
+
) -> None:
|
|
128
|
+
event_type = event_type or []
|
|
129
|
+
event_type_filter = event_type_filter or {}
|
|
130
|
+
|
|
131
|
+
if branch_merged := event_type_filter.get("branch_merged"):
|
|
132
|
+
branches: list[str] = branch_merged.get("branches") or []
|
|
133
|
+
if "infrahub.branch.created" not in event_type:
|
|
134
|
+
event_type.append("infrahub.branch.merged")
|
|
135
|
+
if branches:
|
|
136
|
+
self.resource = EventResourceFilter(labels=ResourceSpecification({"infrahub.branch.name": branches}))
|
|
137
|
+
|
|
138
|
+
if branch_rebased := event_type_filter.get("branch_rebased"):
|
|
139
|
+
branches = branch_rebased.get("branches") or []
|
|
140
|
+
if "infrahub.branch.created" not in event_type:
|
|
141
|
+
event_type.append("infrahub.branch.rebased")
|
|
142
|
+
if branches:
|
|
143
|
+
self.resource = EventResourceFilter(labels=ResourceSpecification({"infrahub.branch.name": branches}))
|
|
144
|
+
|
|
145
|
+
if event_type:
|
|
146
|
+
self.event = EventNameFilter(name=event_type)
|
|
147
|
+
|
|
148
|
+
def add_primary_node_filter(self, primary_node__ids: list[str] | None) -> None:
|
|
149
|
+
if primary_node__ids:
|
|
150
|
+
self.resource = EventResourceFilter(labels=ResourceSpecification({"infrahub.node.id": primary_node__ids}))
|
|
151
|
+
|
|
152
|
+
def add_parent_filter(self, parent__ids: list[str] | None) -> None:
|
|
153
|
+
if parent__ids:
|
|
154
|
+
self.matching_related.append(
|
|
155
|
+
EventRelatedFilter(
|
|
156
|
+
labels=ResourceSpecification(
|
|
157
|
+
{"prefect.resource.role": "infrahub.child_event", "infrahub.event_parent.id": parent__ids}
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def add_related_node_filter(self, related_node__ids: list[str] | None) -> None:
|
|
163
|
+
if related_node__ids:
|
|
164
|
+
self.matching_related.append(
|
|
165
|
+
EventRelatedFilter(
|
|
166
|
+
labels=ResourceSpecification(
|
|
167
|
+
{"prefect.resource.role": "infrahub.related.node", "prefect.resource.id": related_node__ids}
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def from_filters(
|
|
174
|
+
cls,
|
|
175
|
+
ids: list[str] | None = None,
|
|
176
|
+
account__ids: list[str] | None = None,
|
|
177
|
+
related_node__ids: list[str] | None = None,
|
|
178
|
+
parent__ids: list[str] | None = None,
|
|
179
|
+
primary_node__ids: list[str] | None = None,
|
|
180
|
+
event_type: list[str] | None = None,
|
|
181
|
+
event_type_filter: dict[str, Any] | None = None,
|
|
182
|
+
branches: list[str] | None = None,
|
|
183
|
+
level: int | None = None,
|
|
184
|
+
has_children: bool | None = None,
|
|
185
|
+
since: datetime | None = None,
|
|
186
|
+
until: datetime | None = None,
|
|
187
|
+
) -> InfrahubEventFilter:
|
|
188
|
+
occurred_filter = {}
|
|
189
|
+
if since:
|
|
190
|
+
occurred_filter["since"] = Timestamp(since.isoformat()).to_datetime()
|
|
191
|
+
|
|
192
|
+
if until:
|
|
193
|
+
occurred_filter["until"] = Timestamp(until.isoformat()).to_datetime()
|
|
194
|
+
|
|
195
|
+
if occurred_filter:
|
|
196
|
+
filters = cls(occurred=EventOccurredFilter(**occurred_filter))
|
|
197
|
+
else:
|
|
198
|
+
filters = cls()
|
|
199
|
+
|
|
200
|
+
filters.add_event_filter(level=level, has_children=has_children)
|
|
201
|
+
filters.add_event_id_filter(ids=ids)
|
|
202
|
+
filters.add_event_type_filter(event_type=event_type, event_type_filter=event_type_filter)
|
|
203
|
+
filters.add_branch_filter(branches=branches)
|
|
204
|
+
filters.add_account_filter(account__ids=account__ids)
|
|
205
|
+
filters.add_parent_filter(parent__ids=parent__ids)
|
|
206
|
+
filters.add_primary_node_filter(primary_node__ids=primary_node__ids)
|
|
207
|
+
filters.add_related_node_filter(related_node__ids=related_node__ids)
|
|
208
|
+
|
|
209
|
+
return filters
|
infrahub/task_manager/task.py
CHANGED
|
@@ -250,7 +250,7 @@ class PrefectTask:
|
|
|
250
250
|
"node": {
|
|
251
251
|
"title": flow.name,
|
|
252
252
|
"conclusion": CONCLUSION_STATE_MAPPING.get(
|
|
253
|
-
flow.state_name, TaskConclusion.UNKNOWN
|
|
253
|
+
str(flow.state_name), TaskConclusion.UNKNOWN
|
|
254
254
|
).value,
|
|
255
255
|
"state": flow.state_type,
|
|
256
256
|
"progress": progress_flow.data.get(flow.id, None),
|
infrahub/tasks/artifact.py
CHANGED
|
@@ -5,41 +5,42 @@ from prefect import task
|
|
|
5
5
|
from prefect.cache_policies import NONE
|
|
6
6
|
|
|
7
7
|
from infrahub import lock
|
|
8
|
+
from infrahub.artifacts.models import CheckArtifactCreate
|
|
8
9
|
from infrahub.core.constants import InfrahubKind
|
|
9
10
|
from infrahub.git.models import RequestArtifactGenerate
|
|
10
|
-
from infrahub.message_bus import messages
|
|
11
11
|
from infrahub.services import InfrahubServices
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
@task(name="define-artifact", task_run_name="Define Artifact", cache_policy=NONE)
|
|
14
|
+
@task(name="define-artifact", task_run_name="Define Artifact", cache_policy=NONE) # type: ignore[arg-type]
|
|
15
15
|
async def define_artifact(
|
|
16
|
-
|
|
17
|
-
) -> InfrahubNode:
|
|
18
|
-
if
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
16
|
+
model: Union[CheckArtifactCreate, RequestArtifactGenerate], service: InfrahubServices
|
|
17
|
+
) -> tuple[InfrahubNode, bool]:
|
|
18
|
+
"""Return an artifact together with a flag to indicate if the artifact is created now or already existed."""
|
|
19
|
+
created = False
|
|
20
|
+
if model.artifact_id:
|
|
21
|
+
artifact = await service.client.get(kind=InfrahubKind.ARTIFACT, id=model.artifact_id, branch=model.branch_name)
|
|
22
22
|
else:
|
|
23
|
-
async with lock.registry.get(f"{
|
|
23
|
+
async with lock.registry.get(f"{model.target_id}-{model.artifact_definition}", namespace="artifact"):
|
|
24
24
|
artifacts = await service.client.filters(
|
|
25
25
|
kind=InfrahubKind.ARTIFACT,
|
|
26
|
-
branch=
|
|
27
|
-
definition__ids=[
|
|
28
|
-
object__ids=[
|
|
26
|
+
branch=model.branch_name,
|
|
27
|
+
definition__ids=[model.artifact_definition],
|
|
28
|
+
object__ids=[model.target_id],
|
|
29
29
|
)
|
|
30
30
|
if artifacts:
|
|
31
31
|
artifact = artifacts[0]
|
|
32
32
|
else:
|
|
33
33
|
artifact = await service.client.create(
|
|
34
34
|
kind=InfrahubKind.ARTIFACT,
|
|
35
|
-
branch=
|
|
35
|
+
branch=model.branch_name,
|
|
36
36
|
data={
|
|
37
|
-
"name":
|
|
37
|
+
"name": model.artifact_name,
|
|
38
38
|
"status": "Pending",
|
|
39
|
-
"object":
|
|
40
|
-
"definition":
|
|
41
|
-
"content_type":
|
|
39
|
+
"object": model.target_id,
|
|
40
|
+
"definition": model.artifact_definition,
|
|
41
|
+
"content_type": model.content_type,
|
|
42
42
|
},
|
|
43
43
|
)
|
|
44
44
|
await artifact.save()
|
|
45
|
-
|
|
45
|
+
created = True
|
|
46
|
+
return artifact, created
|
infrahub/tasks/registry.py
CHANGED
|
@@ -18,7 +18,7 @@ async def refresh_branches(db: InfrahubDatabase) -> None:
|
|
|
18
18
|
If a branch is already present with a different value for the hash
|
|
19
19
|
We pull the new schema from the database and we update the registry.
|
|
20
20
|
"""
|
|
21
|
-
from infrahub.graphql.manager import GraphQLSchemaManager
|
|
21
|
+
from infrahub.graphql.manager import GraphQLSchemaManager
|
|
22
22
|
|
|
23
23
|
async with lock.registry.local_schema_lock():
|
|
24
24
|
branches = await registry.branch_object.get_list(db=db)
|