infrahub-server 1.3.0a0__py3-none-any.whl → 1.3.0b2__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/actions/tasks.py +4 -11
- infrahub/branch/__init__.py +0 -0
- infrahub/branch/tasks.py +29 -0
- infrahub/branch/triggers.py +22 -0
- infrahub/cli/db.py +2 -2
- infrahub/computed_attribute/gather.py +3 -1
- infrahub/computed_attribute/tasks.py +23 -29
- infrahub/core/attribute.py +3 -3
- infrahub/core/constants/__init__.py +10 -0
- infrahub/core/constants/database.py +1 -0
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/convert_object_type/conversion.py +1 -1
- infrahub/core/diff/query/save.py +67 -40
- infrahub/core/diff/query/time_range_query.py +0 -1
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/migrations/graph/__init__.py +6 -0
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +0 -2
- infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
- infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
- infrahub/core/migrations/query/attribute_add.py +13 -9
- infrahub/core/migrations/query/attribute_rename.py +2 -4
- infrahub/core/migrations/query/delete_element_in_schema.py +16 -11
- infrahub/core/migrations/query/node_duplicate.py +16 -15
- infrahub/core/migrations/query/relationship_duplicate.py +16 -12
- infrahub/core/migrations/schema/node_attribute_remove.py +1 -2
- infrahub/core/migrations/schema/node_remove.py +16 -14
- infrahub/core/node/__init__.py +74 -14
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -2
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -2
- infrahub/core/node/resource_manager/number_pool.py +31 -5
- infrahub/core/node/standard.py +6 -1
- infrahub/core/path.py +1 -1
- infrahub/core/protocols.py +10 -0
- infrahub/core/query/node.py +1 -1
- infrahub/core/query/relationship.py +4 -6
- infrahub/core/query/standard_node.py +19 -5
- infrahub/core/relationship/constraints/peer_relatives.py +72 -0
- infrahub/core/relationship/model.py +1 -1
- infrahub/core/schema/attribute_parameters.py +129 -5
- infrahub/core/schema/attribute_schema.py +62 -14
- infrahub/core/schema/basenode_schema.py +2 -2
- infrahub/core/schema/definitions/core/__init__.py +16 -2
- infrahub/core/schema/definitions/core/group.py +45 -0
- infrahub/core/schema/definitions/core/resource_pool.py +29 -0
- infrahub/core/schema/definitions/internal.py +25 -4
- infrahub/core/schema/generated/attribute_schema.py +12 -5
- infrahub/core/schema/generated/relationship_schema.py +6 -1
- infrahub/core/schema/manager.py +7 -2
- infrahub/core/schema/schema_branch.py +69 -5
- infrahub/core/validators/__init__.py +8 -0
- infrahub/core/validators/attribute/choices.py +0 -1
- infrahub/core/validators/attribute/enum.py +0 -1
- infrahub/core/validators/attribute/kind.py +0 -1
- infrahub/core/validators/attribute/length.py +0 -1
- infrahub/core/validators/attribute/min_max.py +118 -0
- infrahub/core/validators/attribute/number_pool.py +106 -0
- infrahub/core/validators/attribute/optional.py +0 -2
- infrahub/core/validators/attribute/regex.py +0 -1
- infrahub/core/validators/enum.py +5 -0
- infrahub/core/validators/tasks.py +1 -1
- infrahub/database/__init__.py +16 -4
- infrahub/database/validation.py +100 -0
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/registry.py +2 -0
- infrahub/events/models.py +1 -1
- infrahub/git/base.py +5 -3
- infrahub/git/integrator.py +102 -3
- infrahub/graphql/mutations/main.py +1 -1
- infrahub/graphql/mutations/resource_manager.py +54 -6
- infrahub/graphql/queries/resource_manager.py +7 -1
- infrahub/graphql/queries/task.py +10 -0
- infrahub/graphql/resolvers/many_relationship.py +1 -1
- infrahub/graphql/resolvers/resolver.py +2 -2
- infrahub/graphql/resolvers/single_relationship.py +1 -1
- infrahub/graphql/types/task_log.py +3 -2
- infrahub/menu/menu.py +8 -7
- infrahub/message_bus/operations/refresh/registry.py +3 -3
- infrahub/patch/queries/delete_duplicated_edges.py +40 -29
- infrahub/pools/number.py +5 -3
- infrahub/pools/registration.py +22 -0
- infrahub/pools/tasks.py +56 -0
- infrahub/schema/__init__.py +0 -0
- infrahub/schema/tasks.py +27 -0
- infrahub/schema/triggers.py +23 -0
- infrahub/task_manager/task.py +44 -4
- infrahub/trigger/catalogue.py +4 -0
- infrahub/trigger/models.py +5 -4
- infrahub/trigger/setup.py +26 -2
- infrahub/trigger/tasks.py +1 -1
- infrahub/types.py +6 -0
- infrahub/webhook/tasks.py +6 -9
- infrahub/workflows/catalogue.py +27 -1
- infrahub_sdk/client.py +43 -10
- infrahub_sdk/node/__init__.py +39 -0
- infrahub_sdk/node/attribute.py +122 -0
- infrahub_sdk/node/constants.py +21 -0
- infrahub_sdk/{node.py → node/node.py} +50 -749
- infrahub_sdk/node/parsers.py +15 -0
- infrahub_sdk/node/property.py +24 -0
- infrahub_sdk/node/related_node.py +266 -0
- infrahub_sdk/node/relationship.py +302 -0
- infrahub_sdk/protocols.py +112 -0
- infrahub_sdk/protocols_base.py +34 -2
- infrahub_sdk/query_groups.py +13 -2
- infrahub_sdk/schema/main.py +1 -0
- infrahub_sdk/schema/repository.py +16 -0
- infrahub_sdk/spec/object.py +1 -1
- infrahub_sdk/store.py +1 -1
- infrahub_sdk/testing/schemas/car_person.py +1 -0
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/METADATA +3 -3
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/RECORD +122 -100
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/WHEEL +1 -1
- infrahub_testcontainers/container.py +239 -64
- infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
- infrahub_testcontainers/docker-compose.test.yml +1 -0
- infrahub_testcontainers/helpers.py +15 -1
- infrahub_testcontainers/plugin.py +9 -0
- infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -106
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/entry_points.txt +0 -0
|
@@ -59,6 +59,7 @@ services:
|
|
|
59
59
|
NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
|
|
60
60
|
NEO4J_server_memory_heap_initial__size: ${INFRAHUB_TESTING_DB_HEAP_INITIAL_SIZE}
|
|
61
61
|
NEO4J_server_memory_heap_max__size: ${INFRAHUB_TESTING_DB_HEAP_MAX_SIZE}
|
|
62
|
+
NEO4J_server_memory_pagecache_size: ${INFRAHUB_TESTING_DB_PAGECACHE_SIZE}
|
|
62
63
|
volumes:
|
|
63
64
|
- "database_data:/data"
|
|
64
65
|
- "database_logs:/logs"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import subprocess # noqa: S404
|
|
3
3
|
import uuid
|
|
4
|
+
import warnings
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
import pytest
|
|
@@ -61,6 +62,10 @@ class TestInfrahubDocker:
|
|
|
61
62
|
def default_branch(self) -> str:
|
|
62
63
|
return "main"
|
|
63
64
|
|
|
65
|
+
@pytest.fixture(scope="class")
|
|
66
|
+
def deployment_type(self, request: pytest.FixtureRequest) -> str | None:
|
|
67
|
+
return request.config.getoption(name="infrahub_deployment_type", default=None)
|
|
68
|
+
|
|
64
69
|
@pytest.fixture(scope="class")
|
|
65
70
|
def infrahub_compose(
|
|
66
71
|
self,
|
|
@@ -68,12 +73,21 @@ class TestInfrahubDocker:
|
|
|
68
73
|
remote_repos_dir: Path, # initialize repository before running docker compose to fix permissions issues # noqa: ARG002
|
|
69
74
|
remote_backups_dir: Path, # noqa: ARG002
|
|
70
75
|
infrahub_version: str,
|
|
76
|
+
deployment_type: str | None,
|
|
71
77
|
) -> InfrahubDockerCompose:
|
|
72
|
-
return InfrahubDockerCompose.init(
|
|
78
|
+
return InfrahubDockerCompose.init(
|
|
79
|
+
directory=tmp_directory, version=infrahub_version, deployment_type=deployment_type
|
|
80
|
+
)
|
|
73
81
|
|
|
74
82
|
@pytest.fixture(scope="class")
|
|
75
83
|
def infrahub_app(self, request: pytest.FixtureRequest, infrahub_compose: InfrahubDockerCompose) -> dict[str, int]:
|
|
84
|
+
tests_failed_before_class = request.session.testsfailed
|
|
85
|
+
|
|
76
86
|
def cleanup() -> None:
|
|
87
|
+
tests_failed_during_class = request.session.testsfailed - tests_failed_before_class
|
|
88
|
+
if tests_failed_during_class > 0:
|
|
89
|
+
stdout, stderr = infrahub_compose.get_logs("infrahub-server", "task-worker")
|
|
90
|
+
warnings.warn(f"Container logs:\nStdout:\n{stdout}\nStderr:\n{stderr}", stacklevel=2)
|
|
77
91
|
infrahub_compose.stop()
|
|
78
92
|
|
|
79
93
|
request.addfinalizer(cleanup)
|
|
@@ -13,6 +13,15 @@ if TYPE_CHECKING:
|
|
|
13
13
|
def pytest_addoption(parser: pytest.Parser) -> None:
|
|
14
14
|
group = parser.getgroup("infrahub-performance-test")
|
|
15
15
|
|
|
16
|
+
group.addoption(
|
|
17
|
+
"--deployment-type",
|
|
18
|
+
action="store",
|
|
19
|
+
dest="infrahub_deployment_type",
|
|
20
|
+
default=None,
|
|
21
|
+
metavar="INFRAHUB_DEPLOYMENT_TYPE",
|
|
22
|
+
help="Type of deployment to use (default: None, options: cluster)",
|
|
23
|
+
)
|
|
24
|
+
|
|
16
25
|
group.addoption(
|
|
17
26
|
"--performance-result-address",
|
|
18
27
|
action="store",
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
from ..models import EdgeToAdd, EdgeToDelete, PatchPlan, VertexToDelete
|
|
2
|
-
from .base import PatchQuery
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ConsolidateDuplicatedNodesPatchQuery(PatchQuery):
|
|
6
|
-
"""
|
|
7
|
-
Find any groups of nodes with the same labels and properties, move all the edges to one of the duplicated nodes,
|
|
8
|
-
then delete the other duplicated nodes
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
@property
|
|
12
|
-
def name(self) -> str:
|
|
13
|
-
return "consolidate-duplicated-nodes"
|
|
14
|
-
|
|
15
|
-
async def plan(self) -> PatchPlan:
|
|
16
|
-
query = """
|
|
17
|
-
//------------
|
|
18
|
-
// Find nodes with the same labels and UUID
|
|
19
|
-
//------------
|
|
20
|
-
MATCH (n:Node)
|
|
21
|
-
WITH n.uuid AS node_uuid, count(*) as num_nodes_with_uuid
|
|
22
|
-
WHERE num_nodes_with_uuid > 1
|
|
23
|
-
WITH DISTINCT node_uuid
|
|
24
|
-
MATCH (n:Node {uuid: node_uuid})
|
|
25
|
-
CALL (n) {
|
|
26
|
-
WITH labels(n) AS n_labels
|
|
27
|
-
UNWIND n_labels AS n_label
|
|
28
|
-
WITH n_label
|
|
29
|
-
ORDER BY n_label ASC
|
|
30
|
-
RETURN collect(n_label) AS sorted_labels
|
|
31
|
-
}
|
|
32
|
-
WITH n.uuid AS n_uuid, sorted_labels, collect(n) AS duplicate_nodes
|
|
33
|
-
WHERE size(duplicate_nodes) > 1
|
|
34
|
-
WITH n_uuid, head(duplicate_nodes) AS node_to_keep, tail(duplicate_nodes) AS nodes_to_delete
|
|
35
|
-
UNWIND nodes_to_delete AS node_to_delete
|
|
36
|
-
//------------
|
|
37
|
-
// Find the edges that we need to move to the selected node_to_keep
|
|
38
|
-
//------------
|
|
39
|
-
CALL (node_to_keep, node_to_delete) {
|
|
40
|
-
MATCH (node_to_delete)-[edge_to_delete]->(peer)
|
|
41
|
-
RETURN {
|
|
42
|
-
from_id: %(id_func_name)s(node_to_keep),
|
|
43
|
-
to_id: %(id_func_name)s(peer),
|
|
44
|
-
edge_type: type(edge_to_delete),
|
|
45
|
-
after_props: properties(edge_to_delete)
|
|
46
|
-
} AS edge_to_create
|
|
47
|
-
UNION
|
|
48
|
-
WITH node_to_keep, node_to_delete
|
|
49
|
-
MATCH (node_to_delete)<-[edge_to_delete]-(peer)
|
|
50
|
-
RETURN {
|
|
51
|
-
from_id: %(id_func_name)s(peer),
|
|
52
|
-
to_id: %(id_func_name)s(node_to_keep),
|
|
53
|
-
edge_type: type(edge_to_delete),
|
|
54
|
-
after_props: properties(edge_to_delete)
|
|
55
|
-
} AS edge_to_create
|
|
56
|
-
}
|
|
57
|
-
WITH node_to_delete, collect(edge_to_create) AS edges_to_create
|
|
58
|
-
//------------
|
|
59
|
-
// Find the edges that we need to remove from the duplicated nodes
|
|
60
|
-
//------------
|
|
61
|
-
CALL (node_to_delete) {
|
|
62
|
-
MATCH (node_to_delete)-[e]->(peer)
|
|
63
|
-
RETURN {
|
|
64
|
-
db_id: %(id_func_name)s(e),
|
|
65
|
-
from_id: %(id_func_name)s(node_to_delete),
|
|
66
|
-
to_id: %(id_func_name)s(peer),
|
|
67
|
-
edge_type: type(e),
|
|
68
|
-
before_props: properties(e)
|
|
69
|
-
} AS edge_to_delete
|
|
70
|
-
UNION
|
|
71
|
-
WITH node_to_delete
|
|
72
|
-
MATCH (node_to_delete)<-[e]-(peer)
|
|
73
|
-
RETURN {
|
|
74
|
-
db_id: %(id_func_name)s(e),
|
|
75
|
-
from_id: %(id_func_name)s(peer),
|
|
76
|
-
to_id: %(id_func_name)s(node_to_delete),
|
|
77
|
-
edge_type: type(e),
|
|
78
|
-
before_props: properties(e)
|
|
79
|
-
} AS edge_to_delete
|
|
80
|
-
}
|
|
81
|
-
WITH node_to_delete, edges_to_create, collect(edge_to_delete) AS edges_to_delete
|
|
82
|
-
RETURN
|
|
83
|
-
{db_id: %(id_func_name)s(node_to_delete), labels: labels(node_to_delete), before_props: properties(node_to_delete)} AS vertex_to_delete,
|
|
84
|
-
edges_to_create,
|
|
85
|
-
edges_to_delete
|
|
86
|
-
""" % {"id_func_name": self.db.get_id_function_name()}
|
|
87
|
-
results = await self.db.execute_query(query=query)
|
|
88
|
-
vertices_to_delete: list[VertexToDelete] = []
|
|
89
|
-
edges_to_delete: list[EdgeToDelete] = []
|
|
90
|
-
edges_to_add: list[EdgeToAdd] = []
|
|
91
|
-
for result in results:
|
|
92
|
-
serial_vertex_to_delete = result.get("vertex_to_delete")
|
|
93
|
-
if serial_vertex_to_delete:
|
|
94
|
-
vertex_to_delete = VertexToDelete(**serial_vertex_to_delete)
|
|
95
|
-
vertices_to_delete.append(vertex_to_delete)
|
|
96
|
-
for serial_edge_to_delete in result.get("edges_to_delete"):
|
|
97
|
-
edge_to_delete = EdgeToDelete(**serial_edge_to_delete)
|
|
98
|
-
edges_to_delete.append(edge_to_delete)
|
|
99
|
-
for serial_edge_to_create in result.get("edges_to_create"):
|
|
100
|
-
edges_to_add.append(EdgeToAdd(**serial_edge_to_create))
|
|
101
|
-
return PatchPlan(
|
|
102
|
-
name=self.name,
|
|
103
|
-
vertices_to_delete=vertices_to_delete,
|
|
104
|
-
edges_to_add=edges_to_add,
|
|
105
|
-
edges_to_delete=edges_to_delete,
|
|
106
|
-
)
|
|
File without changes
|
|
File without changes
|