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,9 +1,15 @@
|
|
|
1
1
|
from collections import defaultdict
|
|
2
|
-
from typing import AsyncGenerator, Generator
|
|
2
|
+
from typing import AsyncGenerator, Generator, Iterable
|
|
3
|
+
|
|
4
|
+
from neo4j.exceptions import TransientError
|
|
3
5
|
|
|
4
6
|
from infrahub import config
|
|
5
7
|
from infrahub.core import registry
|
|
6
8
|
from infrahub.core.diff.query.field_summary import EnrichedDiffNodeFieldSummaryQuery
|
|
9
|
+
from infrahub.core.diff.query.summary_counts_enricher import (
|
|
10
|
+
DiffFieldsSummaryCountsEnricherQuery,
|
|
11
|
+
DiffNodesSummaryCountsEnricherQuery,
|
|
12
|
+
)
|
|
7
13
|
from infrahub.core.query.diff import DiffCountChanges
|
|
8
14
|
from infrahub.core.timestamp import Timestamp
|
|
9
15
|
from infrahub.database import InfrahubDatabase, retry_db_transaction
|
|
@@ -13,6 +19,7 @@ from infrahub.log import get_logger
|
|
|
13
19
|
from ..model.path import (
|
|
14
20
|
ConflictSelection,
|
|
15
21
|
EnrichedDiffConflict,
|
|
22
|
+
EnrichedDiffNode,
|
|
16
23
|
EnrichedDiffRoot,
|
|
17
24
|
EnrichedDiffRootMetadata,
|
|
18
25
|
EnrichedDiffs,
|
|
@@ -26,13 +33,13 @@ from ..query.all_conflicts import EnrichedDiffAllConflictsQuery
|
|
|
26
33
|
from ..query.delete_query import EnrichedDiffDeleteQuery
|
|
27
34
|
from ..query.diff_get import EnrichedDiffGetQuery
|
|
28
35
|
from ..query.diff_summary import DiffSummaryCounters, DiffSummaryQuery
|
|
29
|
-
from ..query.drop_tracking_id import EnrichedDiffDropTrackingIdQuery
|
|
30
36
|
from ..query.field_specifiers import EnrichedDiffFieldSpecifiersQuery
|
|
31
37
|
from ..query.filters import EnrichedDiffQueryFilters
|
|
32
38
|
from ..query.get_conflict_query import EnrichedDiffConflictQuery
|
|
33
39
|
from ..query.has_conflicts_query import EnrichedDiffHasConflictQuery
|
|
40
|
+
from ..query.merge_tracking_id import EnrichedDiffMergedTrackingIdQuery
|
|
34
41
|
from ..query.roots_metadata import EnrichedDiffRootsMetadataQuery
|
|
35
|
-
from ..query.save import
|
|
42
|
+
from ..query.save import EnrichedDiffRootsUpsertQuery, EnrichedNodeBatchCreateQuery, EnrichedNodesLinkQuery
|
|
36
43
|
from ..query.time_range_query import EnrichedDiffTimeRangeQuery
|
|
37
44
|
from ..query.update_conflict_query import EnrichedDiffConflictUpdateQuery
|
|
38
45
|
from .deserializer import EnrichedDiffDeserializer
|
|
@@ -41,17 +48,17 @@ log = get_logger()
|
|
|
41
48
|
|
|
42
49
|
|
|
43
50
|
class DiffRepository:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def __init__(self, db: InfrahubDatabase, deserializer: EnrichedDiffDeserializer):
|
|
51
|
+
def __init__(self, db: InfrahubDatabase, deserializer: EnrichedDiffDeserializer, max_save_batch_size: int = 1000):
|
|
47
52
|
self.db = db
|
|
48
53
|
self.deserializer = deserializer
|
|
54
|
+
self.max_save_batch_size = max_save_batch_size
|
|
49
55
|
|
|
50
56
|
async def _run_get_diff_query(
|
|
51
57
|
self,
|
|
52
58
|
base_branch_name: str,
|
|
53
59
|
diff_branch_names: list[str],
|
|
54
|
-
|
|
60
|
+
batch_size_limit: int,
|
|
61
|
+
limit: int | None = None,
|
|
55
62
|
from_time: Timestamp | None = None,
|
|
56
63
|
to_time: Timestamp | None = None,
|
|
57
64
|
filters: EnrichedDiffQueryFilters | None = None,
|
|
@@ -62,8 +69,13 @@ class DiffRepository:
|
|
|
62
69
|
diff_ids: list[str] | None = None,
|
|
63
70
|
) -> list[EnrichedDiffRoot]:
|
|
64
71
|
self.deserializer.initialize()
|
|
72
|
+
final_row_number = None
|
|
73
|
+
if limit:
|
|
74
|
+
final_row_number = offset + limit
|
|
65
75
|
has_more_data = True
|
|
66
|
-
while has_more_data:
|
|
76
|
+
while has_more_data and (final_row_number is None or offset < final_row_number):
|
|
77
|
+
if final_row_number is not None and offset + batch_size_limit > final_row_number:
|
|
78
|
+
batch_size_limit = final_row_number - offset
|
|
67
79
|
get_query = await EnrichedDiffGetQuery.init(
|
|
68
80
|
db=self.db,
|
|
69
81
|
base_branch_name=base_branch_name,
|
|
@@ -72,12 +84,12 @@ class DiffRepository:
|
|
|
72
84
|
to_time=to_time,
|
|
73
85
|
filters=filters,
|
|
74
86
|
max_depth=max_depth,
|
|
75
|
-
limit=
|
|
87
|
+
limit=batch_size_limit,
|
|
76
88
|
offset=offset,
|
|
77
89
|
tracking_id=tracking_id,
|
|
78
90
|
diff_ids=diff_ids,
|
|
79
91
|
)
|
|
80
|
-
log.info(f"Beginning enriched diff get query {
|
|
92
|
+
log.info(f"Beginning enriched diff get query {batch_size_limit=}, {offset=}")
|
|
81
93
|
await get_query.execute(db=self.db)
|
|
82
94
|
log.info("Enriched diff get query complete")
|
|
83
95
|
last_result = None
|
|
@@ -87,7 +99,7 @@ class DiffRepository:
|
|
|
87
99
|
has_more_data = False
|
|
88
100
|
if last_result:
|
|
89
101
|
has_more_data = last_result.get_as_type("has_more_data", bool)
|
|
90
|
-
offset +=
|
|
102
|
+
offset += batch_size_limit
|
|
91
103
|
return await self.deserializer.deserialize()
|
|
92
104
|
|
|
93
105
|
async def get(
|
|
@@ -105,16 +117,17 @@ class DiffRepository:
|
|
|
105
117
|
include_empty: bool = False,
|
|
106
118
|
) -> list[EnrichedDiffRoot]:
|
|
107
119
|
final_max_depth = config.SETTINGS.database.max_depth_search_hierarchy
|
|
108
|
-
|
|
120
|
+
batch_size_limit = int(config.SETTINGS.database.query_size_limit / 10)
|
|
109
121
|
diff_roots = await self._run_get_diff_query(
|
|
110
122
|
base_branch_name=base_branch_name,
|
|
111
123
|
diff_branch_names=diff_branch_names,
|
|
124
|
+
batch_size_limit=batch_size_limit,
|
|
125
|
+
limit=limit,
|
|
112
126
|
from_time=from_time,
|
|
113
127
|
to_time=to_time,
|
|
114
128
|
filters=EnrichedDiffQueryFilters(**dict(filters or {})),
|
|
115
129
|
include_parents=include_parents,
|
|
116
130
|
max_depth=final_max_depth,
|
|
117
|
-
limit=limit,
|
|
118
131
|
offset=offset or 0,
|
|
119
132
|
tracking_id=tracking_id,
|
|
120
133
|
diff_ids=diff_ids,
|
|
@@ -131,42 +144,56 @@ class DiffRepository:
|
|
|
131
144
|
to_time: Timestamp,
|
|
132
145
|
) -> list[EnrichedDiffs]:
|
|
133
146
|
max_depth = config.SETTINGS.database.max_depth_search_hierarchy
|
|
134
|
-
|
|
147
|
+
batch_size_limit = int(config.SETTINGS.database.query_size_limit / 10)
|
|
135
148
|
diff_branch_roots = await self._run_get_diff_query(
|
|
136
149
|
base_branch_name=base_branch_name,
|
|
137
150
|
diff_branch_names=[diff_branch_name],
|
|
138
151
|
from_time=from_time,
|
|
139
152
|
to_time=to_time,
|
|
140
153
|
max_depth=max_depth,
|
|
141
|
-
|
|
154
|
+
batch_size_limit=batch_size_limit,
|
|
142
155
|
)
|
|
143
156
|
diffs_by_uuid = {dbr.uuid: dbr for dbr in diff_branch_roots}
|
|
144
157
|
base_branch_roots = await self._run_get_diff_query(
|
|
145
158
|
base_branch_name=base_branch_name,
|
|
146
159
|
diff_branch_names=[base_branch_name],
|
|
147
160
|
max_depth=max_depth,
|
|
148
|
-
|
|
149
|
-
diff_ids=[d.partner_uuid for d in diffs_by_uuid.values()],
|
|
161
|
+
batch_size_limit=batch_size_limit,
|
|
162
|
+
diff_ids=[d.partner_uuid for d in diffs_by_uuid.values() if d.partner_uuid],
|
|
150
163
|
)
|
|
151
164
|
diffs_by_uuid.update({bbr.uuid: bbr for bbr in base_branch_roots})
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
diff_pairs = []
|
|
166
|
+
for dbr in diff_branch_roots:
|
|
167
|
+
if dbr.partner_uuid is None:
|
|
168
|
+
continue
|
|
169
|
+
base_branch_diff = diffs_by_uuid[dbr.partner_uuid]
|
|
170
|
+
diff_pairs.append(
|
|
171
|
+
EnrichedDiffs(
|
|
172
|
+
base_branch_name=base_branch_name,
|
|
173
|
+
diff_branch_name=diff_branch_name,
|
|
174
|
+
base_branch_diff=base_branch_diff,
|
|
175
|
+
diff_branch_diff=dbr,
|
|
176
|
+
)
|
|
158
177
|
)
|
|
159
|
-
|
|
160
|
-
]
|
|
178
|
+
return diff_pairs
|
|
161
179
|
|
|
162
|
-
async def hydrate_diff_pair(
|
|
180
|
+
async def hydrate_diff_pair(
|
|
181
|
+
self,
|
|
182
|
+
enriched_diffs_metadata: EnrichedDiffsMetadata,
|
|
183
|
+
node_uuids: Iterable[str] | None = None,
|
|
184
|
+
) -> EnrichedDiffs:
|
|
185
|
+
filters = None
|
|
186
|
+
if node_uuids:
|
|
187
|
+
filters = {"ids": list(node_uuids) if node_uuids is not None else None}
|
|
163
188
|
hydrated_base_diff = await self.get_one(
|
|
164
189
|
diff_branch_name=enriched_diffs_metadata.base_branch_name,
|
|
165
190
|
diff_id=enriched_diffs_metadata.base_branch_diff.uuid,
|
|
191
|
+
filters=filters,
|
|
166
192
|
)
|
|
167
193
|
hydrated_branch_diff = await self.get_one(
|
|
168
194
|
diff_branch_name=enriched_diffs_metadata.diff_branch_name,
|
|
169
195
|
diff_id=enriched_diffs_metadata.diff_branch_diff.uuid,
|
|
196
|
+
filters=filters,
|
|
170
197
|
)
|
|
171
198
|
return EnrichedDiffs(
|
|
172
199
|
base_branch_name=enriched_diffs_metadata.base_branch_name,
|
|
@@ -208,26 +235,111 @@ class DiffRepository:
|
|
|
208
235
|
) -> Generator[list[EnrichedNodeCreateRequest], None, None]:
|
|
209
236
|
node_requests = []
|
|
210
237
|
for diff_root in (enriched_diffs.base_branch_diff, enriched_diffs.diff_branch_diff):
|
|
238
|
+
size_count = 0
|
|
211
239
|
for node in diff_root.nodes:
|
|
212
|
-
|
|
213
|
-
if
|
|
240
|
+
node_size_count = node.num_properties
|
|
241
|
+
if size_count + node_size_count < self.max_save_batch_size:
|
|
242
|
+
node_requests.append(EnrichedNodeCreateRequest(node=node, root_uuid=diff_root.uuid))
|
|
243
|
+
size_count += node_size_count
|
|
244
|
+
else:
|
|
245
|
+
log.info(f"Num nodes in batch: {len(node_requests)}, num properties in batch: {size_count}")
|
|
214
246
|
yield node_requests
|
|
215
|
-
|
|
247
|
+
size_count = node_size_count
|
|
248
|
+
node_requests = [EnrichedNodeCreateRequest(node=node, root_uuid=diff_root.uuid)]
|
|
216
249
|
if node_requests:
|
|
250
|
+
log.info(f"Num nodes in batch: {len(node_requests)}, num properties in batch: {size_count}")
|
|
217
251
|
yield node_requests
|
|
218
252
|
|
|
219
|
-
@retry_db_transaction(name="
|
|
220
|
-
async def
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
root_query = await EnrichedDiffRootsCreateQuery.init(db=self.db, enriched_diffs=enriched_diffs)
|
|
253
|
+
@retry_db_transaction(name="enriched_diff_metadata_save")
|
|
254
|
+
async def _save_root_metadata(self, enriched_diffs: EnrichedDiffsMetadata) -> None:
|
|
255
|
+
log.info("Updating diff metadata...")
|
|
256
|
+
root_query = await EnrichedDiffRootsUpsertQuery.init(db=self.db, enriched_diffs=enriched_diffs)
|
|
224
257
|
await root_query.execute(db=self.db)
|
|
225
|
-
|
|
226
|
-
|
|
258
|
+
log.info("Diff metadata updated.")
|
|
259
|
+
|
|
260
|
+
async def _save_node_batch(self, node_create_batch: list[EnrichedNodeCreateRequest]) -> None:
|
|
261
|
+
node_query = await EnrichedNodeBatchCreateQuery.init(db=self.db, node_create_batch=node_create_batch)
|
|
262
|
+
try:
|
|
227
263
|
await node_query.execute(db=self.db)
|
|
228
|
-
|
|
264
|
+
except TransientError as exc:
|
|
265
|
+
if not exc.code or "OutOfMemoryError".lower() not in str(exc.code).lower():
|
|
266
|
+
raise
|
|
267
|
+
log.exception("Database memory error during save. Trying smaller transactions")
|
|
268
|
+
for node_request in node_create_batch:
|
|
269
|
+
log.info(
|
|
270
|
+
f"Updating node {node_request.node.uuid}, num_properties={node_request.node.num_properties}..."
|
|
271
|
+
)
|
|
272
|
+
single_node_query = await EnrichedNodeBatchCreateQuery.init(
|
|
273
|
+
db=self.db, node_create_batch=[node_request]
|
|
274
|
+
)
|
|
275
|
+
await single_node_query.execute(db=self.db)
|
|
276
|
+
|
|
277
|
+
@retry_db_transaction(name="enriched_diff_hierarchy_update")
|
|
278
|
+
async def _run_hierarchy_links_update_query(self, diff_root_uuid: str, diff_nodes: list[EnrichedDiffNode]) -> None:
|
|
279
|
+
log.info(f"Updating diff hierarchy links, num_nodes={len(diff_nodes)}")
|
|
280
|
+
link_query = await EnrichedNodesLinkQuery.init(db=self.db, diff_root_uuid=diff_root_uuid, diff_nodes=diff_nodes)
|
|
229
281
|
await link_query.execute(db=self.db)
|
|
230
|
-
|
|
282
|
+
|
|
283
|
+
async def _update_hierarchy_links(self, enriched_diffs: EnrichedDiffs) -> None:
|
|
284
|
+
for diff_root in (enriched_diffs.base_branch_diff, enriched_diffs.diff_branch_diff):
|
|
285
|
+
nodes_to_update = []
|
|
286
|
+
for node in diff_root.nodes:
|
|
287
|
+
if any(r.nodes for r in node.relationships):
|
|
288
|
+
nodes_to_update.append(node)
|
|
289
|
+
if len(nodes_to_update) >= config.SETTINGS.database.query_size_limit:
|
|
290
|
+
await self._run_hierarchy_links_update_query(
|
|
291
|
+
diff_root_uuid=diff_root.uuid, diff_nodes=nodes_to_update
|
|
292
|
+
)
|
|
293
|
+
nodes_to_update = []
|
|
294
|
+
if nodes_to_update:
|
|
295
|
+
await self._run_hierarchy_links_update_query(diff_root_uuid=diff_root.uuid, diff_nodes=nodes_to_update)
|
|
296
|
+
|
|
297
|
+
async def _update_summary_counts(self, diff_root: EnrichedDiffRoot) -> None:
|
|
298
|
+
max_nodes_limit = config.SETTINGS.database.query_size_limit
|
|
299
|
+
num_nodes = len(diff_root.nodes)
|
|
300
|
+
if diff_root.exists_on_database and num_nodes < max_nodes_limit:
|
|
301
|
+
await self.add_summary_counts(
|
|
302
|
+
diff_branch_name=diff_root.diff_branch_name,
|
|
303
|
+
diff_id=diff_root.uuid,
|
|
304
|
+
node_uuids=None,
|
|
305
|
+
)
|
|
306
|
+
return
|
|
307
|
+
node_uuids: list[str] = []
|
|
308
|
+
for diff_node in diff_root.nodes:
|
|
309
|
+
node_uuids.append(diff_node.uuid)
|
|
310
|
+
if len(node_uuids) >= max_nodes_limit:
|
|
311
|
+
await self.add_summary_counts(
|
|
312
|
+
diff_branch_name=diff_root.diff_branch_name,
|
|
313
|
+
diff_id=diff_root.uuid,
|
|
314
|
+
node_uuids=node_uuids,
|
|
315
|
+
)
|
|
316
|
+
node_uuids = []
|
|
317
|
+
if node_uuids:
|
|
318
|
+
await self.add_summary_counts(
|
|
319
|
+
diff_branch_name=diff_root.diff_branch_name,
|
|
320
|
+
diff_id=diff_root.uuid,
|
|
321
|
+
node_uuids=node_uuids,
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
async def save(self, enriched_diffs: EnrichedDiffs | EnrichedDiffsMetadata, do_summary_counts: bool = True) -> None:
|
|
325
|
+
# metadata-only update
|
|
326
|
+
if not isinstance(enriched_diffs, EnrichedDiffs):
|
|
327
|
+
await self._save_root_metadata(enriched_diffs=enriched_diffs)
|
|
328
|
+
return
|
|
329
|
+
|
|
330
|
+
count_nodes_remaining = len(enriched_diffs.base_branch_diff.nodes) + len(enriched_diffs.diff_branch_diff.nodes)
|
|
331
|
+
log.info(f"Saving diff (num_nodes={count_nodes_remaining})...")
|
|
332
|
+
for batch_num, node_create_batch in enumerate(
|
|
333
|
+
self._get_node_create_request_batch(enriched_diffs=enriched_diffs)
|
|
334
|
+
):
|
|
335
|
+
log.info(f"Saving node batch #{batch_num}...")
|
|
336
|
+
await self._save_node_batch(node_create_batch=node_create_batch)
|
|
337
|
+
count_nodes_remaining -= len(node_create_batch)
|
|
338
|
+
log.info(f"Batch saved. {count_nodes_remaining=}")
|
|
339
|
+
await self._update_hierarchy_links(enriched_diffs=enriched_diffs)
|
|
340
|
+
if do_summary_counts:
|
|
341
|
+
await self._update_summary_counts(diff_root=enriched_diffs.diff_branch_diff)
|
|
342
|
+
await self._save_root_metadata(enriched_diffs=enriched_diffs)
|
|
231
343
|
|
|
232
344
|
async def summary(
|
|
233
345
|
self,
|
|
@@ -277,6 +389,7 @@ class DiffRepository:
|
|
|
277
389
|
base_branch_names: list[str] | None = None,
|
|
278
390
|
from_time: Timestamp | None = None,
|
|
279
391
|
to_time: Timestamp | None = None,
|
|
392
|
+
tracking_id: TrackingId | None = None,
|
|
280
393
|
) -> list[EnrichedDiffsMetadata]:
|
|
281
394
|
if diff_branch_names and base_branch_names:
|
|
282
395
|
diff_branch_names += base_branch_names
|
|
@@ -285,11 +398,12 @@ class DiffRepository:
|
|
|
285
398
|
base_branch_names=base_branch_names,
|
|
286
399
|
from_time=from_time,
|
|
287
400
|
to_time=to_time,
|
|
401
|
+
tracking_id=tracking_id,
|
|
288
402
|
)
|
|
289
403
|
roots_by_id = {root.uuid: root for root in empty_roots}
|
|
290
404
|
pairs: list[EnrichedDiffsMetadata] = []
|
|
291
405
|
for branch_root in empty_roots:
|
|
292
|
-
if branch_root.base_branch_name == branch_root.diff_branch_name:
|
|
406
|
+
if branch_root.base_branch_name == branch_root.diff_branch_name or branch_root.partner_uuid is None:
|
|
293
407
|
continue
|
|
294
408
|
base_root = roots_by_id[branch_root.partner_uuid]
|
|
295
409
|
pairs.append(
|
|
@@ -308,6 +422,7 @@ class DiffRepository:
|
|
|
308
422
|
base_branch_names: list[str] | None = None,
|
|
309
423
|
from_time: Timestamp | None = None,
|
|
310
424
|
to_time: Timestamp | None = None,
|
|
425
|
+
tracking_id: TrackingId | None = None,
|
|
311
426
|
) -> list[EnrichedDiffRootMetadata]:
|
|
312
427
|
query = await EnrichedDiffRootsMetadataQuery.init(
|
|
313
428
|
db=self.db,
|
|
@@ -315,6 +430,7 @@ class DiffRepository:
|
|
|
315
430
|
base_branch_names=base_branch_names,
|
|
316
431
|
from_time=from_time,
|
|
317
432
|
to_time=to_time,
|
|
433
|
+
tracking_id=tracking_id,
|
|
318
434
|
)
|
|
319
435
|
await query.execute(db=self.db)
|
|
320
436
|
diff_roots = []
|
|
@@ -374,8 +490,8 @@ class DiffRepository:
|
|
|
374
490
|
await query.execute(db=self.db)
|
|
375
491
|
return await query.get_field_summaries()
|
|
376
492
|
|
|
377
|
-
async def
|
|
378
|
-
query = await
|
|
493
|
+
async def mark_tracking_ids_merged(self, tracking_ids: list[TrackingId]) -> None:
|
|
494
|
+
query = await EnrichedDiffMergedTrackingIdQuery.init(db=self.db, tracking_ids=tracking_ids)
|
|
379
495
|
await query.execute(db=self.db)
|
|
380
496
|
|
|
381
497
|
async def get_num_changes_in_time_range_by_branch(
|
|
@@ -400,3 +516,61 @@ class DiffRepository:
|
|
|
400
516
|
break
|
|
401
517
|
offset += limit
|
|
402
518
|
return specifiers
|
|
519
|
+
|
|
520
|
+
async def add_summary_counts(
|
|
521
|
+
self,
|
|
522
|
+
diff_branch_name: str,
|
|
523
|
+
tracking_id: TrackingId | None = None,
|
|
524
|
+
diff_id: str | None = None,
|
|
525
|
+
node_uuids: list[str] | None = None,
|
|
526
|
+
) -> None:
|
|
527
|
+
await self._add_field_summary_counts(
|
|
528
|
+
diff_branch_name=diff_branch_name,
|
|
529
|
+
tracking_id=tracking_id,
|
|
530
|
+
diff_id=diff_id,
|
|
531
|
+
node_uuids=node_uuids,
|
|
532
|
+
)
|
|
533
|
+
await self._add_node_summary_counts(
|
|
534
|
+
diff_branch_name=diff_branch_name,
|
|
535
|
+
tracking_id=tracking_id,
|
|
536
|
+
diff_id=diff_id,
|
|
537
|
+
node_uuids=node_uuids,
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
@retry_db_transaction(name="enriched_diff_field_summary_counts")
|
|
541
|
+
async def _add_field_summary_counts(
|
|
542
|
+
self,
|
|
543
|
+
diff_branch_name: str,
|
|
544
|
+
tracking_id: TrackingId | None = None,
|
|
545
|
+
diff_id: str | None = None,
|
|
546
|
+
node_uuids: list[str] | None = None,
|
|
547
|
+
) -> None:
|
|
548
|
+
log.info("Updating field summary counts...")
|
|
549
|
+
query = await DiffFieldsSummaryCountsEnricherQuery.init(
|
|
550
|
+
db=self.db,
|
|
551
|
+
diff_branch_name=diff_branch_name,
|
|
552
|
+
tracking_id=tracking_id,
|
|
553
|
+
diff_id=diff_id,
|
|
554
|
+
node_uuids=node_uuids,
|
|
555
|
+
)
|
|
556
|
+
await query.execute(db=self.db)
|
|
557
|
+
log.info("Field summary counts updated.")
|
|
558
|
+
|
|
559
|
+
@retry_db_transaction(name="enriched_diff_node_summary_counts")
|
|
560
|
+
async def _add_node_summary_counts(
|
|
561
|
+
self,
|
|
562
|
+
diff_branch_name: str,
|
|
563
|
+
tracking_id: TrackingId | None = None,
|
|
564
|
+
diff_id: str | None = None,
|
|
565
|
+
node_uuids: list[str] | None = None,
|
|
566
|
+
) -> None:
|
|
567
|
+
log.info("Updating node summary counts...")
|
|
568
|
+
query = await DiffNodesSummaryCountsEnricherQuery.init(
|
|
569
|
+
db=self.db,
|
|
570
|
+
diff_branch_name=diff_branch_name,
|
|
571
|
+
tracking_id=tracking_id,
|
|
572
|
+
diff_id=diff_id,
|
|
573
|
+
node_uuids=node_uuids,
|
|
574
|
+
)
|
|
575
|
+
await query.execute(db=self.db)
|
|
576
|
+
log.info("node summary counts updated.")
|
infrahub/core/diff/tasks.py
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from prefect import flow
|
|
2
4
|
|
|
5
|
+
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
|
|
3
6
|
from infrahub.core import registry
|
|
4
7
|
from infrahub.core.diff.coordinator import DiffCoordinator
|
|
5
|
-
from infrahub.core.diff.models import RequestDiffUpdate
|
|
8
|
+
from infrahub.core.diff.models import RequestDiffUpdate # noqa: TC001 needed for prefect flow
|
|
6
9
|
from infrahub.core.diff.repository.repository import DiffRepository
|
|
7
10
|
from infrahub.dependencies.registry import get_component_registry
|
|
8
11
|
from infrahub.log import get_logger
|
|
9
|
-
from infrahub.services import
|
|
12
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
10
13
|
from infrahub.workflows.catalogue import DIFF_REFRESH
|
|
11
|
-
from infrahub.workflows.utils import
|
|
14
|
+
from infrahub.workflows.utils import add_tags
|
|
12
15
|
|
|
13
16
|
log = get_logger()
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
@flow(name="diff-update", flow_run_name="Update diff for branch {model.branch_name}")
|
|
17
|
-
async def update_diff(model: RequestDiffUpdate) -> None:
|
|
18
|
-
|
|
19
|
-
await add_branch_tag(branch_name=model.branch_name)
|
|
20
|
+
async def update_diff(model: RequestDiffUpdate, service: InfrahubServices) -> None:
|
|
21
|
+
await add_tags(branches=[model.branch_name])
|
|
20
22
|
|
|
21
23
|
async with service.database.start_session() as db:
|
|
22
24
|
component_registry = get_component_registry()
|
|
@@ -35,9 +37,8 @@ async def update_diff(model: RequestDiffUpdate) -> None:
|
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
@flow(name="diff-refresh", flow_run_name="Recreate diff for branch {branch_name}")
|
|
38
|
-
async def refresh_diff(branch_name: str, diff_id: str) -> None:
|
|
39
|
-
|
|
40
|
-
await add_branch_tag(branch_name=branch_name)
|
|
40
|
+
async def refresh_diff(branch_name: str, diff_id: str, service: InfrahubServices) -> None:
|
|
41
|
+
await add_tags(branches=[branch_name])
|
|
41
42
|
|
|
42
43
|
async with service.database.start_session() as db:
|
|
43
44
|
component_registry = get_component_registry()
|
|
@@ -49,9 +50,8 @@ async def refresh_diff(branch_name: str, diff_id: str) -> None:
|
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
@flow(name="diff-refresh-all", flow_run_name="Recreate all diffs for branch {branch_name}")
|
|
52
|
-
async def refresh_diff_all(branch_name: str) -> None:
|
|
53
|
-
|
|
54
|
-
await add_branch_tag(branch_name=branch_name)
|
|
53
|
+
async def refresh_diff_all(branch_name: str, context: InfrahubContext, service: InfrahubServices) -> None:
|
|
54
|
+
await add_tags(branches=[branch_name])
|
|
55
55
|
|
|
56
56
|
async with service.database.start_session() as db:
|
|
57
57
|
component_registry = get_component_registry()
|
|
@@ -63,5 +63,6 @@ async def refresh_diff_all(branch_name: str) -> None:
|
|
|
63
63
|
if diff_root.base_branch_name != diff_root.diff_branch_name:
|
|
64
64
|
await service.workflow.submit_workflow(
|
|
65
65
|
workflow=DIFF_REFRESH,
|
|
66
|
+
context=context,
|
|
66
67
|
parameters={"branch_name": diff_root.diff_branch_name, "diff_id": diff_root.uuid},
|
|
67
68
|
)
|
infrahub/core/enums.py
CHANGED
infrahub/core/graph/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
GRAPH_VERSION =
|
|
1
|
+
GRAPH_VERSION = 20
|
infrahub/core/graph/index.py
CHANGED
|
@@ -12,6 +12,9 @@ node_indexes: list[IndexItem] = [
|
|
|
12
12
|
IndexItem(name="attr_iphost_bin", label="AttributeIPHost", properties=["binary_address"], type=IndexType.RANGE),
|
|
13
13
|
IndexItem(name="rel_uuid", label="Relationship", properties=["uuid"], type=IndexType.RANGE),
|
|
14
14
|
IndexItem(name="rel_identifier", label="Relationship", properties=["name"], type=IndexType.RANGE),
|
|
15
|
+
# diff indices
|
|
16
|
+
IndexItem(name="diff_uuid", label="DiffRoot", properties=["uuid"], type=IndexType.TEXT),
|
|
17
|
+
IndexItem(name="diff_node_uuid", label="DiffNode", properties=["uuid"], type=IndexType.TEXT),
|
|
15
18
|
]
|
|
16
19
|
|
|
17
20
|
rel_indexes: list[IndexItem] = [
|
|
@@ -17,7 +17,7 @@ class ObjectConflictValidatorRecorder:
|
|
|
17
17
|
self.validator_label = validator_label
|
|
18
18
|
self.check_schema_kind = check_schema_kind
|
|
19
19
|
|
|
20
|
-
async def record_conflicts(self, proposed_change_id: str, conflicts: Sequence[ObjectConflict]) -> list[Node]:
|
|
20
|
+
async def record_conflicts(self, proposed_change_id: str, conflicts: Sequence[ObjectConflict]) -> list[Node]:
|
|
21
21
|
try:
|
|
22
22
|
proposed_change = await NodeManager.get_one_by_id_or_default_filter(
|
|
23
23
|
id=proposed_change_id, kind=InfrahubKind.PROPOSEDCHANGE, db=self.db
|
infrahub/core/ipam/reconciler.py
CHANGED
|
@@ -104,7 +104,7 @@ class IpamReconciler:
|
|
|
104
104
|
ip_node_uuid = query.get_ip_node_uuid()
|
|
105
105
|
if not ip_node_uuid:
|
|
106
106
|
node_type = InfrahubKind.IPPREFIX
|
|
107
|
-
if isinstance(ip_value,
|
|
107
|
+
if isinstance(ip_value, ipaddress.IPv6Interface | ipaddress.IPv4Interface):
|
|
108
108
|
node_type = InfrahubKind.IPADDRESS
|
|
109
109
|
raise NodeNotFoundError(node_type=node_type, identifier=str(ip_value))
|
|
110
110
|
current_parent_uuid = query.get_current_parent_uuid()
|
infrahub/core/ipam/tasks.py
CHANGED
|
@@ -5,7 +5,7 @@ from prefect import flow
|
|
|
5
5
|
|
|
6
6
|
from infrahub.core import registry
|
|
7
7
|
from infrahub.core.ipam.reconciler import IpamReconciler
|
|
8
|
-
from infrahub.services import
|
|
8
|
+
from infrahub.services import InfrahubServices
|
|
9
9
|
from infrahub.workflows.utils import add_branch_tag
|
|
10
10
|
|
|
11
11
|
from .model import IpamNodeDetails
|
|
@@ -20,8 +20,7 @@ if TYPE_CHECKING:
|
|
|
20
20
|
description="Ensure the IPAM Tree is up to date",
|
|
21
21
|
persist_result=False,
|
|
22
22
|
)
|
|
23
|
-
async def ipam_reconciliation(branch: str, ipam_node_details: list[IpamNodeDetails]) -> None:
|
|
24
|
-
service = services.service
|
|
23
|
+
async def ipam_reconciliation(branch: str, ipam_node_details: list[IpamNodeDetails], service: InfrahubServices) -> None:
|
|
25
24
|
async with service.database.start_session() as db:
|
|
26
25
|
branch_obj = await registry.get_branch(db=db, branch=branch)
|
|
27
26
|
|
infrahub/core/manager.py
CHANGED
|
@@ -23,7 +23,14 @@ from infrahub.core.query.node import (
|
|
|
23
23
|
from infrahub.core.query.relationship import RelationshipGetPeerQuery
|
|
24
24
|
from infrahub.core.registry import registry
|
|
25
25
|
from infrahub.core.relationship import Relationship, RelationshipManager
|
|
26
|
-
from infrahub.core.schema import
|
|
26
|
+
from infrahub.core.schema import (
|
|
27
|
+
GenericSchema,
|
|
28
|
+
MainSchemaTypes,
|
|
29
|
+
NodeSchema,
|
|
30
|
+
ProfileSchema,
|
|
31
|
+
RelationshipSchema,
|
|
32
|
+
TemplateSchema,
|
|
33
|
+
)
|
|
27
34
|
from infrahub.core.timestamp import Timestamp
|
|
28
35
|
from infrahub.exceptions import NodeNotFoundError, ProcessingError, SchemaNotFoundError
|
|
29
36
|
from infrahub.graphql.models import OrderModel
|
|
@@ -35,8 +42,6 @@ if TYPE_CHECKING:
|
|
|
35
42
|
|
|
36
43
|
SchemaProtocol = TypeVar("SchemaProtocol")
|
|
37
44
|
|
|
38
|
-
# pylint: disable=redefined-builtin,too-many-lines
|
|
39
|
-
|
|
40
45
|
|
|
41
46
|
def identify_node_class(node: NodeToProcess) -> type[Node]:
|
|
42
47
|
"""Identify the proper class to use to create the NodeObject.
|
|
@@ -61,7 +66,7 @@ def get_schema(
|
|
|
61
66
|
) -> MainSchemaTypes:
|
|
62
67
|
if isinstance(node_schema, str):
|
|
63
68
|
return db.schema.get(name=node_schema, branch=branch.name)
|
|
64
|
-
if hasattr(node_schema, "_is_runtime_protocol") and
|
|
69
|
+
if hasattr(node_schema, "_is_runtime_protocol") and node_schema._is_runtime_protocol:
|
|
65
70
|
return db.schema.get(name=node_schema.__name__, branch=branch.name)
|
|
66
71
|
if not isinstance(node_schema, (MainSchemaTypes)):
|
|
67
72
|
raise ValueError(f"Invalid schema provided {node_schema}")
|
|
@@ -129,7 +134,7 @@ class NodeManager:
|
|
|
129
134
|
async def query(
|
|
130
135
|
cls,
|
|
131
136
|
db: InfrahubDatabase,
|
|
132
|
-
schema: Union[NodeSchema, GenericSchema, ProfileSchema, str],
|
|
137
|
+
schema: Union[NodeSchema, GenericSchema, ProfileSchema, TemplateSchema, str],
|
|
133
138
|
filters: dict | None = ...,
|
|
134
139
|
fields: dict | None = ...,
|
|
135
140
|
offset: int | None = ...,
|
|
@@ -267,11 +272,11 @@ class NodeManager:
|
|
|
267
272
|
async def count(
|
|
268
273
|
cls,
|
|
269
274
|
db: InfrahubDatabase,
|
|
270
|
-
schema: Union[type[SchemaProtocol], NodeSchema, GenericSchema, ProfileSchema, str],
|
|
275
|
+
schema: Union[type[SchemaProtocol], NodeSchema, GenericSchema, ProfileSchema, TemplateSchema, str],
|
|
271
276
|
filters: Optional[dict] = None,
|
|
272
277
|
at: Optional[Union[Timestamp, str]] = None,
|
|
273
278
|
branch: Optional[Union[Branch, str]] = None,
|
|
274
|
-
account=None, #
|
|
279
|
+
account=None, # noqa: ARG003
|
|
275
280
|
partial_match: bool = False,
|
|
276
281
|
branch_agnostic: bool = False,
|
|
277
282
|
) -> int:
|
|
@@ -446,7 +451,7 @@ class NodeManager:
|
|
|
446
451
|
limit: Optional[int] = None,
|
|
447
452
|
at: Optional[Union[Timestamp, str]] = None,
|
|
448
453
|
branch: Optional[Union[Branch, str]] = None,
|
|
449
|
-
) -> dict[str,
|
|
454
|
+
) -> dict[str, Node]:
|
|
450
455
|
branch = await registry.get_branch(branch=branch, db=db)
|
|
451
456
|
at = Timestamp(at)
|
|
452
457
|
|
|
@@ -489,7 +494,7 @@ class NodeManager:
|
|
|
489
494
|
kind: type[SchemaProtocol],
|
|
490
495
|
at: Timestamp | str | None = ...,
|
|
491
496
|
branch: Branch | str | None = ...,
|
|
492
|
-
id: str | None = ...,
|
|
497
|
+
id: str | None = ...,
|
|
493
498
|
hfid: list[str] | None = ...,
|
|
494
499
|
) -> SchemaProtocol: ...
|
|
495
500
|
|
|
@@ -501,7 +506,7 @@ class NodeManager:
|
|
|
501
506
|
kind: str,
|
|
502
507
|
at: Timestamp | str | None = ...,
|
|
503
508
|
branch: Branch | str | None = ...,
|
|
504
|
-
id: str | None = ...,
|
|
509
|
+
id: str | None = ...,
|
|
505
510
|
hfid: list[str] | None = ...,
|
|
506
511
|
) -> Any: ...
|
|
507
512
|
|
|
@@ -512,7 +517,7 @@ class NodeManager:
|
|
|
512
517
|
kind: type[SchemaProtocol] | str,
|
|
513
518
|
at: Timestamp | str | None = None,
|
|
514
519
|
branch: Branch | str | None = None,
|
|
515
|
-
id: str | None = None,
|
|
520
|
+
id: str | None = None,
|
|
516
521
|
hfid: list[str] | None = None,
|
|
517
522
|
) -> Any:
|
|
518
523
|
if not id and not hfid:
|
|
@@ -802,7 +807,7 @@ class NodeManager:
|
|
|
802
807
|
raise NodeNotFoundError(branch_name=branch.name, node_type=kind_str, identifier=hfid_str)
|
|
803
808
|
|
|
804
809
|
filters = {}
|
|
805
|
-
for key, item in zip(node_schema.human_friendly_id, hfid):
|
|
810
|
+
for key, item in zip(node_schema.human_friendly_id, hfid, strict=False):
|
|
806
811
|
path = node_schema.parse_schema_path(path=key, schema=registry.schema.get_schema_branch(name=branch.name))
|
|
807
812
|
|
|
808
813
|
if path.is_type_relationship:
|
|
@@ -1007,7 +1012,7 @@ class NodeManager:
|
|
|
1007
1012
|
cls,
|
|
1008
1013
|
id: str,
|
|
1009
1014
|
db: InfrahubDatabase,
|
|
1010
|
-
kind:
|
|
1015
|
+
kind: None = ...,
|
|
1011
1016
|
raise_on_error: bool = ...,
|
|
1012
1017
|
fields: dict | None = ...,
|
|
1013
1018
|
at: Timestamp | str | None = ...,
|
|
@@ -1148,7 +1153,7 @@ class NodeManager:
|
|
|
1148
1153
|
|
|
1149
1154
|
nodes: dict[str, Node] = {}
|
|
1150
1155
|
|
|
1151
|
-
for node_id in ids:
|
|
1156
|
+
for node_id in ids:
|
|
1152
1157
|
if node_id not in nodes_info_by_id:
|
|
1153
1158
|
continue
|
|
1154
1159
|
|
|
@@ -1310,7 +1315,7 @@ class NodeManager:
|
|
|
1310
1315
|
nodes: list[Node],
|
|
1311
1316
|
branch: Optional[Union[Branch, str]] = None,
|
|
1312
1317
|
at: Optional[Union[Timestamp, str]] = None,
|
|
1313
|
-
) -> list[
|
|
1318
|
+
) -> list[Node]:
|
|
1314
1319
|
"""Returns list of deleted nodes because of cascading deletes"""
|
|
1315
1320
|
branch = await registry.get_branch(branch=branch, db=db)
|
|
1316
1321
|
node_delete_validator = NodeDeleteValidator(db=db, branch=branch)
|