infrahub-server 1.1.6__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 +54 -22
- infrahub/core/branch/models.py +4 -4
- infrahub/core/branch/tasks.py +137 -129
- 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 +12 -8
- infrahub/core/diff/coordinator.py +49 -70
- infrahub/core/diff/data_check_synchronizer.py +86 -7
- infrahub/core/diff/enricher/aggregated.py +3 -3
- infrahub/core/diff/enricher/cardinality_one.py +7 -7
- infrahub/core/diff/enricher/hierarchy.py +22 -7
- infrahub/core/diff/enricher/labels.py +19 -4
- infrahub/core/diff/enricher/path_identifier.py +7 -9
- infrahub/core/diff/enricher/summary_counts.py +3 -1
- infrahub/core/diff/merger/merger.py +8 -4
- infrahub/core/diff/model/path.py +76 -35
- infrahub/core/diff/parent_node_adder.py +78 -0
- infrahub/core/diff/payload_builder.py +13 -2
- infrahub/core/diff/query/all_conflicts.py +6 -3
- infrahub/core/diff/query/artifact.py +1 -1
- infrahub/core/diff/query/delete_query.py +1 -1
- infrahub/core/diff/query/diff_get.py +3 -2
- infrahub/core/diff/query/diff_summary.py +1 -1
- infrahub/core/diff/query/field_specifiers.py +3 -1
- infrahub/core/diff/query/field_summary.py +3 -2
- infrahub/core/diff/query/filters.py +14 -3
- infrahub/core/diff/query/get_conflict_query.py +1 -1
- infrahub/core/diff/query/has_conflicts_query.py +6 -3
- infrahub/core/diff/query/merge.py +3 -3
- infrahub/core/diff/query/{drop_tracking_id.py → merge_tracking_id.py} +4 -4
- infrahub/core/diff/query/roots_metadata.py +9 -2
- infrahub/core/diff/query/save.py +233 -142
- infrahub/core/diff/query/summary_counts_enricher.py +267 -0
- infrahub/core/diff/query/time_range_query.py +3 -2
- infrahub/core/diff/query/update_conflict_query.py +1 -1
- infrahub/core/diff/query_parser.py +49 -24
- infrahub/core/diff/repository/deserializer.py +32 -28
- infrahub/core/diff/repository/repository.py +215 -41
- 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 +170 -46
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/constraints/grouped_uniqueness.py +9 -2
- infrahub/core/node/delete_validator.py +4 -4
- infrahub/core/node/ipam.py +13 -8
- infrahub/core/node/permissions.py +4 -0
- infrahub/core/node/resource_manager/ip_prefix_pool.py +8 -5
- infrahub/core/node/standard.py +3 -5
- infrahub/core/property.py +1 -1
- infrahub/core/protocols.py +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 +45 -7
- infrahub/core/query/ipam.py +4 -4
- infrahub/core/query/node.py +19 -14
- infrahub/core/query/relationship.py +213 -26
- infrahub/core/query/resource_manager.py +13 -11
- infrahub/core/query/standard_node.py +6 -6
- infrahub/core/query/task.py +3 -3
- infrahub/core/query/task_log.py +1 -1
- infrahub/core/query/utils.py +5 -5
- infrahub/core/registry.py +0 -2
- infrahub/core/relationship/constraints/count.py +1 -1
- infrahub/core/relationship/constraints/peer_kind.py +1 -1
- infrahub/core/relationship/model.py +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 +3 -2
- infrahub/core/validators/attribute/choices.py +1 -1
- infrahub/core/validators/attribute/enum.py +1 -1
- infrahub/core/validators/attribute/kind.py +1 -1
- infrahub/core/validators/attribute/length.py +1 -1
- infrahub/core/validators/attribute/optional.py +1 -1
- infrahub/core/validators/attribute/regex.py +1 -1
- infrahub/core/validators/attribute/unique.py +1 -1
- infrahub/core/validators/checks_runner.py +37 -0
- infrahub/core/validators/node/generate_profile.py +1 -1
- infrahub/core/validators/node/hierarchy.py +1 -1
- infrahub/core/validators/query.py +1 -1
- infrahub/core/validators/relationship/count.py +1 -1
- infrahub/core/validators/relationship/optional.py +1 -1
- infrahub/core/validators/relationship/peer.py +1 -1
- infrahub/core/validators/tasks.py +8 -6
- infrahub/core/validators/uniqueness/query.py +20 -17
- infrahub/database/__init__.py +16 -2
- infrahub/database/memgraph.py +1 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +0 -2
- infrahub/dependencies/builder/diff/combiner.py +1 -1
- infrahub/dependencies/builder/diff/conflicts_enricher.py +1 -1
- infrahub/dependencies/builder/diff/coordinator.py +0 -2
- infrahub/dependencies/builder/diff/deserializer.py +4 -2
- infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
- infrahub/dependencies/builder/diff/enricher/summary_counts.py +1 -1
- 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 -13
- infrahub/graphql/mutations/diff.py +54 -14
- 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 +243 -50
- infrahub/graphql/mutations/menu.py +10 -10
- infrahub/graphql/mutations/proposed_change.py +36 -28
- infrahub/graphql/mutations/relationship.py +343 -104
- 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 +16 -10
- 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 +43 -27
- infrahub/graphql/queries/search.py +9 -8
- infrahub/graphql/queries/status.py +12 -9
- infrahub/graphql/queries/task.py +11 -9
- infrahub/graphql/resolvers/resolver.py +69 -43
- infrahub/graphql/resolvers/single_relationship.py +16 -10
- infrahub/graphql/schema.py +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/__init__.py +2 -1
- infrahub/permissions/globals.py +15 -0
- infrahub/permissions/types.py +26 -0
- infrahub/pools/prefix.py +29 -165
- infrahub/prefect_server/__init__.py +0 -0
- infrahub/prefect_server/app.py +18 -0
- infrahub/prefect_server/database.py +20 -0
- infrahub/prefect_server/events.py +28 -0
- infrahub/prefect_server/models.py +46 -0
- infrahub/proposed_change/models.py +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/client.py +8 -0
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/check.py +3 -3
- 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 +4 -19
- infrahub_sdk/ctl/validate.py +2 -1
- infrahub_sdk/exceptions.py +12 -0
- infrahub_sdk/generator.py +3 -0
- infrahub_sdk/node.py +4 -4
- infrahub_sdk/protocols.py +21 -8
- infrahub_sdk/schema/__init__.py +14 -2
- 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/timestamp.py +134 -33
- infrahub_sdk/utils.py +39 -1
- infrahub_sdk/yaml.py +2 -3
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/METADATA +47 -12
- infrahub_server-1.2.0b1.dist-info/RECORD +725 -0
- infrahub_testcontainers/container.py +14 -6
- infrahub_testcontainers/docker-compose.test.yml +24 -5
- infrahub_testcontainers/haproxy.cfg +43 -0
- infrahub_testcontainers/helpers.py +85 -1
- infrahub/core/branch/constants.py +0 -2
- infrahub/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_server-1.1.6.dist-info/RECORD +0 -681
- /infrahub/{schema → artifacts}/__init__.py +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/WHEEL +0 -0
- {infrahub_server-1.1.6.dist-info → infrahub_server-1.2.0b1.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from prefect import flow
|
|
2
4
|
|
|
3
5
|
from infrahub.core import registry
|
|
@@ -7,7 +9,7 @@ from infrahub.core.diff.repository.repository import DiffRepository
|
|
|
7
9
|
from infrahub.dependencies.registry import get_component_registry
|
|
8
10
|
from infrahub.log import get_logger
|
|
9
11
|
from infrahub.message_bus import InfrahubMessage, messages
|
|
10
|
-
from infrahub.services import InfrahubServices
|
|
12
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
11
13
|
from infrahub.workflows.catalogue import (
|
|
12
14
|
DIFF_UPDATE,
|
|
13
15
|
TRIGGER_ARTIFACT_DEFINITION_GENERATE,
|
|
@@ -33,11 +35,13 @@ async def merge(message: messages.EventBranchMerge, service: InfrahubServices) -
|
|
|
33
35
|
|
|
34
36
|
await service.workflow.submit_workflow(
|
|
35
37
|
workflow=TRIGGER_ARTIFACT_DEFINITION_GENERATE,
|
|
38
|
+
context=message.context,
|
|
36
39
|
parameters={"branch": message.target_branch},
|
|
37
40
|
)
|
|
38
41
|
|
|
39
42
|
await service.workflow.submit_workflow(
|
|
40
43
|
workflow=TRIGGER_GENERATOR_DEFINITION_RUN,
|
|
44
|
+
context=message.context,
|
|
41
45
|
parameters={"branch": message.target_branch},
|
|
42
46
|
)
|
|
43
47
|
|
|
@@ -49,9 +53,9 @@ async def merge(message: messages.EventBranchMerge, service: InfrahubServices) -
|
|
|
49
53
|
):
|
|
50
54
|
request_diff_update_model = RequestDiffUpdate(branch_name=diff_root.diff_branch_name)
|
|
51
55
|
await service.workflow.submit_workflow(
|
|
52
|
-
workflow=DIFF_UPDATE, parameters={"model": request_diff_update_model}
|
|
56
|
+
workflow=DIFF_UPDATE, context=message.context, parameters={"model": request_diff_update_model}
|
|
53
57
|
)
|
|
54
58
|
|
|
55
59
|
for event in events:
|
|
56
60
|
event.assign_meta(parent=message)
|
|
57
|
-
await service.send(message=event)
|
|
61
|
+
await service.message_bus.send(message=event)
|
|
@@ -2,11 +2,8 @@ from prefect import flow
|
|
|
2
2
|
|
|
3
3
|
from infrahub.message_bus import messages
|
|
4
4
|
from infrahub.services import InfrahubServices
|
|
5
|
-
from infrahub.workflows.catalogue import WEBHOOK_CONFIGURE
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
@flow(name="event-worker-newprimary-api")
|
|
9
8
|
async def new_primary_api(message: messages.EventWorkerNewPrimaryAPI, service: InfrahubServices) -> None:
|
|
10
9
|
service.log.info("api_worker promoted to primary", worker_id=message.worker_id)
|
|
11
|
-
|
|
12
|
-
await service.workflow.submit_workflow(workflow=WEBHOOK_CONFIGURE)
|
|
@@ -67,7 +67,7 @@ async def execution(message: messages.FinalizeValidatorExecution, service: Infra
|
|
|
67
67
|
validator_id=message.validator_id,
|
|
68
68
|
validator_execution_id=message.validator_execution_id,
|
|
69
69
|
)
|
|
70
|
-
await service.send(message=message, delay=MessageTTL.FIVE)
|
|
70
|
+
await service.message_bus.send(message=message, delay=MessageTTL.FIVE)
|
|
71
71
|
return
|
|
72
72
|
|
|
73
73
|
log.info(
|
|
@@ -27,8 +27,8 @@ async def get(message: messages.GitFileGet, service: InfrahubServices) -> None:
|
|
|
27
27
|
except (FileOutOfRepositoryError, RepositoryFileNotFoundError) as e:
|
|
28
28
|
if message.reply_requested:
|
|
29
29
|
response = GitFileGetResponse(data=GitFileGetResponseData(error_message=e.message, http_code=e.HTTP_CODE))
|
|
30
|
-
await service.
|
|
30
|
+
await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
|
|
31
31
|
else:
|
|
32
32
|
if message.reply_requested:
|
|
33
33
|
response = GitFileGetResponse(data=GitFileGetResponseData(content=content))
|
|
34
|
-
await service.
|
|
34
|
+
await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
|
|
@@ -28,7 +28,7 @@ async def connectivity(message: messages.GitRepositoryConnectivity, service: Inf
|
|
|
28
28
|
response = GitRepositoryConnectivityResponse(
|
|
29
29
|
data=response_data,
|
|
30
30
|
)
|
|
31
|
-
await service.
|
|
31
|
+
await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@flow(name="refresh-git-fetch", flow_run_name="Fetch git repository {message.repository_name} on " + WORKER_IDENTITY)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from infrahub_sdk.uuidt import UUIDT
|
|
4
2
|
from prefect import flow
|
|
5
3
|
from prefect.logging import get_run_logger
|
|
@@ -125,10 +123,10 @@ async def check(message: messages.RequestGeneratorDefinitionCheck, service: Infr
|
|
|
125
123
|
)
|
|
126
124
|
for event in events:
|
|
127
125
|
event.assign_meta(parent=message)
|
|
128
|
-
await service.send(message=event)
|
|
126
|
+
await service.message_bus.send(message=event)
|
|
129
127
|
|
|
130
128
|
|
|
131
|
-
def _run_generator(instance_id:
|
|
129
|
+
def _run_generator(instance_id: str | None, managed_branch: bool, impacted_instances: list[str]) -> bool:
|
|
132
130
|
"""Returns a boolean to indicate if a generator instance needs to be executed
|
|
133
131
|
Will return true if:
|
|
134
132
|
* The instance_id wasn't set which could be that it's a new object that doesn't have a previous generator instance
|
|
@@ -11,6 +11,7 @@ from infrahub.core.constants import CheckType, InfrahubKind, RepositoryInternalS
|
|
|
11
11
|
from infrahub.core.diff.coordinator import DiffCoordinator
|
|
12
12
|
from infrahub.core.registry import registry
|
|
13
13
|
from infrahub.dependencies.registry import get_component_registry
|
|
14
|
+
from infrahub.git.models import TriggerRepositoryInternalChecks
|
|
14
15
|
from infrahub.git.repository import InfrahubRepository
|
|
15
16
|
from infrahub.message_bus import InfrahubMessage, messages
|
|
16
17
|
from infrahub.message_bus.types import (
|
|
@@ -20,6 +21,7 @@ from infrahub.message_bus.types import (
|
|
|
20
21
|
ProposedChangeSubscriber,
|
|
21
22
|
)
|
|
22
23
|
from infrahub.proposed_change.models import (
|
|
24
|
+
RequestArtifactDefinitionCheck,
|
|
23
25
|
RequestProposedChangeDataIntegrity,
|
|
24
26
|
RequestProposedChangeRepositoryChecks,
|
|
25
27
|
RequestProposedChangeRunGenerators,
|
|
@@ -28,6 +30,8 @@ from infrahub.proposed_change.models import (
|
|
|
28
30
|
)
|
|
29
31
|
from infrahub.services import InfrahubServices # noqa: TC001
|
|
30
32
|
from infrahub.workflows.catalogue import (
|
|
33
|
+
GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER,
|
|
34
|
+
REQUEST_ARTIFACT_DEFINITION_CHECK,
|
|
31
35
|
REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
|
|
32
36
|
REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
33
37
|
REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
|
|
@@ -74,17 +78,15 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
74
78
|
):
|
|
75
79
|
for repo in repositories:
|
|
76
80
|
if not repo.read_only and repo.internal_status == RepositoryInternalStatus.ACTIVE.value:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
model = TriggerRepositoryInternalChecks(
|
|
82
|
+
proposed_change=message.proposed_change,
|
|
83
|
+
repository=repo.repository_id,
|
|
84
|
+
source_branch=repo.source_branch,
|
|
85
|
+
target_branch=repo.destination_branch,
|
|
86
|
+
)
|
|
87
|
+
await service.workflow.submit_workflow(
|
|
88
|
+
workflow=GIT_REPOSITORY_INTERNAL_CHECKS_TRIGGER, parameters={"model": model}
|
|
84
89
|
)
|
|
85
|
-
for event in events:
|
|
86
|
-
event.assign_meta(parent=message)
|
|
87
|
-
await service.send(message=event)
|
|
88
90
|
return
|
|
89
91
|
|
|
90
92
|
await _gather_repository_repository_diffs(repositories=repositories, service=service)
|
|
@@ -103,6 +105,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
103
105
|
if message.check_type is CheckType.ARTIFACT:
|
|
104
106
|
events.append(
|
|
105
107
|
messages.RequestProposedChangeRefreshArtifacts(
|
|
108
|
+
context=message.context,
|
|
106
109
|
proposed_change=message.proposed_change,
|
|
107
110
|
source_branch=message.source_branch,
|
|
108
111
|
source_branch_sync_with_git=message.source_branch_sync_with_git,
|
|
@@ -122,7 +125,9 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
122
125
|
do_repository_checks=message.check_type is CheckType.ALL,
|
|
123
126
|
)
|
|
124
127
|
await service.workflow.submit_workflow(
|
|
125
|
-
workflow=REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
|
|
128
|
+
workflow=REQUEST_PROPOSED_CHANGE_RUN_GENERATORS,
|
|
129
|
+
context=message.context,
|
|
130
|
+
parameters={"model": model_proposed_change_run_generator},
|
|
126
131
|
)
|
|
127
132
|
|
|
128
133
|
if message.check_type in [CheckType.ALL, CheckType.DATA] and branch_diff.has_node_changes(
|
|
@@ -136,7 +141,9 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
136
141
|
branch_diff=branch_diff,
|
|
137
142
|
)
|
|
138
143
|
await service.workflow.submit_workflow(
|
|
139
|
-
workflow=REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
|
|
144
|
+
workflow=REQUEST_PROPOSED_CHANGE_DATA_INTEGRITY,
|
|
145
|
+
context=message.context,
|
|
146
|
+
parameters={"model": model_proposed_change_data_integrity},
|
|
140
147
|
)
|
|
141
148
|
|
|
142
149
|
if message.check_type in [CheckType.REPOSITORY, CheckType.USER]:
|
|
@@ -148,7 +155,9 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
148
155
|
branch_diff=branch_diff,
|
|
149
156
|
)
|
|
150
157
|
await service.workflow.submit_workflow(
|
|
151
|
-
workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
158
|
+
workflow=REQUEST_PROPOSED_CHANGE_REPOSITORY_CHECKS,
|
|
159
|
+
context=message.context,
|
|
160
|
+
parameters={"model": model_proposed_change_repo_checks},
|
|
152
161
|
)
|
|
153
162
|
|
|
154
163
|
if message.check_type in [CheckType.ALL, CheckType.SCHEMA] and branch_diff.has_data_changes(
|
|
@@ -156,6 +165,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
156
165
|
):
|
|
157
166
|
await service.workflow.submit_workflow(
|
|
158
167
|
workflow=REQUEST_PROPOSED_CHANGE_SCHEMA_INTEGRITY,
|
|
168
|
+
context=message.context,
|
|
159
169
|
parameters={
|
|
160
170
|
"model": RequestProposedChangeSchemaIntegrity(
|
|
161
171
|
proposed_change=message.proposed_change,
|
|
@@ -170,6 +180,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
170
180
|
if message.check_type in [CheckType.ALL, CheckType.TEST]:
|
|
171
181
|
await service.workflow.submit_workflow(
|
|
172
182
|
workflow=REQUEST_PROPOSED_CHANGE_USER_TESTS,
|
|
183
|
+
context=message.context,
|
|
173
184
|
parameters={
|
|
174
185
|
"model": RequestProposedChangeUserTests(
|
|
175
186
|
proposed_change=message.proposed_change,
|
|
@@ -183,7 +194,7 @@ async def pipeline(message: messages.RequestProposedChangePipeline, service: Inf
|
|
|
183
194
|
|
|
184
195
|
for event in events:
|
|
185
196
|
event.assign_meta(parent=message)
|
|
186
|
-
await service.send(message=event)
|
|
197
|
+
await service.message_bus.send(message=event)
|
|
187
198
|
|
|
188
199
|
|
|
189
200
|
@flow(
|
|
@@ -232,7 +243,8 @@ async def refresh_artifacts(message: messages.RequestProposedChangeRefreshArtifa
|
|
|
232
243
|
|
|
233
244
|
if select:
|
|
234
245
|
log.info(f"Trigger processing of {artifact_definition.definition_name}")
|
|
235
|
-
|
|
246
|
+
model = RequestArtifactDefinitionCheck(
|
|
247
|
+
context=message.context,
|
|
236
248
|
artifact_definition=artifact_definition,
|
|
237
249
|
branch_diff=message.branch_diff,
|
|
238
250
|
proposed_change=message.proposed_change,
|
|
@@ -241,8 +253,7 @@ async def refresh_artifacts(message: messages.RequestProposedChangeRefreshArtifa
|
|
|
241
253
|
destination_branch=message.destination_branch,
|
|
242
254
|
)
|
|
243
255
|
|
|
244
|
-
|
|
245
|
-
await service.send(message=msg)
|
|
256
|
+
await service.workflow.submit_workflow(REQUEST_ARTIFACT_DEFINITION_CHECK, parameters={"model": model})
|
|
246
257
|
|
|
247
258
|
|
|
248
259
|
GATHER_ARTIFACT_DEFINITIONS = """
|
|
@@ -520,7 +531,7 @@ async def _get_proposed_change_repositories(
|
|
|
520
531
|
return _parse_proposed_change_repositories(message=message, source=source_all, destination=destination_all)
|
|
521
532
|
|
|
522
533
|
|
|
523
|
-
@task(name="proposed-change-validate-repository-conflicts", task_run_name="Validate conflicts on repository")
|
|
534
|
+
@task(name="proposed-change-validate-repository-conflicts", task_run_name="Validate conflicts on repository") # type: ignore[arg-type]
|
|
524
535
|
async def _validate_repository_merge_conflicts(
|
|
525
536
|
repositories: list[ProposedChangeRepository], service: InfrahubServices
|
|
526
537
|
) -> bool:
|
|
@@ -529,7 +540,10 @@ async def _validate_repository_merge_conflicts(
|
|
|
529
540
|
for repo in repositories:
|
|
530
541
|
if repo.has_diff and not repo.is_staging:
|
|
531
542
|
git_repo = await InfrahubRepository.init(
|
|
532
|
-
id=repo.repository_id,
|
|
543
|
+
id=repo.repository_id,
|
|
544
|
+
name=repo.repository_name,
|
|
545
|
+
client=service.client,
|
|
546
|
+
service=service,
|
|
533
547
|
)
|
|
534
548
|
async with lock.registry.get(name=repo.repository_name, namespace="repository"):
|
|
535
549
|
repo.conflicts = await git_repo.get_conflicts(
|
|
@@ -551,7 +565,10 @@ async def _gather_repository_repository_diffs(
|
|
|
551
565
|
if repo.has_diff and repo.source_commit and repo.destination_commit:
|
|
552
566
|
# TODO we need to find a way to return all files in the repo if the repo is new
|
|
553
567
|
git_repo = await InfrahubRepository.init(
|
|
554
|
-
id=repo.repository_id,
|
|
568
|
+
id=repo.repository_id,
|
|
569
|
+
name=repo.repository_name,
|
|
570
|
+
client=service.client,
|
|
571
|
+
service=service,
|
|
555
572
|
)
|
|
556
573
|
|
|
557
574
|
files_changed: list[str] = []
|
|
@@ -10,4 +10,4 @@ async def request(message: messages.SendEchoRequest, service: InfrahubServices)
|
|
|
10
10
|
service.log.info(f"Received message: {message.message}")
|
|
11
11
|
if message.reply_requested:
|
|
12
12
|
response = SendEchoRequestResponse(data=SendEchoRequestResponseData(response=f"Reply to: {message.message}"))
|
|
13
|
-
await service.
|
|
13
|
+
await service.message_bus.reply_if_initiator_meta(message=response, initiator=message)
|
infrahub/message_bus/types.py
CHANGED
|
@@ -9,7 +9,7 @@ from pydantic import BaseModel, Field
|
|
|
9
9
|
from infrahub.core.constants import InfrahubKind, RepositoryInternalStatus
|
|
10
10
|
from infrahub.exceptions import NodeNotFoundError
|
|
11
11
|
|
|
12
|
-
SCHEMA_CHANGE = re.compile("^Schema[A-Z]")
|
|
12
|
+
SCHEMA_CHANGE = re.compile(r"^Schema[A-Z]")
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class MessageTTL(int, Enum):
|
infrahub/permissions/__init__.py
CHANGED
|
@@ -2,12 +2,13 @@ from infrahub.permissions.backend import PermissionBackend
|
|
|
2
2
|
from infrahub.permissions.local_backend import LocalPermissionBackend
|
|
3
3
|
from infrahub.permissions.manager import PermissionManager
|
|
4
4
|
from infrahub.permissions.report import report_schema_permissions
|
|
5
|
-
from infrahub.permissions.types import AssignedPermissions
|
|
5
|
+
from infrahub.permissions.types import AssignedPermissions, get_global_permission_for_kind
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"AssignedPermissions",
|
|
9
9
|
"LocalPermissionBackend",
|
|
10
10
|
"PermissionBackend",
|
|
11
11
|
"PermissionManager",
|
|
12
|
+
"get_global_permission_for_kind",
|
|
12
13
|
"report_schema_permissions",
|
|
13
14
|
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from infrahub.core.account import GlobalPermission
|
|
2
|
+
from infrahub.core.constants import GLOBAL_BRANCH_NAME, GlobalPermissions, PermissionDecision
|
|
3
|
+
from infrahub.core.registry import registry
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def define_global_permission_from_branch(permission: GlobalPermissions, branch_name: str) -> GlobalPermission:
|
|
7
|
+
if branch_name in (GLOBAL_BRANCH_NAME, registry.default_branch):
|
|
8
|
+
decision = PermissionDecision.ALLOW_DEFAULT
|
|
9
|
+
else:
|
|
10
|
+
decision = PermissionDecision.ALLOW_OTHER
|
|
11
|
+
|
|
12
|
+
return GlobalPermission(
|
|
13
|
+
action=permission.value,
|
|
14
|
+
decision=decision.value,
|
|
15
|
+
)
|
infrahub/permissions/types.py
CHANGED
|
@@ -2,8 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, TypedDict
|
|
4
4
|
|
|
5
|
+
from infrahub.core.constants import GlobalPermissions, InfrahubKind
|
|
6
|
+
from infrahub.core.schema import NodeSchema
|
|
7
|
+
|
|
5
8
|
if TYPE_CHECKING:
|
|
6
9
|
from infrahub.core.account import GlobalPermission, ObjectPermission
|
|
10
|
+
from infrahub.core.schema import MainSchemaTypes
|
|
7
11
|
from infrahub.permissions.constants import BranchRelativePermissionDecision
|
|
8
12
|
|
|
9
13
|
|
|
@@ -18,3 +22,25 @@ class KindPermissions(TypedDict):
|
|
|
18
22
|
delete: BranchRelativePermissionDecision
|
|
19
23
|
update: BranchRelativePermissionDecision
|
|
20
24
|
view: BranchRelativePermissionDecision
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_global_permission_for_kind(schema: MainSchemaTypes) -> GlobalPermissions | None:
|
|
28
|
+
kind_permission_map = {
|
|
29
|
+
InfrahubKind.GENERICACCOUNT: GlobalPermissions.MANAGE_ACCOUNTS,
|
|
30
|
+
InfrahubKind.ACCOUNTGROUP: GlobalPermissions.MANAGE_ACCOUNTS,
|
|
31
|
+
InfrahubKind.ACCOUNTROLE: GlobalPermissions.MANAGE_ACCOUNTS,
|
|
32
|
+
InfrahubKind.BASEPERMISSION: GlobalPermissions.MANAGE_PERMISSIONS,
|
|
33
|
+
InfrahubKind.GENERICREPOSITORY: GlobalPermissions.MANAGE_REPOSITORIES,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if schema.kind in kind_permission_map:
|
|
37
|
+
return kind_permission_map[schema.kind]
|
|
38
|
+
|
|
39
|
+
if isinstance(schema, NodeSchema):
|
|
40
|
+
for base in schema.inherit_from:
|
|
41
|
+
try:
|
|
42
|
+
return kind_permission_map[base]
|
|
43
|
+
except KeyError:
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
return None
|
infrahub/pools/prefix.py
CHANGED
|
@@ -1,174 +1,38 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ipaddress
|
|
4
|
-
from
|
|
5
|
-
from ipaddress import IPv4Network, IPv6Network
|
|
6
|
-
from typing import Optional, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Literal
|
|
7
5
|
|
|
6
|
+
from netaddr import IPSet
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Class to automatically manage Prefixes and help to carve out sub-prefixes
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
def __init__(self, network: str) -> None:
|
|
15
|
-
self.network = ipaddress.ip_network(network)
|
|
16
|
-
|
|
17
|
-
# Define biggest and smallest possible masks
|
|
18
|
-
self.mask_biggest = self.network.prefixlen + 1
|
|
19
|
-
if self.network.version == 4:
|
|
20
|
-
self.mask_smallest = 32
|
|
21
|
-
else:
|
|
22
|
-
self.mask_smallest = 128
|
|
23
|
-
|
|
24
|
-
self.available_subnets = defaultdict(list)
|
|
25
|
-
self.sub_by_key: dict[str, Optional[str]] = OrderedDict()
|
|
26
|
-
self.sub_by_id: dict[str, str] = OrderedDict()
|
|
27
|
-
|
|
28
|
-
# Save the top level available subnet
|
|
29
|
-
for subnet in list(self.network.subnets(new_prefix=self.mask_biggest)):
|
|
30
|
-
self.available_subnets[self.mask_biggest].append(str(subnet))
|
|
31
|
-
|
|
32
|
-
def reserve(self, subnet: str, identifier: Optional[str] = None) -> bool:
|
|
33
|
-
"""
|
|
34
|
-
Indicate that a specific subnet is already reserved/used
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
# TODO Add check to make sure the subnet provided has the right size
|
|
38
|
-
sub = ipaddress.ip_network(subnet)
|
|
39
|
-
|
|
40
|
-
if int(sub.prefixlen) <= int(self.network.prefixlen):
|
|
41
|
-
raise ValueError(f"{subnet} do not have the right size ({sub.prefixlen},{self.network.prefixlen})")
|
|
42
|
-
|
|
43
|
-
if sub.supernet(new_prefix=self.network.prefixlen) != self.network:
|
|
44
|
-
raise ValueError(f"{subnet} is not part of this network")
|
|
45
|
-
|
|
46
|
-
# Check first if this ID as already done a reservation
|
|
47
|
-
if identifier and identifier in self.sub_by_id.keys():
|
|
48
|
-
if self.sub_by_id[identifier] == str(sub):
|
|
49
|
-
return True
|
|
50
|
-
raise ValueError(
|
|
51
|
-
f"this identifier ({identifier}) is already used but for a different resource ({self.sub_by_id[identifier]})"
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
if identifier and str(sub) in self.sub_by_key.keys():
|
|
55
|
-
raise ValueError(f"this subnet is already reserved but not with this identifier ({identifier})")
|
|
56
|
-
|
|
57
|
-
if str(sub) in self.sub_by_key.keys():
|
|
58
|
-
self.remove_subnet_from_available_list(sub)
|
|
59
|
-
return True
|
|
60
|
-
|
|
61
|
-
# Check if the subnet itself is available
|
|
62
|
-
# if available reserve and return
|
|
63
|
-
if subnet in self.available_subnets[sub.prefixlen]:
|
|
64
|
-
if identifier:
|
|
65
|
-
self.sub_by_id[identifier] = subnet
|
|
66
|
-
self.sub_by_key[subnet] = identifier
|
|
67
|
-
else:
|
|
68
|
-
self.sub_by_key[subnet] = None
|
|
69
|
-
|
|
70
|
-
self.remove_subnet_from_available_list(sub)
|
|
71
|
-
return True
|
|
72
|
-
|
|
73
|
-
# If not reserved already, check if the subnet is available
|
|
74
|
-
# start at sublen and check all available subnet
|
|
75
|
-
# increase 1 by 1 until we find the closer supernet available
|
|
76
|
-
# break it down and keep track of the other available subnets
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from infrahub.core.ipam.constants import IPNetworkType
|
|
77
10
|
|
|
78
|
-
for sublen in range(sub.prefixlen - 1, self.network.prefixlen, -1):
|
|
79
|
-
supernet = sub.supernet(new_prefix=sublen)
|
|
80
|
-
if str(supernet) in self.available_subnets[sublen]:
|
|
81
|
-
self.split_supernet(supernet=supernet, subnet=sub)
|
|
82
|
-
return self.reserve(subnet=subnet, identifier=identifier)
|
|
83
11
|
|
|
84
|
-
|
|
12
|
+
def get_next_available_prefix(pool: IPSet, prefix_length: int, prefix_ver: Literal[4, 6] = 4) -> IPNetworkType:
|
|
13
|
+
"""Get the next available prefix of a given prefix length from an IPSet.
|
|
85
14
|
|
|
86
|
-
|
|
87
|
-
|
|
15
|
+
Args:
|
|
16
|
+
pool: netaddr IPSet object with available subnets
|
|
17
|
+
prefix_length: length of the desired prefix
|
|
18
|
+
prefix_ver: IPSet can contain a mix of IPv4 and IPv6 subnets. This parameter specifies the IP version of prefix to acquire.
|
|
88
19
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
subs = supernet.subnets(new_prefix=clean_prefixlen)
|
|
109
|
-
next_sub: Union[IPv4Network, IPv6Network] = next(subs) # type: ignore[assignment]
|
|
110
|
-
self.split_supernet(supernet=supernet, subnet=next_sub)
|
|
111
|
-
self.reserve(subnet=str(next_sub), identifier=identifier)
|
|
112
|
-
return next_sub
|
|
113
|
-
|
|
114
|
-
raise IndexError("No More subnet available")
|
|
115
|
-
|
|
116
|
-
def get_nbr_available_subnets(self) -> dict[int, int]:
|
|
117
|
-
tmp = {}
|
|
118
|
-
for i in range(self.mask_biggest, self.mask_smallest + 1):
|
|
119
|
-
tmp[i] = len(self.available_subnets[i])
|
|
120
|
-
|
|
121
|
-
return tmp
|
|
122
|
-
|
|
123
|
-
def check_if_already_allocated(self, identifier: str) -> bool:
|
|
124
|
-
"""
|
|
125
|
-
Check if a subnet has already been allocated based on an identifier
|
|
126
|
-
|
|
127
|
-
Need to add the same capability based on Network address
|
|
128
|
-
If both identifier and subnet are provided, identifier take precedence
|
|
129
|
-
"""
|
|
130
|
-
if identifier in self.sub_by_id.keys():
|
|
131
|
-
return True
|
|
132
|
-
return False
|
|
133
|
-
|
|
134
|
-
def split_supernet(
|
|
135
|
-
self, supernet: Union[IPv4Network, IPv6Network], subnet: Union[IPv4Network, IPv6Network]
|
|
136
|
-
) -> None:
|
|
137
|
-
"""Split a supernet into smaller networks"""
|
|
138
|
-
|
|
139
|
-
# TODO ensure subnet is small than supernet
|
|
140
|
-
# TODO ensure that subnet is part of supernet
|
|
141
|
-
parent_net = supernet
|
|
142
|
-
for i in range(supernet.prefixlen + 1, subnet.prefixlen + 1):
|
|
143
|
-
tmp_net: list[Union[IPv4Network, IPv6Network]] = list(parent_net.subnets(new_prefix=i))
|
|
144
|
-
|
|
145
|
-
if i == subnet.prefixlen:
|
|
146
|
-
for net in tmp_net:
|
|
147
|
-
self.available_subnets[i].append(str(net))
|
|
148
|
-
else:
|
|
149
|
-
if subnet.subnet_of(other=tmp_net[0]): # type: ignore[arg-type]
|
|
150
|
-
parent = 0
|
|
151
|
-
other = 1
|
|
152
|
-
else:
|
|
153
|
-
parent = 1
|
|
154
|
-
other = 0
|
|
155
|
-
|
|
156
|
-
parent_net = tmp_net[parent]
|
|
157
|
-
self.available_subnets[i].append(str(tmp_net[other]))
|
|
158
|
-
|
|
159
|
-
self.remove_subnet_from_available_list(supernet)
|
|
160
|
-
|
|
161
|
-
def remove_subnet_from_available_list(self, subnet: Union[IPv4Network, IPv6Network]) -> None:
|
|
162
|
-
"""Remove a subnet from the list of available Subnet."""
|
|
163
|
-
try:
|
|
164
|
-
idx = self.available_subnets[subnet.prefixlen].index(str(subnet))
|
|
165
|
-
del self.available_subnets[subnet.prefixlen][idx]
|
|
166
|
-
except ValueError:
|
|
167
|
-
# Already removed
|
|
168
|
-
pass
|
|
169
|
-
|
|
170
|
-
# if idx:
|
|
171
|
-
# return True
|
|
172
|
-
# except:
|
|
173
|
-
# log.warn("Unable to remove %s from list of available subnets" % str(subnet))
|
|
174
|
-
# return False
|
|
20
|
+
Raises:
|
|
21
|
+
ValueError: If there are no available subnets in the pool
|
|
22
|
+
"""
|
|
23
|
+
prefix_ver_map = {
|
|
24
|
+
4: ipaddress.IPv4Network,
|
|
25
|
+
6: ipaddress.IPv6Network,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
filtered_pool = IPSet([])
|
|
29
|
+
for subnet in pool.iter_cidrs():
|
|
30
|
+
if isinstance(ipaddress.ip_network(str(subnet)), prefix_ver_map[prefix_ver]):
|
|
31
|
+
filtered_pool.add(subnet)
|
|
32
|
+
|
|
33
|
+
for cidr in filtered_pool.iter_cidrs():
|
|
34
|
+
if cidr.prefixlen <= prefix_length:
|
|
35
|
+
next_available = ipaddress.ip_network(f"{cidr.network}/{prefix_length}")
|
|
36
|
+
return next_available
|
|
37
|
+
|
|
38
|
+
raise ValueError("No available subnets in pool")
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, FastAPI
|
|
4
|
+
from prefect.server.api.server import create_app
|
|
5
|
+
|
|
6
|
+
from . import events
|
|
7
|
+
|
|
8
|
+
router = APIRouter(prefix="/infrahub")
|
|
9
|
+
|
|
10
|
+
router.include_router(events.router)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_infrahub_prefect() -> FastAPI:
|
|
14
|
+
app = create_app()
|
|
15
|
+
api_app: FastAPI = app.__dict__["api_app"]
|
|
16
|
+
api_app.include_router(router=router)
|
|
17
|
+
|
|
18
|
+
return app
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from prefect.server.events.schemas.events import ReceivedEvent
|
|
6
|
+
from prefect.server.events.storage import INTERACTIVE_PAGE_SIZE
|
|
7
|
+
from prefect.server.events.storage.database import raw_count_events, read_events
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from prefect.server.events.filters import EventFilter
|
|
11
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def query_events(
|
|
15
|
+
session: AsyncSession, filter: EventFilter, page_size: int = INTERACTIVE_PAGE_SIZE, offset: int | None = None
|
|
16
|
+
) -> tuple[list[ReceivedEvent], int]:
|
|
17
|
+
count = await raw_count_events(session, filter) # type: ignore[attr-defined]
|
|
18
|
+
page = await read_events(session, filter, limit=page_size, offset=offset) # type: ignore[attr-defined]
|
|
19
|
+
events = [ReceivedEvent.model_validate(e, from_attributes=True) for e in page]
|
|
20
|
+
return events, count
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from fastapi import APIRouter
|
|
2
|
+
from fastapi.param_functions import Depends
|
|
3
|
+
from prefect.server.database import PrefectDBInterface, provide_database_interface
|
|
4
|
+
|
|
5
|
+
from .database import query_events
|
|
6
|
+
from .models import InfrahubEventfilterInput, InfrahubEventPage
|
|
7
|
+
|
|
8
|
+
router = APIRouter(prefix="/events", tags=["Infrahub"])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@router.post(
|
|
12
|
+
"/filter",
|
|
13
|
+
)
|
|
14
|
+
async def read_events(
|
|
15
|
+
event_filter: InfrahubEventfilterInput,
|
|
16
|
+
db: PrefectDBInterface = Depends(provide_database_interface), # noqa: B008
|
|
17
|
+
) -> InfrahubEventPage:
|
|
18
|
+
event_filter.filter.set_prefix()
|
|
19
|
+
|
|
20
|
+
async with db.session_context() as session:
|
|
21
|
+
events, total = await query_events(
|
|
22
|
+
session=session, filter=event_filter.filter, page_size=event_filter.limit, offset=event_filter.offset
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
return InfrahubEventPage(
|
|
26
|
+
events=events,
|
|
27
|
+
total=total,
|
|
28
|
+
)
|