infrahub-server 1.2.12__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/actions/constants.py +130 -0
- infrahub/actions/gather.py +114 -0
- infrahub/actions/models.py +243 -0
- infrahub/actions/parsers.py +104 -0
- infrahub/actions/schema.py +393 -0
- infrahub/actions/tasks.py +119 -0
- infrahub/actions/triggers.py +21 -0
- infrahub/branch/__init__.py +0 -0
- infrahub/branch/tasks.py +29 -0
- infrahub/branch/triggers.py +22 -0
- infrahub/cli/db.py +3 -4
- infrahub/computed_attribute/gather.py +3 -1
- infrahub/computed_attribute/tasks.py +23 -29
- infrahub/core/account.py +24 -47
- infrahub/core/attribute.py +13 -15
- infrahub/core/constants/__init__.py +10 -0
- infrahub/core/constants/infrahubkind.py +9 -0
- infrahub/core/constraint/node/runner.py +3 -1
- infrahub/core/convert_object_type/__init__.py +0 -0
- infrahub/core/convert_object_type/conversion.py +124 -0
- infrahub/core/convert_object_type/schema_mapping.py +56 -0
- infrahub/core/diff/coordinator.py +8 -1
- infrahub/core/diff/query/all_conflicts.py +1 -5
- infrahub/core/diff/query/artifact.py +10 -20
- infrahub/core/diff/query/delete_query.py +8 -4
- infrahub/core/diff/query/diff_get.py +3 -6
- infrahub/core/diff/query/field_specifiers.py +1 -1
- infrahub/core/diff/query/field_summary.py +2 -4
- infrahub/core/diff/query/merge.py +72 -125
- infrahub/core/diff/query/save.py +28 -43
- infrahub/core/diff/query/summary_counts_enricher.py +34 -54
- infrahub/core/diff/query/time_range_query.py +0 -1
- infrahub/core/diff/repository/repository.py +4 -0
- infrahub/core/manager.py +14 -11
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +1 -2
- infrahub/core/migrations/graph/m012_convert_account_generic.py +1 -1
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +2 -6
- infrahub/core/migrations/graph/m015_diff_format_update.py +1 -2
- infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -2
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +11 -22
- infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -6
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +1 -2
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +2 -2
- infrahub/core/migrations/graph/m024_missing_hierarchy_backfill.py +1 -2
- infrahub/core/migrations/graph/m028_delete_diffs.py +1 -2
- infrahub/core/migrations/graph/m029_duplicates_cleanup.py +30 -48
- infrahub/core/migrations/graph/m030_illegal_edges.py +1 -2
- infrahub/core/migrations/query/attribute_add.py +1 -2
- infrahub/core/migrations/query/attribute_rename.py +6 -11
- infrahub/core/migrations/query/delete_element_in_schema.py +19 -17
- infrahub/core/migrations/query/node_duplicate.py +19 -21
- infrahub/core/migrations/query/relationship_duplicate.py +19 -18
- infrahub/core/migrations/schema/node_attribute_remove.py +4 -8
- infrahub/core/migrations/schema/node_remove.py +19 -20
- infrahub/core/models.py +29 -2
- infrahub/core/node/__init__.py +131 -28
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/create.py +211 -0
- infrahub/core/node/resource_manager/number_pool.py +31 -5
- infrahub/core/node/standard.py +6 -1
- infrahub/core/path.py +15 -1
- infrahub/core/protocols.py +57 -0
- infrahub/core/protocols_base.py +3 -0
- infrahub/core/query/__init__.py +2 -2
- infrahub/core/query/delete.py +3 -3
- infrahub/core/query/diff.py +19 -32
- infrahub/core/query/ipam.py +10 -20
- infrahub/core/query/node.py +29 -47
- infrahub/core/query/relationship.py +55 -34
- infrahub/core/query/resource_manager.py +1 -2
- infrahub/core/query/standard_node.py +19 -5
- infrahub/core/query/subquery.py +2 -4
- infrahub/core/relationship/constraints/count.py +10 -9
- infrahub/core/relationship/constraints/interface.py +2 -1
- infrahub/core/relationship/constraints/peer_kind.py +2 -1
- infrahub/core/relationship/constraints/peer_parent.py +56 -0
- infrahub/core/relationship/constraints/peer_relatives.py +72 -0
- infrahub/core/relationship/constraints/profiles_kind.py +1 -1
- infrahub/core/relationship/model.py +4 -1
- infrahub/core/schema/__init__.py +2 -1
- infrahub/core/schema/attribute_parameters.py +160 -0
- infrahub/core/schema/attribute_schema.py +130 -7
- infrahub/core/schema/basenode_schema.py +27 -3
- infrahub/core/schema/definitions/core/__init__.py +29 -1
- infrahub/core/schema/definitions/core/group.py +45 -0
- infrahub/core/schema/definitions/core/resource_pool.py +9 -0
- infrahub/core/schema/definitions/internal.py +43 -5
- infrahub/core/schema/generated/attribute_schema.py +16 -3
- infrahub/core/schema/generated/relationship_schema.py +11 -1
- infrahub/core/schema/manager.py +7 -2
- infrahub/core/schema/schema_branch.py +104 -9
- infrahub/core/validators/__init__.py +15 -2
- infrahub/core/validators/attribute/choices.py +1 -3
- infrahub/core/validators/attribute/enum.py +1 -3
- infrahub/core/validators/attribute/kind.py +1 -3
- infrahub/core/validators/attribute/length.py +13 -7
- infrahub/core/validators/attribute/min_max.py +118 -0
- infrahub/core/validators/attribute/number_pool.py +106 -0
- infrahub/core/validators/attribute/optional.py +1 -4
- infrahub/core/validators/attribute/regex.py +5 -6
- infrahub/core/validators/attribute/unique.py +1 -3
- infrahub/core/validators/determiner.py +18 -2
- infrahub/core/validators/enum.py +12 -0
- infrahub/core/validators/node/hierarchy.py +3 -6
- infrahub/core/validators/query.py +1 -3
- infrahub/core/validators/relationship/count.py +6 -12
- infrahub/core/validators/relationship/optional.py +2 -4
- infrahub/core/validators/relationship/peer.py +177 -12
- infrahub/core/validators/tasks.py +1 -1
- infrahub/core/validators/uniqueness/query.py +5 -9
- infrahub/database/__init__.py +12 -4
- infrahub/database/validation.py +1 -2
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +4 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_parent.py +8 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
- infrahub/dependencies/builder/constraint/schema/aggregated.py +2 -0
- infrahub/dependencies/builder/constraint/schema/relationship_peer.py +8 -0
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/registry.py +4 -0
- infrahub/events/group_action.py +1 -0
- infrahub/events/models.py +1 -1
- infrahub/git/base.py +5 -3
- infrahub/git/integrator.py +96 -5
- infrahub/git/tasks.py +1 -0
- infrahub/graphql/analyzer.py +139 -18
- infrahub/graphql/manager.py +4 -0
- infrahub/graphql/mutations/action.py +164 -0
- infrahub/graphql/mutations/convert_object_type.py +71 -0
- infrahub/graphql/mutations/main.py +24 -175
- infrahub/graphql/mutations/proposed_change.py +20 -17
- infrahub/graphql/mutations/relationship.py +32 -0
- infrahub/graphql/mutations/resource_manager.py +63 -7
- infrahub/graphql/queries/convert_object_type_mapping.py +34 -0
- infrahub/graphql/queries/resource_manager.py +7 -1
- 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/schema.py +6 -0
- infrahub/menu/menu.py +34 -2
- infrahub/message_bus/messages/__init__.py +0 -10
- infrahub/message_bus/operations/__init__.py +0 -8
- infrahub/message_bus/operations/refresh/registry.py +3 -6
- infrahub/patch/queries/delete_duplicated_edges.py +10 -15
- infrahub/pools/models.py +14 -0
- infrahub/pools/number.py +5 -3
- infrahub/pools/registration.py +22 -0
- infrahub/pools/tasks.py +126 -0
- infrahub/prefect_server/models.py +1 -19
- infrahub/proposed_change/models.py +68 -3
- infrahub/proposed_change/tasks.py +911 -34
- infrahub/schema/__init__.py +0 -0
- infrahub/schema/tasks.py +27 -0
- infrahub/schema/triggers.py +23 -0
- infrahub/task_manager/models.py +10 -6
- infrahub/trigger/catalogue.py +6 -0
- infrahub/trigger/models.py +23 -6
- infrahub/trigger/setup.py +26 -2
- infrahub/trigger/tasks.py +4 -2
- infrahub/types.py +6 -0
- infrahub/webhook/tasks.py +4 -8
- infrahub/workflows/catalogue.py +103 -1
- infrahub_sdk/client.py +43 -10
- infrahub_sdk/ctl/generator.py +4 -4
- infrahub_sdk/ctl/repository.py +1 -1
- 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} +158 -803
- 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/pytest_plugin/items/python_transform.py +2 -1
- infrahub_sdk/query_groups.py +17 -5
- 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_sdk/utils.py +7 -20
- infrahub_sdk/yaml.py +6 -5
- {infrahub_server-1.2.12.dist-info → infrahub_server-1.3.0.dist-info}/METADATA +3 -3
- {infrahub_server-1.2.12.dist-info → infrahub_server-1.3.0.dist-info}/RECORD +192 -166
- infrahub_testcontainers/container.py +0 -1
- infrahub_testcontainers/docker-compose.test.yml +1 -1
- infrahub_testcontainers/helpers.py +8 -2
- infrahub/message_bus/messages/check_generator_run.py +0 -26
- infrahub/message_bus/messages/finalize_validator_execution.py +0 -15
- infrahub/message_bus/messages/proposed_change/base_with_diff.py +0 -16
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +0 -11
- infrahub/message_bus/messages/request_generatordefinition_check.py +0 -20
- infrahub/message_bus/messages/request_proposedchange_pipeline.py +0 -23
- infrahub/message_bus/operations/check/__init__.py +0 -3
- infrahub/message_bus/operations/check/generator.py +0 -156
- infrahub/message_bus/operations/finalize/__init__.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +0 -133
- infrahub/message_bus/operations/requests/__init__.py +0 -9
- infrahub/message_bus/operations/requests/generator_definition.py +0 -140
- infrahub/message_bus/operations/requests/proposed_change.py +0 -629
- /infrahub/{message_bus/messages/proposed_change → actions}/__init__.py +0 -0
- {infrahub_server-1.2.12.dist-info → infrahub_server-1.3.0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.12.dist-info → infrahub_server-1.3.0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.2.12.dist-info → infrahub_server-1.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -2,17 +2,17 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
|
-
from infrahub
|
|
5
|
+
from infrahub import config
|
|
6
|
+
from infrahub.core.constants import PathType, RelationshipKind
|
|
6
7
|
from infrahub.core.path import DataPath, GroupedDataPaths
|
|
7
8
|
from infrahub.core.schema import GenericSchema
|
|
8
9
|
|
|
9
10
|
from ..interface import ConstraintCheckerInterface
|
|
10
|
-
from ..shared import
|
|
11
|
-
RelationshipSchemaValidatorQuery,
|
|
12
|
-
)
|
|
11
|
+
from ..shared import RelationshipSchemaValidatorQuery
|
|
13
12
|
|
|
14
13
|
if TYPE_CHECKING:
|
|
15
14
|
from infrahub.core.branch import Branch
|
|
15
|
+
from infrahub.core.schema.relationship_schema import RelationshipSchema
|
|
16
16
|
from infrahub.database import InfrahubDatabase
|
|
17
17
|
|
|
18
18
|
from ..model import SchemaConstraintValidatorRequest
|
|
@@ -36,8 +36,7 @@ class RelationshipPeerUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
|
36
36
|
# ruff: noqa: E501
|
|
37
37
|
query = """
|
|
38
38
|
MATCH (n:%(node_kind)s)
|
|
39
|
-
CALL {
|
|
40
|
-
WITH n
|
|
39
|
+
CALL (n) {
|
|
41
40
|
MATCH path = (root:Root)<-[rroot:IS_PART_OF]-(n)
|
|
42
41
|
WHERE all(r in relationships(path) WHERE %(branch_filter)s)
|
|
43
42
|
RETURN path as full_path, n as active_node
|
|
@@ -45,10 +44,8 @@ class RelationshipPeerUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
|
45
44
|
LIMIT 1
|
|
46
45
|
}
|
|
47
46
|
WITH full_path, active_node
|
|
48
|
-
WITH full_path, active_node
|
|
49
47
|
WHERE all(r in relationships(full_path) WHERE r.status = "active")
|
|
50
|
-
CALL {
|
|
51
|
-
WITH active_node
|
|
48
|
+
CALL (active_node) {
|
|
52
49
|
MATCH path = (active_node)-[rrel1:IS_RELATED]-(rel:Relationship { name: $relationship_id })-[rrel2:IS_RELATED]-(peer:Node)
|
|
53
50
|
WHERE all(
|
|
54
51
|
r in relationships(path)
|
|
@@ -68,8 +65,7 @@ class RelationshipPeerUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
|
68
65
|
collect([branch_level_sum, from_times, active_relationship_count, relationship_path, deepest_branch_name]) as enriched_paths,
|
|
69
66
|
start_node,
|
|
70
67
|
peer_node
|
|
71
|
-
CALL {
|
|
72
|
-
WITH enriched_paths, peer_node
|
|
68
|
+
CALL (enriched_paths, peer_node) {
|
|
73
69
|
UNWIND enriched_paths as path_to_check
|
|
74
70
|
RETURN path_to_check[3] as current_path, path_to_check[4] as branch_name, peer_node as current_peer
|
|
75
71
|
ORDER BY
|
|
@@ -80,7 +76,6 @@ class RelationshipPeerUpdateValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
|
80
76
|
LIMIT 1
|
|
81
77
|
}
|
|
82
78
|
WITH start_node, current_peer, branch_name, current_path
|
|
83
|
-
WITH start_node, current_peer, branch_name, current_path
|
|
84
79
|
WHERE all(r in relationships(current_path) WHERE r.status = "active")
|
|
85
80
|
AND NOT any(label IN LABELS(current_peer) WHERE label IN $allowed_peer_kinds)
|
|
86
81
|
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}
|
|
@@ -130,3 +125,173 @@ class RelationshipPeerChecker(ConstraintCheckerInterface):
|
|
|
130
125
|
await query.execute(db=self.db)
|
|
131
126
|
grouped_data_paths_list.append(await query.get_paths())
|
|
132
127
|
return grouped_data_paths_list
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class RelationshipPeerParentValidatorQuery(RelationshipSchemaValidatorQuery):
|
|
131
|
+
name = "relationship_constraints_peer_parent_validator"
|
|
132
|
+
|
|
133
|
+
def __init__(
|
|
134
|
+
self,
|
|
135
|
+
relationship: RelationshipSchema,
|
|
136
|
+
parent_relationship: RelationshipSchema,
|
|
137
|
+
peer_parent_relationship: RelationshipSchema,
|
|
138
|
+
**kwargs: Any,
|
|
139
|
+
):
|
|
140
|
+
super().__init__(**kwargs)
|
|
141
|
+
|
|
142
|
+
self.relationship = relationship
|
|
143
|
+
self.parent_relationship = parent_relationship
|
|
144
|
+
self.peer_parent_relationship = peer_parent_relationship
|
|
145
|
+
|
|
146
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
147
|
+
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
|
|
148
|
+
self.params.update(branch_params)
|
|
149
|
+
self.params["peer_relationship_id"] = self.relationship.identifier
|
|
150
|
+
self.params["parent_relationship_id"] = self.parent_relationship.identifier
|
|
151
|
+
self.params["peer_parent_relationship_id"] = self.peer_parent_relationship.identifier
|
|
152
|
+
|
|
153
|
+
parent_arrows = self.parent_relationship.get_query_arrows()
|
|
154
|
+
parent_match = (
|
|
155
|
+
"MATCH (active_node)%(lstart)s[r1:IS_RELATED]%(lend)s"
|
|
156
|
+
"(rel:Relationship { name: $parent_relationship_id })%(rstart)s[r2:IS_RELATED]%(rend)s(parent:Node)"
|
|
157
|
+
) % {
|
|
158
|
+
"lstart": parent_arrows.left.start,
|
|
159
|
+
"lend": parent_arrows.left.end,
|
|
160
|
+
"rstart": parent_arrows.right.start,
|
|
161
|
+
"rend": parent_arrows.right.end,
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
peer_parent_arrows = self.relationship.get_query_arrows()
|
|
165
|
+
peer_match = (
|
|
166
|
+
"MATCH (active_node)%(lstart)s[r1:IS_RELATED]%(lend)s"
|
|
167
|
+
"(r:Relationship {name: $peer_relationship_id })%(rstart)s[r2:IS_RELATED]%(rend)s(peer:Node)"
|
|
168
|
+
) % {
|
|
169
|
+
"lstart": peer_parent_arrows.left.start,
|
|
170
|
+
"lend": peer_parent_arrows.left.end,
|
|
171
|
+
"rstart": peer_parent_arrows.right.start,
|
|
172
|
+
"rend": peer_parent_arrows.right.end,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
peer_parent_arrows = self.peer_parent_relationship.get_query_arrows()
|
|
176
|
+
peer_parent_match = (
|
|
177
|
+
"MATCH (peer:Node)%(lstart)s[r1:IS_RELATED]%(lend)s"
|
|
178
|
+
"(r:Relationship {name: $peer_parent_relationship_id})%(rstart)s[r2:IS_RELATED]%(rend)s(peer_parent:Node)"
|
|
179
|
+
) % {
|
|
180
|
+
"lstart": peer_parent_arrows.left.start,
|
|
181
|
+
"lend": peer_parent_arrows.left.end,
|
|
182
|
+
"rstart": peer_parent_arrows.right.start,
|
|
183
|
+
"rend": peer_parent_arrows.right.end,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
query = """
|
|
187
|
+
MATCH (n:%(node_kind)s)
|
|
188
|
+
CALL (n) {
|
|
189
|
+
MATCH path = (root:Root)<-[r:IS_PART_OF]-(n)
|
|
190
|
+
WHERE %(branch_filter)s
|
|
191
|
+
RETURN n as active_node, r.status = "active" AS is_active
|
|
192
|
+
ORDER BY r.branch_level DESC, r.from DESC
|
|
193
|
+
LIMIT 1
|
|
194
|
+
}
|
|
195
|
+
WITH active_node, is_active
|
|
196
|
+
WHERE is_active = TRUE
|
|
197
|
+
%(parent_match)s
|
|
198
|
+
WHERE all(r in [r1, r2] WHERE %(branch_filter)s AND r.status = "active")
|
|
199
|
+
CALL (active_node) {
|
|
200
|
+
%(peer_match)s
|
|
201
|
+
WITH DISTINCT active_node, peer
|
|
202
|
+
%(peer_match)s
|
|
203
|
+
WHERE all(r in [r1, r2] WHERE %(branch_filter)s)
|
|
204
|
+
WITH peer, r1.status = "active" AND r2.status = "active" AS is_active
|
|
205
|
+
ORDER BY peer.uuid, r1.branch_level DESC, r2.branch_level DESC, r1.from DESC, r2.from DESC, is_active DESC
|
|
206
|
+
WITH peer, head(collect(is_active)) AS is_active
|
|
207
|
+
WHERE is_active = TRUE
|
|
208
|
+
RETURN peer
|
|
209
|
+
}
|
|
210
|
+
CALL (peer) {
|
|
211
|
+
%(peer_parent_match)s
|
|
212
|
+
WHERE all(r IN [r1, r2] WHERE %(branch_filter)s)
|
|
213
|
+
WITH peer_parent, r1, r2, r1.status = "active" AND r2.status = "active" AS is_active
|
|
214
|
+
WITH peer_parent, r1.branch AS branch_name, is_active
|
|
215
|
+
ORDER BY r1.branch_level DESC, r2.branch_level DESC, r1.from DESC, r2.from DESC, is_active DESC
|
|
216
|
+
LIMIT 1
|
|
217
|
+
WITH peer_parent, branch_name
|
|
218
|
+
WHERE is_active = TRUE
|
|
219
|
+
RETURN peer_parent, branch_name
|
|
220
|
+
}
|
|
221
|
+
WITH DISTINCT active_node, parent, peer, peer_parent, branch_name
|
|
222
|
+
WHERE parent.uuid <> peer_parent.uuid
|
|
223
|
+
""" % {
|
|
224
|
+
"branch_filter": branch_filter,
|
|
225
|
+
"node_kind": self.node_schema.kind,
|
|
226
|
+
"parent_match": parent_match,
|
|
227
|
+
"peer_match": peer_match,
|
|
228
|
+
"peer_parent_match": peer_parent_match,
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
self.add_to_query(query)
|
|
232
|
+
self.return_labels = ["active_node.uuid", "parent.uuid", "peer.uuid", "peer_parent.uuid", "branch_name"]
|
|
233
|
+
|
|
234
|
+
async def get_paths(self) -> GroupedDataPaths:
|
|
235
|
+
grouped_data_paths = GroupedDataPaths()
|
|
236
|
+
|
|
237
|
+
for result in self.results:
|
|
238
|
+
grouped_data_paths.add_data_path(
|
|
239
|
+
DataPath(
|
|
240
|
+
branch=str(result.get("branch_name")),
|
|
241
|
+
path_type=PathType.RELATIONSHIP_ONE,
|
|
242
|
+
node_id=str(result.get("peer.uuid")),
|
|
243
|
+
field_name=self.peer_parent_relationship.name,
|
|
244
|
+
peer_id=str(result.get("peer_parent.uuid")),
|
|
245
|
+
kind=self.relationship.peer,
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
return grouped_data_paths
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class RelationshipPeerParentChecker(ConstraintCheckerInterface):
|
|
253
|
+
query_classes = [RelationshipPeerParentValidatorQuery]
|
|
254
|
+
|
|
255
|
+
def __init__(self, db: InfrahubDatabase, branch: Branch | None = None) -> None:
|
|
256
|
+
self.db = db
|
|
257
|
+
self.branch = branch
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def name(self) -> str:
|
|
261
|
+
return "relationship.common_parent.update"
|
|
262
|
+
|
|
263
|
+
def supports(self, request: SchemaConstraintValidatorRequest) -> bool:
|
|
264
|
+
return request.constraint_name == self.name and config.SETTINGS.main.schema_strict_mode
|
|
265
|
+
|
|
266
|
+
async def check(self, request: SchemaConstraintValidatorRequest) -> list[GroupedDataPaths]:
|
|
267
|
+
grouped_data_paths_list: list[GroupedDataPaths] = []
|
|
268
|
+
|
|
269
|
+
if not request.schema_path.field_name:
|
|
270
|
+
return grouped_data_paths_list
|
|
271
|
+
|
|
272
|
+
relationship = request.node_schema.get_relationship(name=request.schema_path.field_name)
|
|
273
|
+
if not relationship.common_parent:
|
|
274
|
+
# Should not happen if schema validation was done properly
|
|
275
|
+
return grouped_data_paths_list
|
|
276
|
+
|
|
277
|
+
parent_relationship = next(
|
|
278
|
+
iter(request.node_schema.get_relationships_of_kind(relationship_kinds=[RelationshipKind.PARENT]))
|
|
279
|
+
)
|
|
280
|
+
peer_parent_relationship = request.schema_branch.get(name=relationship.peer, duplicate=False).get_relationship(
|
|
281
|
+
name=relationship.common_parent
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
for query_class in self.query_classes:
|
|
285
|
+
query = await query_class.init(
|
|
286
|
+
db=self.db,
|
|
287
|
+
branch=self.branch,
|
|
288
|
+
node_schema=request.node_schema,
|
|
289
|
+
schema_path=request.schema_path,
|
|
290
|
+
relationship=relationship,
|
|
291
|
+
parent_relationship=parent_relationship,
|
|
292
|
+
peer_parent_relationship=peer_parent_relationship,
|
|
293
|
+
)
|
|
294
|
+
await query.execute(db=self.db)
|
|
295
|
+
grouped_data_paths_list.append(await query.get_paths())
|
|
296
|
+
|
|
297
|
+
return grouped_data_paths_list
|
|
@@ -9,7 +9,7 @@ from prefect.logging import get_run_logger
|
|
|
9
9
|
|
|
10
10
|
from infrahub.core.branch import Branch # noqa: TC001
|
|
11
11
|
from infrahub.core.path import SchemaPath # noqa: TC001
|
|
12
|
-
from infrahub.core.schema import GenericSchema, NodeSchema
|
|
12
|
+
from infrahub.core.schema import GenericSchema, NodeSchema
|
|
13
13
|
from infrahub.core.validators.aggregated_checker import AggregatedConstraintChecker
|
|
14
14
|
from infrahub.core.validators.model import (
|
|
15
15
|
SchemaConstraintValidatorRequest,
|
|
@@ -158,12 +158,11 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
158
158
|
# ruff: noqa: E501
|
|
159
159
|
query = """
|
|
160
160
|
// get attributes for node and its relationships
|
|
161
|
-
CALL {
|
|
161
|
+
CALL () {
|
|
162
162
|
%(select_subqueries_str)s
|
|
163
163
|
}
|
|
164
|
-
CALL {
|
|
164
|
+
CALL (potential_path) {
|
|
165
165
|
WITH potential_path
|
|
166
|
-
WITH potential_path // workaround for neo4j not allowing WHERE in a WITH of a subquery
|
|
167
166
|
// only the branches and times we care about
|
|
168
167
|
WHERE all(
|
|
169
168
|
r IN relationships(potential_path) WHERE (
|
|
@@ -183,8 +182,7 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
183
182
|
start_node,
|
|
184
183
|
rel_identifier,
|
|
185
184
|
potential_attr
|
|
186
|
-
CALL {
|
|
187
|
-
WITH enriched_paths
|
|
185
|
+
CALL (enriched_paths) {
|
|
188
186
|
UNWIND enriched_paths as path_to_check
|
|
189
187
|
RETURN path_to_check[0] as current_path, path_to_check[4] as latest_value
|
|
190
188
|
ORDER BY
|
|
@@ -194,16 +192,14 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
194
192
|
path_to_check[3] DESC
|
|
195
193
|
LIMIT 1
|
|
196
194
|
}
|
|
197
|
-
CALL {
|
|
195
|
+
CALL (current_path) {
|
|
198
196
|
// only active paths
|
|
199
197
|
WITH current_path
|
|
200
|
-
WITH current_path // workaround for neo4j not allowing WHERE in a WITH of a subquery
|
|
201
198
|
WHERE all(r IN relationships(current_path) WHERE r.status = "active")
|
|
202
199
|
RETURN current_path as active_path
|
|
203
200
|
}
|
|
204
|
-
CALL {
|
|
201
|
+
CALL (active_path) {
|
|
205
202
|
// get deepest branch name
|
|
206
|
-
WITH active_path
|
|
207
203
|
UNWIND %(branch_name_and_level)s as branch_name_and_level
|
|
208
204
|
RETURN branch_name_and_level[0] as branch_name
|
|
209
205
|
ORDER BY branch_name_and_level[1] DESC
|
infrahub/database/__init__.py
CHANGED
|
@@ -39,7 +39,7 @@ if TYPE_CHECKING:
|
|
|
39
39
|
from types import TracebackType
|
|
40
40
|
|
|
41
41
|
from infrahub.core.branch import Branch
|
|
42
|
-
from infrahub.core.schema import MainSchemaTypes, NodeSchema
|
|
42
|
+
from infrahub.core.schema import GenericSchema, MainSchemaTypes, NodeSchema
|
|
43
43
|
from infrahub.core.schema.schema_branch import SchemaBranch
|
|
44
44
|
|
|
45
45
|
validated_database = {}
|
|
@@ -91,6 +91,15 @@ class DatabaseSchemaManager:
|
|
|
91
91
|
|
|
92
92
|
raise ValueError("The selected node is not of type NodeSchema")
|
|
93
93
|
|
|
94
|
+
def get_generic_schema(
|
|
95
|
+
self, name: str, branch: Branch | str | None = None, duplicate: bool = True
|
|
96
|
+
) -> GenericSchema:
|
|
97
|
+
schema = self.get(name=name, branch=branch, duplicate=duplicate)
|
|
98
|
+
if schema.is_generic_schema:
|
|
99
|
+
return schema
|
|
100
|
+
|
|
101
|
+
raise ValueError("The selected node is not of type GenericSchema")
|
|
102
|
+
|
|
94
103
|
def set(self, name: str, schema: MainSchemaTypes, branch: str | None = None) -> int:
|
|
95
104
|
branch_name = get_branch_name(branch=branch)
|
|
96
105
|
if branch_name not in self._db._schemas:
|
|
@@ -284,7 +293,7 @@ class InfrahubDatabase:
|
|
|
284
293
|
exc_type: type[BaseException] | None,
|
|
285
294
|
exc_value: BaseException | None,
|
|
286
295
|
traceback: TracebackType | None,
|
|
287
|
-
):
|
|
296
|
+
) -> None:
|
|
288
297
|
if self._mode == InfrahubDatabaseMode.SESSION:
|
|
289
298
|
return await self._session.close()
|
|
290
299
|
|
|
@@ -330,7 +339,7 @@ class InfrahubDatabase:
|
|
|
330
339
|
CONNECTION_POOL_USAGE.labels(self._driver._pool.address).set(float(connpool_usage))
|
|
331
340
|
|
|
332
341
|
if config.SETTINGS.database.max_concurrent_queries:
|
|
333
|
-
while connpool_usage > config.SETTINGS.database.max_concurrent_queries:
|
|
342
|
+
while connpool_usage > config.SETTINGS.database.max_concurrent_queries:
|
|
334
343
|
await asyncio.sleep(config.SETTINGS.database.max_concurrent_queries_delay)
|
|
335
344
|
connpool_usage = self._driver._pool.in_use_connection_count(self._driver._pool.address)
|
|
336
345
|
|
|
@@ -489,7 +498,6 @@ async def get_db(retry: int = 0) -> AsyncDriver:
|
|
|
489
498
|
trusted_certificates=trusted_certificates,
|
|
490
499
|
notifications_disabled_categories=[
|
|
491
500
|
NotificationDisabledCategory.UNRECOGNIZED,
|
|
492
|
-
NotificationDisabledCategory.DEPRECATION, # TODO: Remove me with 1.3
|
|
493
501
|
],
|
|
494
502
|
notifications_min_severity=NotificationMinimumSeverity.WARNING,
|
|
495
503
|
)
|
infrahub/database/validation.py
CHANGED
|
@@ -65,8 +65,7 @@ WITH DISTINCT n, delete_branch, delete_time, added_e, peer AS added_peer
|
|
|
65
65
|
// ------------
|
|
66
66
|
// get the branched_from for the branch on which the node was deleted
|
|
67
67
|
// ------------
|
|
68
|
-
CALL {
|
|
69
|
-
WITH added_e
|
|
68
|
+
CALL (added_e) {
|
|
70
69
|
MATCH (b:Branch {name: added_e.branch})
|
|
71
70
|
RETURN b.branched_from AS added_e_branched_from
|
|
72
71
|
}
|
|
@@ -4,6 +4,8 @@ from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilder
|
|
|
4
4
|
from ..node.grouped_uniqueness import NodeGroupedUniquenessConstraintDependency
|
|
5
5
|
from ..relationship_manager.count import RelationshipCountConstraintDependency
|
|
6
6
|
from ..relationship_manager.peer_kind import RelationshipPeerKindConstraintDependency
|
|
7
|
+
from ..relationship_manager.peer_parent import RelationshipPeerParentConstraintDependency
|
|
8
|
+
from ..relationship_manager.peer_relatives import RelationshipPeerRelativesConstraintDependency
|
|
7
9
|
from ..relationship_manager.profiles_kind import RelationshipProfilesKindConstraintDependency
|
|
8
10
|
|
|
9
11
|
|
|
@@ -18,5 +20,7 @@ class NodeConstraintRunnerDependency(DependencyBuilder[NodeConstraintRunner]):
|
|
|
18
20
|
RelationshipPeerKindConstraintDependency.build(context=context),
|
|
19
21
|
RelationshipCountConstraintDependency.build(context=context),
|
|
20
22
|
RelationshipProfilesKindConstraintDependency.build(context=context),
|
|
23
|
+
RelationshipPeerParentConstraintDependency.build(context=context),
|
|
24
|
+
RelationshipPeerRelativesConstraintDependency.build(context=context),
|
|
21
25
|
],
|
|
22
26
|
)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from infrahub.core.relationship.constraints.peer_parent import RelationshipPeerParentConstraint
|
|
2
|
+
from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class RelationshipPeerParentConstraintDependency(DependencyBuilder[RelationshipPeerParentConstraint]):
|
|
6
|
+
@classmethod
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> RelationshipPeerParentConstraint:
|
|
8
|
+
return RelationshipPeerParentConstraint(db=context.db, branch=context.branch)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from infrahub.core.relationship.constraints.peer_relatives import RelationshipPeerRelativesConstraint
|
|
2
|
+
from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class RelationshipPeerRelativesConstraintDependency(DependencyBuilder[RelationshipPeerRelativesConstraint]):
|
|
6
|
+
@classmethod
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> RelationshipPeerRelativesConstraint:
|
|
8
|
+
return RelationshipPeerRelativesConstraint(db=context.db, branch=context.branch)
|
|
@@ -14,6 +14,7 @@ from .node_attribute import SchemaNodeAttributeAddConstraintDependency
|
|
|
14
14
|
from .node_relationship import SchemaNodeRelationshipAddConstraintDependency
|
|
15
15
|
from .relationship_count import SchemaRelationshipCountConstraintDependency
|
|
16
16
|
from .relationship_optional import SchemaRelationshipOptionalConstraintDependency
|
|
17
|
+
from .relationship_peer import SchemaRelationshipPeerParentConstraintDependency
|
|
17
18
|
from .uniqueness import SchemaUniquenessConstraintDependency
|
|
18
19
|
|
|
19
20
|
|
|
@@ -36,6 +37,7 @@ class AggregatedSchemaConstraintsDependency(DependencyBuilder[AggregatedConstrai
|
|
|
36
37
|
SchemaAttributeKindConstraintDependency.build(context=context),
|
|
37
38
|
SchemaNodeAttributeAddConstraintDependency.build(context=context),
|
|
38
39
|
SchemaNodeRelationshipAddConstraintDependency.build(context=context),
|
|
40
|
+
SchemaRelationshipPeerParentConstraintDependency.build(context=context),
|
|
39
41
|
],
|
|
40
42
|
db=context.db,
|
|
41
43
|
branch=context.branch,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from infrahub.core.validators.relationship.peer import RelationshipPeerParentChecker
|
|
2
|
+
from infrahub.dependencies.interface import DependencyBuilder, DependencyBuilderContext
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SchemaRelationshipPeerParentConstraintDependency(DependencyBuilder[RelationshipPeerParentChecker]):
|
|
6
|
+
@classmethod
|
|
7
|
+
def build(cls, context: DependencyBuilderContext) -> RelationshipPeerParentChecker:
|
|
8
|
+
return RelationshipPeerParentChecker(db=context.db, branch=context.branch)
|
|
@@ -6,5 +6,5 @@ from .parent_node_adder import DiffParentNodeAdderDependency
|
|
|
6
6
|
|
|
7
7
|
class DiffDeserializerDependency(DependencyBuilder[EnrichedDiffDeserializer]):
|
|
8
8
|
@classmethod
|
|
9
|
-
def build(cls, context: DependencyBuilderContext) -> EnrichedDiffDeserializer:
|
|
9
|
+
def build(cls, context: DependencyBuilderContext) -> EnrichedDiffDeserializer:
|
|
10
10
|
return EnrichedDiffDeserializer(parent_adder=DiffParentNodeAdderDependency.build(context=context))
|
|
@@ -3,6 +3,8 @@ from .builder.constraint.node.grouped_uniqueness import NodeGroupedUniquenessCon
|
|
|
3
3
|
from .builder.constraint.node.uniqueness import NodeAttributeUniquenessConstraintDependency
|
|
4
4
|
from .builder.constraint.relationship_manager.count import RelationshipCountConstraintDependency
|
|
5
5
|
from .builder.constraint.relationship_manager.peer_kind import RelationshipPeerKindConstraintDependency
|
|
6
|
+
from .builder.constraint.relationship_manager.peer_parent import RelationshipPeerParentConstraintDependency
|
|
7
|
+
from .builder.constraint.relationship_manager.peer_relatives import RelationshipPeerRelativesConstraintDependency
|
|
6
8
|
from .builder.constraint.relationship_manager.profiles_kind import RelationshipProfilesKindConstraintDependency
|
|
7
9
|
from .builder.constraint.schema.aggregated import AggregatedSchemaConstraintsDependency
|
|
8
10
|
from .builder.constraint.schema.attribute_regex import SchemaAttributeRegexConstraintDependency
|
|
@@ -37,6 +39,8 @@ def build_component_registry() -> ComponentDependencyRegistry:
|
|
|
37
39
|
component_registry.track_dependency(RelationshipCountConstraintDependency)
|
|
38
40
|
component_registry.track_dependency(RelationshipProfilesKindConstraintDependency)
|
|
39
41
|
component_registry.track_dependency(RelationshipPeerKindConstraintDependency)
|
|
42
|
+
component_registry.track_dependency(RelationshipPeerParentConstraintDependency)
|
|
43
|
+
component_registry.track_dependency(RelationshipPeerRelativesConstraintDependency)
|
|
40
44
|
component_registry.track_dependency(NodeConstraintRunnerDependency)
|
|
41
45
|
component_registry.track_dependency(NodeDeleteValidatorDependency)
|
|
42
46
|
component_registry.track_dependency(IpamKindsGetterDependency)
|
infrahub/events/group_action.py
CHANGED
infrahub/events/models.py
CHANGED
|
@@ -8,7 +8,7 @@ from pydantic import BaseModel, Field, PrivateAttr, model_validator
|
|
|
8
8
|
|
|
9
9
|
from infrahub import __version__
|
|
10
10
|
from infrahub.auth import AccountSession, AuthType
|
|
11
|
-
from infrahub.context import InfrahubContext
|
|
11
|
+
from infrahub.context import InfrahubContext
|
|
12
12
|
from infrahub.core.branch import Branch # noqa: TC001
|
|
13
13
|
from infrahub.message_bus import InfrahubMessage, Meta
|
|
14
14
|
from infrahub.worker import WORKER_IDENTITY
|
infrahub/git/base.py
CHANGED
|
@@ -162,6 +162,11 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
162
162
|
infrahub_branch_name: str | None = Field(None, description="Infrahub branch on which to sync the remote repository")
|
|
163
163
|
model_config = ConfigDict(arbitrary_types_allowed=True, ignored_types=(Flow, Task))
|
|
164
164
|
|
|
165
|
+
def get_client(self) -> InfrahubClient:
|
|
166
|
+
if self.client is None:
|
|
167
|
+
raise ValueError("Client is not set")
|
|
168
|
+
return self.client
|
|
169
|
+
|
|
165
170
|
@property
|
|
166
171
|
def sdk(self) -> InfrahubClient:
|
|
167
172
|
if self.client:
|
|
@@ -445,9 +450,6 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
445
450
|
|
|
446
451
|
return [Worktree.init(response) for response in responses]
|
|
447
452
|
|
|
448
|
-
def get_client(self) -> InfrahubClient:
|
|
449
|
-
return self.sdk
|
|
450
|
-
|
|
451
453
|
def get_location(self) -> str:
|
|
452
454
|
if self.location:
|
|
453
455
|
return self.location
|
infrahub/git/integrator.py
CHANGED
|
@@ -29,10 +29,12 @@ from infrahub_sdk.schema.repository import (
|
|
|
29
29
|
InfrahubPythonTransformConfig,
|
|
30
30
|
InfrahubRepositoryConfig,
|
|
31
31
|
)
|
|
32
|
+
from infrahub_sdk.spec.menu import MenuFile
|
|
33
|
+
from infrahub_sdk.spec.object import ObjectFile
|
|
32
34
|
from infrahub_sdk.template import Jinja2Template
|
|
33
35
|
from infrahub_sdk.template.exceptions import JinjaTemplateError
|
|
34
36
|
from infrahub_sdk.utils import compare_lists
|
|
35
|
-
from infrahub_sdk.yaml import SchemaFile
|
|
37
|
+
from infrahub_sdk.yaml import InfrahubFile, SchemaFile
|
|
36
38
|
from prefect import flow, task
|
|
37
39
|
from prefect.cache_policies import NONE
|
|
38
40
|
from prefect.logging import get_run_logger
|
|
@@ -40,7 +42,7 @@ from pydantic import BaseModel, Field
|
|
|
40
42
|
from pydantic import ValidationError as PydanticValidationError
|
|
41
43
|
from typing_extensions import Self
|
|
42
44
|
|
|
43
|
-
from infrahub.core.constants import ArtifactStatus, ContentType, InfrahubKind, RepositorySyncStatus
|
|
45
|
+
from infrahub.core.constants import ArtifactStatus, ContentType, InfrahubKind, RepositoryObjects, RepositorySyncStatus
|
|
44
46
|
from infrahub.core.registry import registry
|
|
45
47
|
from infrahub.events.artifact_action import ArtifactCreatedEvent, ArtifactUpdatedEvent
|
|
46
48
|
from infrahub.events.models import EventMeta
|
|
@@ -54,6 +56,7 @@ if TYPE_CHECKING:
|
|
|
54
56
|
import types
|
|
55
57
|
|
|
56
58
|
from infrahub_sdk.checks import InfrahubCheck
|
|
59
|
+
from infrahub_sdk.ctl.utils import YamlFileVar
|
|
57
60
|
from infrahub_sdk.schema.repository import InfrahubRepositoryArtifactDefinitionConfig
|
|
58
61
|
from infrahub_sdk.transforms import InfrahubTransform
|
|
59
62
|
|
|
@@ -159,7 +162,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
159
162
|
async def ensure_location_is_defined(self) -> None:
|
|
160
163
|
if self.location:
|
|
161
164
|
return
|
|
162
|
-
client = self.
|
|
165
|
+
client = self.sdk
|
|
163
166
|
repo = await client.get(
|
|
164
167
|
kind=CoreGenericRepository, name__value=self.name, exclude=["tags", "credential"], raise_when_missing=True
|
|
165
168
|
)
|
|
@@ -179,16 +182,20 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
179
182
|
|
|
180
183
|
config_file = await self.get_repository_config(branch_name=infrahub_branch_name, commit=commit) # type: ignore[misc]
|
|
181
184
|
sync_status = RepositorySyncStatus.IN_SYNC if config_file else RepositorySyncStatus.ERROR_IMPORT
|
|
185
|
+
|
|
182
186
|
error: Exception | None = None
|
|
183
187
|
|
|
184
188
|
try:
|
|
185
189
|
if config_file:
|
|
186
190
|
await self.import_schema_files(branch_name=infrahub_branch_name, commit=commit, config_file=config_file) # type: ignore[misc]
|
|
187
|
-
|
|
188
191
|
await self.import_all_graphql_query(
|
|
189
192
|
branch_name=infrahub_branch_name, commit=commit, config_file=config_file
|
|
190
193
|
) # type: ignore[misc]
|
|
191
|
-
|
|
194
|
+
await self.import_objects(
|
|
195
|
+
branch_name=infrahub_branch_name,
|
|
196
|
+
commit=commit,
|
|
197
|
+
config_file=config_file,
|
|
198
|
+
) # type: ignore[misc]
|
|
192
199
|
await self.import_all_python_files( # type: ignore[call-overload]
|
|
193
200
|
branch_name=infrahub_branch_name, commit=commit, config_file=config_file
|
|
194
201
|
) # type: ignore[misc]
|
|
@@ -815,6 +822,80 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
815
822
|
log.info(f"TransformPython {transform_name!r} not found locally, deleting")
|
|
816
823
|
await transform_definition_in_graph[transform_name].delete()
|
|
817
824
|
|
|
825
|
+
async def _load_yamlfile_from_disk(self, paths: list[Path], file_type: type[YamlFileVar]) -> list[YamlFileVar]:
|
|
826
|
+
data_files = file_type.load_from_disk(paths=paths)
|
|
827
|
+
|
|
828
|
+
for data_file in data_files:
|
|
829
|
+
if not data_file.valid or not data_file.content:
|
|
830
|
+
raise ValueError(f"{data_file.error_message} ({data_file.location})")
|
|
831
|
+
|
|
832
|
+
return data_files
|
|
833
|
+
|
|
834
|
+
async def _load_objects(
|
|
835
|
+
self,
|
|
836
|
+
paths: list[Path],
|
|
837
|
+
branch: str,
|
|
838
|
+
file_type: type[InfrahubFile],
|
|
839
|
+
) -> None:
|
|
840
|
+
"""Load one or multiple objects files into Infrahub."""
|
|
841
|
+
|
|
842
|
+
log = get_run_logger()
|
|
843
|
+
files = await self._load_yamlfile_from_disk(paths=paths, file_type=file_type)
|
|
844
|
+
|
|
845
|
+
for file in files:
|
|
846
|
+
await file.validate_format(client=self.sdk, branch=branch)
|
|
847
|
+
schema = await self.sdk.schema.get(kind=file.spec.kind, branch=branch)
|
|
848
|
+
if not schema.human_friendly_id and not schema.default_filter:
|
|
849
|
+
raise ValueError(
|
|
850
|
+
f"Schemas of objects or menus defined within {file.location} "
|
|
851
|
+
"should have a `human_friendly_id` defined to avoid creating duplicated objects."
|
|
852
|
+
)
|
|
853
|
+
|
|
854
|
+
for file in files:
|
|
855
|
+
log.info(f"Loading objects defined in {file.location}")
|
|
856
|
+
await file.process(client=self.sdk, branch=branch)
|
|
857
|
+
|
|
858
|
+
async def _import_file_paths(
|
|
859
|
+
self, branch_name: str, commit: str, files_pathes: list[Path], object_type: RepositoryObjects
|
|
860
|
+
) -> None:
|
|
861
|
+
branch_wt = self.get_worktree(identifier=commit or branch_name)
|
|
862
|
+
file_pathes = [branch_wt.directory / file_path for file_path in files_pathes]
|
|
863
|
+
|
|
864
|
+
# We currently assume there can't be concurrent imports, but if so, we might need to clone the client before tracking here.
|
|
865
|
+
async with self.sdk.start_tracking(
|
|
866
|
+
identifier=f"group-repo-{object_type.value}-{self.id}",
|
|
867
|
+
delete_unused_nodes=True,
|
|
868
|
+
branch=branch_name,
|
|
869
|
+
group_type="CoreRepositoryGroup",
|
|
870
|
+
group_params={"content": object_type.value, "repository": str(self.id)},
|
|
871
|
+
):
|
|
872
|
+
file_type = repo_object_type_to_file_type(object_type)
|
|
873
|
+
await self._load_objects(
|
|
874
|
+
paths=file_pathes,
|
|
875
|
+
branch=branch_name,
|
|
876
|
+
file_type=file_type,
|
|
877
|
+
)
|
|
878
|
+
|
|
879
|
+
@task(name="import-objects", task_run_name="Import Objects", cache_policy=NONE) # type: ignore[arg-type]
|
|
880
|
+
async def import_objects(
|
|
881
|
+
self,
|
|
882
|
+
branch_name: str,
|
|
883
|
+
commit: str,
|
|
884
|
+
config_file: InfrahubRepositoryConfig,
|
|
885
|
+
) -> None:
|
|
886
|
+
await self._import_file_paths(
|
|
887
|
+
branch_name=branch_name,
|
|
888
|
+
commit=commit,
|
|
889
|
+
files_pathes=config_file.objects,
|
|
890
|
+
object_type=RepositoryObjects.OBJECT,
|
|
891
|
+
)
|
|
892
|
+
await self._import_file_paths(
|
|
893
|
+
branch_name=branch_name,
|
|
894
|
+
commit=commit,
|
|
895
|
+
files_pathes=config_file.menus,
|
|
896
|
+
object_type=RepositoryObjects.MENU,
|
|
897
|
+
)
|
|
898
|
+
|
|
818
899
|
@task(name="check-definition-get", task_run_name="Get Check Definition", cache_policy=NONE) # type: ignore[arg-type]
|
|
819
900
|
async def get_check_definition(
|
|
820
901
|
self,
|
|
@@ -1342,3 +1423,13 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1342
1423
|
|
|
1343
1424
|
await self.service.event.send(event=event)
|
|
1344
1425
|
return ArtifactGenerateResult(changed=True, checksum=checksum, storage_id=storage_id, artifact_id=artifact.id)
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
def repo_object_type_to_file_type(repo_object: RepositoryObjects) -> type[InfrahubFile]:
|
|
1429
|
+
match repo_object:
|
|
1430
|
+
case RepositoryObjects.OBJECT:
|
|
1431
|
+
return ObjectFile
|
|
1432
|
+
case RepositoryObjects.MENU:
|
|
1433
|
+
return MenuFile
|
|
1434
|
+
case _:
|
|
1435
|
+
raise ValueError(f"Unknown repository object type: {repo_object}")
|
infrahub/git/tasks.py
CHANGED
|
@@ -696,6 +696,7 @@ async def trigger_internal_checks(
|
|
|
696
696
|
if (
|
|
697
697
|
existing_validator.typename == InfrahubKind.REPOSITORYVALIDATOR
|
|
698
698
|
and existing_validator.repository.id == model.repository
|
|
699
|
+
and existing_validator.label.value == validator_name
|
|
699
700
|
):
|
|
700
701
|
previous_validator = existing_validator
|
|
701
702
|
|