infrahub-server 1.6.0__py3-none-any.whl → 1.6.0b0__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/config.py +1 -1
- infrahub/core/constants/__init__.py +0 -1
- infrahub/core/manager.py +31 -36
- infrahub/core/models.py +6 -5
- infrahub/core/node/__init__.py +5 -11
- infrahub/core/node/create.py +8 -36
- infrahub/core/node/standard.py +1 -1
- infrahub/core/protocols.py +7 -1
- infrahub/core/query/attribute.py +1 -1
- infrahub/core/query/node.py +5 -9
- infrahub/core/relationship/model.py +1 -12
- infrahub/core/schema/generic_schema.py +1 -1
- infrahub/core/schema/schema_branch.py +16 -35
- infrahub/core/validators/determiner.py +6 -3
- infrahub/database/__init__.py +1 -1
- infrahub/git/base.py +3 -2
- infrahub/graphql/loaders/peers.py +0 -6
- infrahub/graphql/mutations/profile.py +1 -8
- infrahub/graphql/queries/resource_manager.py +3 -2
- infrahub/graphql/queries/search.py +3 -2
- infrahub/graphql/resolvers/ipam.py +0 -20
- infrahub/graphql/resolvers/many_relationship.py +11 -12
- infrahub/graphql/resolvers/resolver.py +2 -6
- infrahub/graphql/resolvers/single_relationship.py +11 -1
- infrahub/log.py +1 -1
- infrahub/message_bus/messages/__init__.py +12 -0
- infrahub/profiles/node_applier.py +0 -9
- infrahub/proposed_change/tasks.py +1 -1
- infrahub/task_manager/task.py +2 -2
- infrahub/trigger/setup.py +9 -6
- infrahub/utils.py +0 -18
- infrahub/workers/infrahub_async.py +6 -7
- infrahub_sdk/client.py +1 -113
- infrahub_sdk/ctl/branch.py +1 -175
- infrahub_sdk/ctl/check.py +3 -3
- infrahub_sdk/ctl/cli_commands.py +9 -9
- infrahub_sdk/ctl/generator.py +2 -2
- infrahub_sdk/ctl/graphql.py +2 -1
- infrahub_sdk/ctl/importer.py +2 -1
- infrahub_sdk/ctl/repository.py +6 -5
- infrahub_sdk/ctl/task.py +4 -2
- infrahub_sdk/ctl/utils.py +2 -2
- infrahub_sdk/ctl/validate.py +2 -1
- infrahub_sdk/diff.py +3 -80
- infrahub_sdk/graphql/constants.py +1 -14
- infrahub_sdk/graphql/renderers.py +1 -5
- infrahub_sdk/node/attribute.py +1 -0
- infrahub_sdk/node/constants.py +1 -1
- infrahub_sdk/node/related_node.py +2 -1
- infrahub_sdk/node/relationship.py +2 -1
- infrahub_sdk/protocols_base.py +1 -0
- infrahub_sdk/schema/__init__.py +3 -0
- {infrahub_server-1.6.0.dist-info → infrahub_server-1.6.0b0.dist-info}/METADATA +1 -1
- {infrahub_server-1.6.0.dist-info → infrahub_server-1.6.0b0.dist-info}/RECORD +58 -58
- {infrahub_server-1.6.0.dist-info → infrahub_server-1.6.0b0.dist-info}/WHEEL +1 -1
- infrahub_testcontainers/container.py +2 -2
- {infrahub_server-1.6.0.dist-info → infrahub_server-1.6.0b0.dist-info}/entry_points.txt +0 -0
- {infrahub_server-1.6.0.dist-info → infrahub_server-1.6.0b0.dist-info}/licenses/LICENSE.txt +0 -0
infrahub/config.py
CHANGED
|
@@ -327,7 +327,7 @@ class DevelopmentSettings(BaseSettings):
|
|
|
327
327
|
description="Allow enterprise configuration in development mode, this will not enable the features just allow the configuration.",
|
|
328
328
|
)
|
|
329
329
|
git_credential_helper: str = Field(
|
|
330
|
-
default="infrahub-git-credential",
|
|
330
|
+
default="/usr/local/bin/infrahub-git-credential",
|
|
331
331
|
description="Location of git credential helper",
|
|
332
332
|
)
|
|
333
333
|
|
|
@@ -391,4 +391,3 @@ DEFAULT_REL_IDENTIFIER_LENGTH = 128
|
|
|
391
391
|
OBJECT_TEMPLATE_RELATIONSHIP_NAME = "object_template"
|
|
392
392
|
OBJECT_TEMPLATE_NAME_ATTR = "template_name"
|
|
393
393
|
PROFILE_NODE_RELATIONSHIP_IDENTIFIER = "node__profile"
|
|
394
|
-
PROFILE_TEMPLATE_RELATIONSHIP_IDENTIFIER = "template__profile"
|
infrahub/core/manager.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, Iterable, Literal, TypeVar, overload
|
|
|
5
5
|
|
|
6
6
|
from infrahub_sdk.utils import deep_merge_dict, is_valid_uuid
|
|
7
7
|
|
|
8
|
-
from infrahub.core.constants import
|
|
8
|
+
from infrahub.core.constants import RelationshipCardinality, RelationshipDirection
|
|
9
9
|
from infrahub.core.node import Node
|
|
10
10
|
from infrahub.core.node.delete_validator import NodeDeleteValidator
|
|
11
11
|
from infrahub.core.query.node import (
|
|
@@ -188,22 +188,17 @@ class NodeManager:
|
|
|
188
188
|
await query.execute(db=db)
|
|
189
189
|
node_ids = query.get_node_ids()
|
|
190
190
|
|
|
191
|
-
if
|
|
192
|
-
|
|
193
|
-
and "identifier" in fields
|
|
194
|
-
and node_schema.kind
|
|
195
|
-
in [
|
|
196
|
-
InfrahubKind.BASEPERMISSION,
|
|
197
|
-
InfrahubKind.GLOBALPERMISSION,
|
|
198
|
-
InfrahubKind.OBJECTPERMISSION,
|
|
199
|
-
]
|
|
200
|
-
):
|
|
201
|
-
# This is a workaround to ensure we are querying the right fields for permissions
|
|
202
|
-
# The identifier for permissions needs the same fields as the display label
|
|
191
|
+
# if display_label or hfid has been requested we need to ensure we are querying the right fields
|
|
192
|
+
if fields and "display_label" in fields:
|
|
203
193
|
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
204
194
|
display_label_fields = schema_branch.generate_fields_for_display_label(name=node_schema.kind)
|
|
205
195
|
if display_label_fields:
|
|
206
|
-
deep_merge_dict(dicta=fields, dictb=display_label_fields)
|
|
196
|
+
fields = deep_merge_dict(dicta=fields, dictb=display_label_fields)
|
|
197
|
+
|
|
198
|
+
if fields and "hfid" in fields and node_schema.human_friendly_id:
|
|
199
|
+
hfid_fields = node_schema.generate_fields_for_hfid()
|
|
200
|
+
if hfid_fields:
|
|
201
|
+
fields = deep_merge_dict(dicta=fields, dictb=hfid_fields)
|
|
207
202
|
|
|
208
203
|
response = await cls.get_many(
|
|
209
204
|
ids=node_ids,
|
|
@@ -305,8 +300,6 @@ class NodeManager:
|
|
|
305
300
|
branch: Branch | str | None = None,
|
|
306
301
|
branch_agnostic: bool = False,
|
|
307
302
|
fetch_peers: bool = False,
|
|
308
|
-
include_source: bool = False,
|
|
309
|
-
include_owner: bool = False,
|
|
310
303
|
) -> list[Relationship]:
|
|
311
304
|
branch = await registry.get_branch(branch=branch, db=db)
|
|
312
305
|
at = Timestamp(at)
|
|
@@ -331,31 +324,24 @@ class NodeManager:
|
|
|
331
324
|
if not peers_info:
|
|
332
325
|
return []
|
|
333
326
|
|
|
334
|
-
if
|
|
335
|
-
|
|
336
|
-
|
|
327
|
+
# if display_label has been requested we need to ensure we are querying the right fields
|
|
328
|
+
if fields and "display_label" in fields:
|
|
329
|
+
peer_schema = schema.get_peer_schema(db=db, branch=branch)
|
|
330
|
+
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
331
|
+
display_label_fields = schema_branch.generate_fields_for_display_label(name=peer_schema.kind)
|
|
332
|
+
if display_label_fields:
|
|
333
|
+
fields = deep_merge_dict(dicta=fields, dictb=display_label_fields)
|
|
334
|
+
|
|
335
|
+
if fields and "hfid" in fields:
|
|
337
336
|
peer_schema = schema.get_peer_schema(db=db, branch=branch)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
InfrahubKind.OBJECTPERMISSION,
|
|
342
|
-
]:
|
|
343
|
-
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
344
|
-
display_label_fields = schema_branch.generate_fields_for_display_label(name=peer_schema.kind)
|
|
345
|
-
if display_label_fields:
|
|
346
|
-
deep_merge_dict(dicta=fields, dictb=display_label_fields)
|
|
337
|
+
hfid_fields = peer_schema.generate_fields_for_hfid()
|
|
338
|
+
if hfid_fields:
|
|
339
|
+
fields = deep_merge_dict(dicta=fields, dictb=hfid_fields)
|
|
347
340
|
|
|
348
341
|
if fetch_peers:
|
|
349
342
|
peer_ids = [peer.peer_id for peer in peers_info]
|
|
350
343
|
peer_nodes = await cls.get_many(
|
|
351
|
-
db=db,
|
|
352
|
-
ids=peer_ids,
|
|
353
|
-
fields=fields,
|
|
354
|
-
at=at,
|
|
355
|
-
branch=branch,
|
|
356
|
-
branch_agnostic=branch_agnostic,
|
|
357
|
-
include_source=include_source,
|
|
358
|
-
include_owner=include_owner,
|
|
344
|
+
db=db, ids=peer_ids, fields=fields, at=at, branch=branch, branch_agnostic=branch_agnostic
|
|
359
345
|
)
|
|
360
346
|
|
|
361
347
|
results = []
|
|
@@ -434,6 +420,15 @@ class NodeManager:
|
|
|
434
420
|
if not peers_ids:
|
|
435
421
|
return {}
|
|
436
422
|
|
|
423
|
+
hierarchy_schema = node_schema.get_hierarchy_schema(db=db, branch=branch)
|
|
424
|
+
|
|
425
|
+
# if display_label has been requested we need to ensure we are querying the right fields
|
|
426
|
+
if fields and "display_label" in fields:
|
|
427
|
+
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
428
|
+
display_label_fields = schema_branch.generate_fields_for_display_label(name=hierarchy_schema.kind)
|
|
429
|
+
if display_label_fields:
|
|
430
|
+
fields = deep_merge_dict(dicta=fields, dictb=display_label_fields)
|
|
431
|
+
|
|
437
432
|
return await cls.get_many(
|
|
438
433
|
db=db, ids=peers_ids, fields=fields, at=at, branch=branch, include_owner=True, include_source=True
|
|
439
434
|
)
|
infrahub/core/models.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import contextlib
|
|
4
3
|
import hashlib
|
|
5
4
|
from typing import TYPE_CHECKING, Any
|
|
6
5
|
|
|
@@ -360,7 +359,7 @@ class SchemaUpdateValidationResult(BaseModel):
|
|
|
360
359
|
|
|
361
360
|
def validate_migrations(self, migration_map: dict[str, Any]) -> None:
|
|
362
361
|
for migration in self.migrations:
|
|
363
|
-
if migration_map.get(migration.migration_name) is None:
|
|
362
|
+
if migration_map.get(migration.migration_name, None) is None:
|
|
364
363
|
self.errors.append(
|
|
365
364
|
SchemaUpdateValidationError(
|
|
366
365
|
path=migration.path,
|
|
@@ -371,7 +370,7 @@ class SchemaUpdateValidationResult(BaseModel):
|
|
|
371
370
|
|
|
372
371
|
def validate_constraints(self, validator_map: dict[str, Any]) -> None:
|
|
373
372
|
for constraint in self.constraints:
|
|
374
|
-
if validator_map.get(constraint.constraint_name) is None:
|
|
373
|
+
if validator_map.get(constraint.constraint_name, None) is None:
|
|
375
374
|
self.errors.append(
|
|
376
375
|
SchemaUpdateValidationError(
|
|
377
376
|
path=constraint.path,
|
|
@@ -579,9 +578,11 @@ class HashableModel(BaseModel):
|
|
|
579
578
|
|
|
580
579
|
for field_name in other.model_fields.keys():
|
|
581
580
|
if not hasattr(self, field_name):
|
|
582
|
-
|
|
583
|
-
# handles the case where self and other are different types and other has fields that self does not
|
|
581
|
+
try:
|
|
584
582
|
setattr(self, field_name, getattr(other, field_name))
|
|
583
|
+
except ValueError:
|
|
584
|
+
# handles the case where self and other are different types and other has fields that self does not
|
|
585
|
+
pass
|
|
585
586
|
continue
|
|
586
587
|
|
|
587
588
|
attr_other = getattr(other, field_name)
|
infrahub/core/node/__init__.py
CHANGED
|
@@ -467,21 +467,15 @@ class Node(BaseNode, metaclass=BaseNodeMeta):
|
|
|
467
467
|
for attribute_name in template._attributes:
|
|
468
468
|
if attribute_name in list(fields) + [OBJECT_TEMPLATE_NAME_ATTR]:
|
|
469
469
|
continue
|
|
470
|
-
|
|
471
|
-
attr_value = attr.value
|
|
470
|
+
attr_value = getattr(template, attribute_name).value
|
|
472
471
|
if attr_value is not None:
|
|
473
|
-
|
|
474
|
-
field_data = {"value": attr_value, "source": attr.source_id or template.id}
|
|
475
|
-
if attr.is_from_profile:
|
|
476
|
-
field_data["is_from_profile"] = True
|
|
477
|
-
fields[attribute_name] = field_data
|
|
472
|
+
fields[attribute_name] = {"value": attr_value, "source": template.id}
|
|
478
473
|
|
|
479
474
|
for relationship_name in template._relationships:
|
|
480
475
|
relationship_schema = template._schema.get_relationship(name=relationship_name)
|
|
481
476
|
if (
|
|
482
477
|
relationship_name in list(fields)
|
|
483
|
-
or relationship_schema.kind
|
|
484
|
-
not in [RelationshipKind.ATTRIBUTE, RelationshipKind.GENERIC, RelationshipKind.PROFILE]
|
|
478
|
+
or relationship_schema.kind not in [RelationshipKind.ATTRIBUTE, RelationshipKind.GENERIC]
|
|
485
479
|
or relationship_name == OBJECT_TEMPLATE_RELATIONSHIP_NAME
|
|
486
480
|
):
|
|
487
481
|
continue
|
|
@@ -576,7 +570,7 @@ class Node(BaseNode, metaclass=BaseNodeMeta):
|
|
|
576
570
|
self,
|
|
577
571
|
rel_schema.name,
|
|
578
572
|
await generator_method(
|
|
579
|
-
db=db, name=rel_schema.name, schema=rel_schema, data=fields.get(rel_schema.name)
|
|
573
|
+
db=db, name=rel_schema.name, schema=rel_schema, data=fields.get(rel_schema.name, None)
|
|
580
574
|
),
|
|
581
575
|
)
|
|
582
576
|
except ValidationError as exc:
|
|
@@ -606,7 +600,7 @@ class Node(BaseNode, metaclass=BaseNodeMeta):
|
|
|
606
600
|
self,
|
|
607
601
|
attr_schema.name,
|
|
608
602
|
await generator_method(
|
|
609
|
-
db=db, name=attr_schema.name, schema=attr_schema, data=fields.get(attr_schema.name)
|
|
603
|
+
db=db, name=attr_schema.name, schema=attr_schema, data=fields.get(attr_schema.name, None)
|
|
610
604
|
),
|
|
611
605
|
)
|
|
612
606
|
if not self._existing:
|
infrahub/core/node/create.py
CHANGED
|
@@ -58,34 +58,18 @@ async def extract_peer_data(
|
|
|
58
58
|
except ValueError:
|
|
59
59
|
pass
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
# Otherwise, use the template itself as the source
|
|
63
|
-
source_id = template_attr.source_id or template_peer.id
|
|
64
|
-
attr_data = {"value": template_attr.value, "source": source_id}
|
|
65
|
-
if template_attr.is_from_profile:
|
|
66
|
-
attr_data["is_from_profile"] = True
|
|
67
|
-
obj_peer_data[attr_name] = attr_data
|
|
61
|
+
obj_peer_data[attr_name] = {"value": template_attr.value, "source": template_peer.id}
|
|
68
62
|
|
|
69
63
|
for rel in template_peer.get_schema().relationship_names:
|
|
70
64
|
rel_manager: RelationshipManager = getattr(template_peer, rel)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
not in [
|
|
74
|
-
RelationshipKind.COMPONENT,
|
|
75
|
-
RelationshipKind.PARENT,
|
|
76
|
-
RelationshipKind.PROFILE,
|
|
77
|
-
RelationshipKind.ATTRIBUTE,
|
|
78
|
-
]
|
|
79
|
-
or rel_manager.schema.name not in obj_peer_schema.relationship_names
|
|
80
|
-
):
|
|
65
|
+
|
|
66
|
+
if rel_manager.schema.name not in obj_peer_schema.relationship_names:
|
|
81
67
|
continue
|
|
82
68
|
|
|
83
69
|
peers_map = await rel_manager.get_peers(db=db)
|
|
84
|
-
if rel_manager.schema.kind in [
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
RelationshipKind.PROFILE,
|
|
88
|
-
] and list(peers_map.keys()) == [current_template.id]:
|
|
70
|
+
if rel_manager.schema.kind in [RelationshipKind.COMPONENT, RelationshipKind.PARENT] and list(
|
|
71
|
+
peers_map.keys()
|
|
72
|
+
) == [current_template.id]:
|
|
89
73
|
obj_peer_data[rel] = {"id": parent_obj.id}
|
|
90
74
|
continue
|
|
91
75
|
|
|
@@ -96,13 +80,7 @@ async def extract_peer_data(
|
|
|
96
80
|
continue
|
|
97
81
|
rel_peer_ids.append({"id": peer_id})
|
|
98
82
|
|
|
99
|
-
|
|
100
|
-
if rel_peer_ids:
|
|
101
|
-
obj_peer_data[rel] = rel_peer_ids
|
|
102
|
-
|
|
103
|
-
if rel_manager.schema.kind == RelationshipKind.PROFILE:
|
|
104
|
-
profiles = list(await rel_manager.get_peers(db=db))
|
|
105
|
-
obj_peer_data[rel] = profiles
|
|
83
|
+
obj_peer_data[rel] = rel_peer_ids
|
|
106
84
|
|
|
107
85
|
return obj_peer_data
|
|
108
86
|
|
|
@@ -147,12 +125,6 @@ async def handle_template_relationships(
|
|
|
147
125
|
await constraint_runner.check(node=obj_peer, field_filters=list(obj_peer_data))
|
|
148
126
|
await obj_peer.save(db=db)
|
|
149
127
|
|
|
150
|
-
template_profile_ids = await get_profile_ids(db=db, obj=template_relationship_peer)
|
|
151
|
-
if template_profile_ids:
|
|
152
|
-
node_profiles_applier = NodeProfilesApplier(db=db, branch=branch)
|
|
153
|
-
await node_profiles_applier.apply_profiles(node=obj_peer)
|
|
154
|
-
await obj_peer.save(db=db)
|
|
155
|
-
|
|
156
128
|
await handle_template_relationships(
|
|
157
129
|
db=db,
|
|
158
130
|
branch=branch,
|
|
@@ -164,7 +136,7 @@ async def handle_template_relationships(
|
|
|
164
136
|
)
|
|
165
137
|
|
|
166
138
|
|
|
167
|
-
async def get_profile_ids(db: InfrahubDatabase, obj: Node
|
|
139
|
+
async def get_profile_ids(db: InfrahubDatabase, obj: Node) -> set[str]:
|
|
168
140
|
if not hasattr(obj, "profiles"):
|
|
169
141
|
return set()
|
|
170
142
|
profile_rels = await obj.profiles.get_relationships(db=db)
|
infrahub/core/node/standard.py
CHANGED
infrahub/core/protocols.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional, Protocol, runtime_checkable
|
|
6
6
|
|
|
7
7
|
from infrahub.core.protocols_base import CoreNode
|
|
8
8
|
|
|
@@ -16,16 +16,22 @@ if TYPE_CHECKING:
|
|
|
16
16
|
DateTime,
|
|
17
17
|
DateTimeOptional,
|
|
18
18
|
Dropdown,
|
|
19
|
+
DropdownOptional,
|
|
19
20
|
HashedPassword,
|
|
21
|
+
HashedPasswordOptional,
|
|
20
22
|
Integer,
|
|
21
23
|
IntegerOptional,
|
|
22
24
|
IPHost,
|
|
25
|
+
IPHostOptional,
|
|
23
26
|
IPNetwork,
|
|
27
|
+
IPNetworkOptional,
|
|
24
28
|
JSONAttribute,
|
|
25
29
|
JSONAttributeOptional,
|
|
30
|
+
ListAttribute,
|
|
26
31
|
ListAttributeOptional,
|
|
27
32
|
String,
|
|
28
33
|
StringOptional,
|
|
34
|
+
URLOptional,
|
|
29
35
|
)
|
|
30
36
|
from infrahub.core.relationship import RelationshipManager
|
|
31
37
|
|
infrahub/core/query/attribute.py
CHANGED
|
@@ -373,7 +373,7 @@ async def default_attribute_query_filter(
|
|
|
373
373
|
if property_name not in [v.value for v in NodeProperty]:
|
|
374
374
|
raise ValueError(f"filter {filter_name}: {filter_value}, {property_name} is not a valid property")
|
|
375
375
|
|
|
376
|
-
if property_attr
|
|
376
|
+
if property_attr not in ["id"]:
|
|
377
377
|
raise ValueError(f"filter {filter_name}: {filter_value}, {property_attr} is supported")
|
|
378
378
|
|
|
379
379
|
clean_filter_name = f"{property_name}_{property_attr}"
|
infrahub/core/query/node.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import contextlib
|
|
4
3
|
from collections import defaultdict
|
|
5
4
|
from copy import copy
|
|
6
5
|
from dataclasses import dataclass
|
|
@@ -13,7 +12,6 @@ from infrahub.core import registry
|
|
|
13
12
|
from infrahub.core.constants import (
|
|
14
13
|
GLOBAL_BRANCH_NAME,
|
|
15
14
|
PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
|
|
16
|
-
PROFILE_TEMPLATE_RELATIONSHIP_IDENTIFIER,
|
|
17
15
|
AttributeDBNodeType,
|
|
18
16
|
RelationshipDirection,
|
|
19
17
|
RelationshipHierarchyDirection,
|
|
@@ -625,8 +623,7 @@ class NodeListGetAttributeQuery(Query):
|
|
|
625
623
|
|
|
626
624
|
async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG002
|
|
627
625
|
self.params["ids"] = self.ids
|
|
628
|
-
self.params["
|
|
629
|
-
self.params["profile_template_relationship_name"] = PROFILE_TEMPLATE_RELATIONSHIP_IDENTIFIER
|
|
626
|
+
self.params["profile_relationship_name"] = PROFILE_NODE_RELATIONSHIP_IDENTIFIER
|
|
630
627
|
|
|
631
628
|
branch_filter, branch_params = self.branch.get_query_filter_path(
|
|
632
629
|
at=self.at, branch_agnostic=self.branch_agnostic
|
|
@@ -635,10 +632,7 @@ class NodeListGetAttributeQuery(Query):
|
|
|
635
632
|
|
|
636
633
|
query = """
|
|
637
634
|
MATCH (n:Node) WHERE n.uuid IN $ids
|
|
638
|
-
WITH n, (
|
|
639
|
-
exists((n)-[:IS_RELATED]-(:Relationship {name: $profile_node_relationship_name})) OR
|
|
640
|
-
exists((n)-[:IS_RELATED]-(:Relationship {name: $profile_template_relationship_name}))
|
|
641
|
-
) AS might_use_profile
|
|
635
|
+
WITH n, exists((n)-[:IS_RELATED]-(:Relationship {name: $profile_relationship_name})) AS might_use_profile
|
|
642
636
|
MATCH (n)-[:HAS_ATTRIBUTE]-(a:Attribute)
|
|
643
637
|
"""
|
|
644
638
|
if self.fields:
|
|
@@ -1140,8 +1134,10 @@ class NodeGetListQuery(Query):
|
|
|
1140
1134
|
self._variables_to_track.append(variable)
|
|
1141
1135
|
|
|
1142
1136
|
def _untrack_variable(self, variable: str) -> None:
|
|
1143
|
-
|
|
1137
|
+
try:
|
|
1144
1138
|
self._variables_to_track.remove(variable)
|
|
1139
|
+
except ValueError:
|
|
1140
|
+
...
|
|
1145
1141
|
|
|
1146
1142
|
def _get_tracked_variables(self) -> list[str]:
|
|
1147
1143
|
return self._variables_to_track
|
|
@@ -912,8 +912,6 @@ class RelationshipManager:
|
|
|
912
912
|
db: InfrahubDatabase,
|
|
913
913
|
peer_type: type[PeerType],
|
|
914
914
|
branch_agnostic: bool = ...,
|
|
915
|
-
include_source: bool = ...,
|
|
916
|
-
include_owner: bool = ...,
|
|
917
915
|
) -> Mapping[str, PeerType]: ...
|
|
918
916
|
|
|
919
917
|
@overload
|
|
@@ -922,8 +920,6 @@ class RelationshipManager:
|
|
|
922
920
|
db: InfrahubDatabase,
|
|
923
921
|
peer_type: None = None,
|
|
924
922
|
branch_agnostic: bool = ...,
|
|
925
|
-
include_source: bool = ...,
|
|
926
|
-
include_owner: bool = ...,
|
|
927
923
|
) -> Mapping[str, Node]: ...
|
|
928
924
|
|
|
929
925
|
async def get_peers(
|
|
@@ -931,18 +927,11 @@ class RelationshipManager:
|
|
|
931
927
|
db: InfrahubDatabase,
|
|
932
928
|
peer_type: type[PeerType] | None = None, # noqa: ARG002
|
|
933
929
|
branch_agnostic: bool = False,
|
|
934
|
-
include_source: bool = False,
|
|
935
|
-
include_owner: bool = False,
|
|
936
930
|
) -> Mapping[str, Node | PeerType]:
|
|
937
931
|
rels = await self.get_relationships(db=db, branch_agnostic=branch_agnostic)
|
|
938
932
|
peer_ids = [rel.peer_id for rel in rels if rel.peer_id]
|
|
939
933
|
nodes = await registry.manager.get_many(
|
|
940
|
-
db=db,
|
|
941
|
-
ids=peer_ids,
|
|
942
|
-
branch=self.branch,
|
|
943
|
-
branch_agnostic=branch_agnostic,
|
|
944
|
-
include_source=include_source,
|
|
945
|
-
include_owner=include_owner,
|
|
934
|
+
db=db, ids=peer_ids, branch=self.branch, branch_agnostic=branch_agnostic
|
|
946
935
|
)
|
|
947
936
|
return nodes
|
|
948
937
|
|
|
@@ -51,4 +51,4 @@ class GenericSchema(GeneratedGenericSchema):
|
|
|
51
51
|
def _get_field_names_for_diff(self) -> list[str]:
|
|
52
52
|
"""Exclude used_by from the diff for generic nodes"""
|
|
53
53
|
fields = super()._get_field_names_for_diff()
|
|
54
|
-
return [field for field in fields if field
|
|
54
|
+
return [field for field in fields if field not in ["used_by"]]
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import contextlib
|
|
4
3
|
import copy
|
|
5
4
|
import hashlib
|
|
6
5
|
import keyword
|
|
@@ -20,7 +19,6 @@ from infrahub.core.constants import (
|
|
|
20
19
|
OBJECT_TEMPLATE_NAME_ATTR,
|
|
21
20
|
OBJECT_TEMPLATE_RELATIONSHIP_NAME,
|
|
22
21
|
PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
|
|
23
|
-
PROFILE_TEMPLATE_RELATIONSHIP_IDENTIFIER,
|
|
24
22
|
RESERVED_ATTR_GEN_NAMES,
|
|
25
23
|
RESERVED_ATTR_REL_NAMES,
|
|
26
24
|
RESTRICTED_NAMESPACES,
|
|
@@ -74,16 +72,6 @@ from .schema_branch_hfid import HFIDs
|
|
|
74
72
|
log = get_logger()
|
|
75
73
|
|
|
76
74
|
|
|
77
|
-
profiles_rel_settings: dict[str, Any] = {
|
|
78
|
-
"name": "profiles",
|
|
79
|
-
"identifier": PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
|
|
80
|
-
"peer": InfrahubKind.PROFILE,
|
|
81
|
-
"kind": RelationshipKind.PROFILE,
|
|
82
|
-
"cardinality": RelationshipCardinality.MANY,
|
|
83
|
-
"branch": BranchSupportType.AWARE,
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
75
|
class SchemaBranch:
|
|
88
76
|
def __init__(
|
|
89
77
|
self,
|
|
@@ -346,8 +334,10 @@ class SchemaBranch:
|
|
|
346
334
|
)
|
|
347
335
|
|
|
348
336
|
schema: MainSchemaTypes | None = None
|
|
349
|
-
|
|
337
|
+
try:
|
|
350
338
|
schema = self._cache[key]
|
|
339
|
+
except KeyError:
|
|
340
|
+
pass
|
|
351
341
|
|
|
352
342
|
if not schema:
|
|
353
343
|
raise ValueError(f"Schema {name!r} on branch {self.name} has incorrect hash: {key!r}")
|
|
@@ -1126,7 +1116,7 @@ class SchemaBranch:
|
|
|
1126
1116
|
) from None
|
|
1127
1117
|
|
|
1128
1118
|
for rel in node.relationships:
|
|
1129
|
-
if rel.peer
|
|
1119
|
+
if rel.peer in [InfrahubKind.GENERICGROUP]:
|
|
1130
1120
|
continue
|
|
1131
1121
|
if not self.has(rel.peer) or self.get(rel.peer, duplicate=False).state == HashableModelState.ABSENT:
|
|
1132
1122
|
raise ValueError(
|
|
@@ -2173,8 +2163,10 @@ class SchemaBranch:
|
|
|
2173
2163
|
or not node.generate_profile
|
|
2174
2164
|
or node.state == HashableModelState.ABSENT
|
|
2175
2165
|
):
|
|
2176
|
-
|
|
2166
|
+
try:
|
|
2177
2167
|
self.delete(name=self._get_profile_kind(node_kind=node.kind))
|
|
2168
|
+
except SchemaNotFoundError:
|
|
2169
|
+
...
|
|
2178
2170
|
continue
|
|
2179
2171
|
|
|
2180
2172
|
profile = self.generate_profile_from_node(node=node)
|
|
@@ -2220,6 +2212,15 @@ class SchemaBranch:
|
|
|
2220
2212
|
):
|
|
2221
2213
|
continue
|
|
2222
2214
|
|
|
2215
|
+
profiles_rel_settings: dict[str, Any] = {
|
|
2216
|
+
"name": "profiles",
|
|
2217
|
+
"identifier": PROFILE_NODE_RELATIONSHIP_IDENTIFIER,
|
|
2218
|
+
"peer": InfrahubKind.PROFILE,
|
|
2219
|
+
"kind": RelationshipKind.PROFILE,
|
|
2220
|
+
"cardinality": RelationshipCardinality.MANY,
|
|
2221
|
+
"branch": BranchSupportType.AWARE,
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2223
2224
|
# Add relationship between node and profile
|
|
2224
2225
|
if "profiles" not in node.relationship_names:
|
|
2225
2226
|
node_schema = self.get(name=node_name, duplicate=True)
|
|
@@ -2284,18 +2285,6 @@ class SchemaBranch:
|
|
|
2284
2285
|
)
|
|
2285
2286
|
],
|
|
2286
2287
|
)
|
|
2287
|
-
if f"Template{node.kind}" in self.all_names:
|
|
2288
|
-
template = self.get(name=f"Template{node.kind}", duplicate=False)
|
|
2289
|
-
profile.relationships.append(
|
|
2290
|
-
RelationshipSchema(
|
|
2291
|
-
name="related_templates",
|
|
2292
|
-
identifier=PROFILE_TEMPLATE_RELATIONSHIP_IDENTIFIER,
|
|
2293
|
-
peer=template.kind,
|
|
2294
|
-
kind=RelationshipKind.PROFILE,
|
|
2295
|
-
cardinality=RelationshipCardinality.MANY,
|
|
2296
|
-
branch=BranchSupportType.AWARE,
|
|
2297
|
-
)
|
|
2298
|
-
)
|
|
2299
2288
|
|
|
2300
2289
|
for node_attr in node.attributes:
|
|
2301
2290
|
if not node_attr.support_profiles:
|
|
@@ -2426,14 +2415,6 @@ class SchemaBranch:
|
|
|
2426
2415
|
template_schema.human_friendly_id = [parent_hfid] + template_schema.human_friendly_id
|
|
2427
2416
|
template_schema.uniqueness_constraints[0].append(relationship.name)
|
|
2428
2417
|
|
|
2429
|
-
if getattr(node, "generate_profile", False):
|
|
2430
|
-
if "profiles" not in [r.name for r in template_schema.relationships]:
|
|
2431
|
-
settings = dict(profiles_rel_settings)
|
|
2432
|
-
settings["identifier"] = PROFILE_TEMPLATE_RELATIONSHIP_IDENTIFIER
|
|
2433
|
-
template_schema.relationships.append(RelationshipSchema(**settings))
|
|
2434
|
-
|
|
2435
|
-
self.set(name=template_schema.kind, schema=template_schema)
|
|
2436
|
-
|
|
2437
2418
|
def generate_object_template_from_node(
|
|
2438
2419
|
self, node: NodeSchema | GenericSchema, need_templates: set[NodeSchema | GenericSchema]
|
|
2439
2420
|
) -> TemplateSchema | GenericSchema:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import contextlib
|
|
2
1
|
from typing import TYPE_CHECKING, Any
|
|
3
2
|
|
|
4
3
|
from infrahub.core.constants import RelationshipKind, SchemaPathType
|
|
@@ -85,10 +84,14 @@ class ConstraintValidatorDeterminer:
|
|
|
85
84
|
constraints: list[SchemaUpdateConstraintInfo] = []
|
|
86
85
|
schemas = list(self.schema_branch.get_all(duplicate=False).values())
|
|
87
86
|
# added here to check their uniqueness constraints
|
|
88
|
-
|
|
87
|
+
try:
|
|
89
88
|
schemas.append(self.schema_branch.get_node(name="SchemaAttribute", duplicate=False))
|
|
90
|
-
|
|
89
|
+
except SchemaNotFoundError:
|
|
90
|
+
pass
|
|
91
|
+
try:
|
|
91
92
|
schemas.append(self.schema_branch.get_node(name="SchemaRelationship", duplicate=False))
|
|
93
|
+
except SchemaNotFoundError:
|
|
94
|
+
pass
|
|
92
95
|
for schema in schemas:
|
|
93
96
|
constraints.extend(await self._get_property_constraints_for_one_schema(schema=schema))
|
|
94
97
|
return constraints
|
infrahub/database/__init__.py
CHANGED
|
@@ -356,7 +356,7 @@ class InfrahubDatabase:
|
|
|
356
356
|
type
|
|
357
357
|
and type == QueryType.READ
|
|
358
358
|
and runtime not in [Neo4jRuntime.DEFAULT, Neo4jRuntime.UNDEFINED]
|
|
359
|
-
and not (self.is_transaction and runtime
|
|
359
|
+
and not (self.is_transaction and runtime in [Neo4jRuntime.PARALLEL])
|
|
360
360
|
):
|
|
361
361
|
query = f"CYPHER runtime = {runtime.value}\n" + query
|
|
362
362
|
else:
|
infrahub/git/base.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import contextlib
|
|
4
3
|
import shutil
|
|
5
4
|
from abc import ABC, abstractmethod
|
|
6
5
|
from pathlib import Path
|
|
@@ -749,8 +748,10 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
749
748
|
for short_name, branch_data in branches.items():
|
|
750
749
|
branch = None
|
|
751
750
|
|
|
752
|
-
|
|
751
|
+
try:
|
|
753
752
|
branch = registry.get_branch_from_registry(branch=short_name)
|
|
753
|
+
except BranchNotFoundError:
|
|
754
|
+
...
|
|
754
755
|
|
|
755
756
|
branch_exists_import_sync_condition = branch and (
|
|
756
757
|
branch.name not in {registry.default_branch, self.default_branch}
|
|
@@ -22,8 +22,6 @@ class QueryPeerParams:
|
|
|
22
22
|
fields: dict | None = None
|
|
23
23
|
at: Timestamp | str | None = None
|
|
24
24
|
branch_agnostic: bool = False
|
|
25
|
-
include_source: bool = False
|
|
26
|
-
include_owner: bool = False
|
|
27
25
|
|
|
28
26
|
def __hash__(self) -> int:
|
|
29
27
|
frozen_fields: frozenset | None = None
|
|
@@ -41,8 +39,6 @@ class QueryPeerParams:
|
|
|
41
39
|
self.schema.name,
|
|
42
40
|
str(self.source_kind),
|
|
43
41
|
str(self.branch_agnostic),
|
|
44
|
-
str(self.include_source),
|
|
45
|
-
str(self.include_owner),
|
|
46
42
|
]
|
|
47
43
|
)
|
|
48
44
|
return hash(hash_str)
|
|
@@ -67,8 +63,6 @@ class PeerRelationshipsDataLoader(DataLoader[str, list[Relationship]]):
|
|
|
67
63
|
branch=self.query_params.branch,
|
|
68
64
|
branch_agnostic=self.query_params.branch_agnostic,
|
|
69
65
|
fetch_peers=True,
|
|
70
|
-
include_source=self.query_params.include_source,
|
|
71
|
-
include_owner=self.query_params.include_owner,
|
|
72
66
|
)
|
|
73
67
|
peer_rels_by_node_id: dict[str, list[Relationship]] = {}
|
|
74
68
|
for rel in peer_rels:
|
|
@@ -57,8 +57,6 @@ class InfrahubProfileMutation(InfrahubMutationMixin, Mutation):
|
|
|
57
57
|
) -> None:
|
|
58
58
|
if not node_ids:
|
|
59
59
|
related_nodes = await obj.related_nodes.get_relationships(db=db) # type: ignore[attr-defined]
|
|
60
|
-
if hasattr(obj, "related_templates"):
|
|
61
|
-
related_nodes.extend(await obj.related_templates.get_relationships(db=db)) # type: ignore[attr-defined]
|
|
62
60
|
node_ids = [rel.peer_id for rel in related_nodes]
|
|
63
61
|
if node_ids:
|
|
64
62
|
await workflow_service.submit_workflow(
|
|
@@ -81,12 +79,7 @@ class InfrahubProfileMutation(InfrahubMutationMixin, Mutation):
|
|
|
81
79
|
|
|
82
80
|
@classmethod
|
|
83
81
|
async def _get_profile_related_node_ids(cls, db: InfrahubDatabase, obj: Node) -> set[str]:
|
|
84
|
-
related_nodes = []
|
|
85
|
-
related_nodes.extend(await obj.related_nodes.get_relationships(db=db)) # type: ignore[attr-defined]
|
|
86
|
-
|
|
87
|
-
if hasattr(obj, "related_templates"):
|
|
88
|
-
related_nodes.extend(await obj.related_templates.get_relationships(db=db)) # type: ignore[attr-defined]
|
|
89
|
-
|
|
82
|
+
related_nodes = await obj.related_nodes.get_relationships(db=db) # type: ignore[attr-defined]
|
|
90
83
|
if related_nodes:
|
|
91
84
|
related_node_ids = {rel.peer_id for rel in related_nodes}
|
|
92
85
|
else:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import contextlib
|
|
4
3
|
from typing import TYPE_CHECKING, Any
|
|
5
4
|
|
|
6
5
|
from graphene import BigInt, Field, Float, Int, List, NonNull, ObjectType, String
|
|
@@ -197,8 +196,10 @@ class PoolUtilization(ObjectType):
|
|
|
197
196
|
|
|
198
197
|
resources_map: dict[str, Node] = {}
|
|
199
198
|
|
|
200
|
-
|
|
199
|
+
try:
|
|
201
200
|
resources_map = await pool.resources.get_peers(db=db, branch_agnostic=True) # type: ignore[attr-defined,union-attr]
|
|
201
|
+
except SchemaNotFoundError:
|
|
202
|
+
pass
|
|
202
203
|
|
|
203
204
|
utilization_getter = PrefixUtilizationGetter(
|
|
204
205
|
db=db, ip_prefixes=list(resources_map.values()), at=graphql_context.at
|