infrahub-server 1.3.0b5__py3-none-any.whl → 1.3.0b6__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 +36 -79
- infrahub/actions/schema.py +2 -0
- infrahub/core/constraint/node/runner.py +3 -1
- infrahub/core/convert_object_type/conversion.py +2 -0
- infrahub/core/diff/query/delete_query.py +8 -4
- infrahub/core/diff/repository/repository.py +4 -0
- 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/m028_delete_diffs.py +1 -2
- infrahub/core/node/__init__.py +65 -36
- infrahub/core/path.py +14 -0
- 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 +1 -1
- infrahub/core/relationship/constraints/profiles_kind.py +1 -1
- infrahub/core/schema/definitions/internal.py +8 -1
- infrahub/core/schema/generated/relationship_schema.py +6 -1
- infrahub/core/schema/schema_branch.py +36 -8
- infrahub/core/validators/__init__.py +2 -1
- infrahub/core/validators/relationship/peer.py +174 -4
- infrahub/database/__init__.py +0 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_parent.py +8 -0
- infrahub/dependencies/builder/constraint/schema/aggregated.py +2 -0
- infrahub/dependencies/builder/constraint/schema/relationship_peer.py +8 -0
- infrahub/dependencies/registry.py +2 -0
- infrahub/git/tasks.py +1 -0
- infrahub/graphql/mutations/convert_object_type.py +16 -7
- infrahub/graphql/mutations/relationship.py +32 -0
- infrahub/graphql/queries/convert_object_type_mapping.py +3 -5
- infrahub/message_bus/operations/refresh/registry.py +3 -6
- infrahub/pools/models.py +14 -0
- infrahub/pools/tasks.py +71 -1
- infrahub_sdk/ctl/generator.py +4 -4
- infrahub_sdk/ctl/repository.py +1 -1
- infrahub_sdk/node/node.py +146 -92
- infrahub_sdk/pytest_plugin/items/python_transform.py +2 -1
- infrahub_sdk/query_groups.py +4 -3
- infrahub_sdk/utils.py +7 -20
- infrahub_sdk/yaml.py +6 -5
- {infrahub_server-1.3.0b5.dist-info → infrahub_server-1.3.0b6.dist-info}/METADATA +2 -2
- {infrahub_server-1.3.0b5.dist-info → infrahub_server-1.3.0b6.dist-info}/RECORD +47 -43
- {infrahub_server-1.3.0b5.dist-info → infrahub_server-1.3.0b6.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.3.0b5.dist-info → infrahub_server-1.3.0b6.dist-info}/WHEEL +0 -0
- {infrahub_server-1.3.0b5.dist-info → infrahub_server-1.3.0b6.dist-info}/entry_points.txt +0 -0
infrahub_sdk/ctl/generator.py
CHANGED
|
@@ -74,20 +74,20 @@ async def run(
|
|
|
74
74
|
targets = await client.get(
|
|
75
75
|
kind="CoreGroup", branch=branch, include=["members"], name__value=generator_config.targets
|
|
76
76
|
)
|
|
77
|
-
await targets.members.fetch()
|
|
77
|
+
await targets._get_relationship_many(name="members").fetch()
|
|
78
78
|
|
|
79
|
-
if not targets.members.peers:
|
|
79
|
+
if not targets._get_relationship_many(name="members").peers:
|
|
80
80
|
console.print(
|
|
81
81
|
f"[red]No members found within '{generator_config.targets}', not running generator '{generator_name}'"
|
|
82
82
|
)
|
|
83
83
|
return
|
|
84
84
|
|
|
85
|
-
for member in targets.members.peers:
|
|
85
|
+
for member in targets._get_relationship_many(name="members").peers:
|
|
86
86
|
check_parameter = {}
|
|
87
87
|
if identifier:
|
|
88
88
|
attribute = getattr(member.peer, identifier)
|
|
89
89
|
check_parameter = {identifier: attribute.value}
|
|
90
|
-
params = {"name": member.peer.name.value}
|
|
90
|
+
params = {"name": member.peer._get_attribute(name="name").value}
|
|
91
91
|
generator = generator_class(
|
|
92
92
|
query=generator_config.query,
|
|
93
93
|
client=client,
|
infrahub_sdk/ctl/repository.py
CHANGED
|
@@ -45,7 +45,7 @@ def get_repository_config(repo_config_file: Path) -> InfrahubRepositoryConfig:
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def load_repository_config_file(repo_config_file: Path) -> dict:
|
|
48
|
-
yaml_data = read_file(
|
|
48
|
+
yaml_data = read_file(file_path=repo_config_file)
|
|
49
49
|
|
|
50
50
|
try:
|
|
51
51
|
data = yaml.safe_load(yaml_data)
|
infrahub_sdk/node/node.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable
|
|
3
4
|
from copy import copy
|
|
4
5
|
from typing import TYPE_CHECKING, Any
|
|
5
6
|
|
|
6
7
|
from ..constants import InfrahubClientMode
|
|
7
|
-
from ..exceptions import
|
|
8
|
-
FeatureNotSupportedError,
|
|
9
|
-
NodeNotFoundError,
|
|
10
|
-
)
|
|
8
|
+
from ..exceptions import FeatureNotSupportedError, NodeNotFoundError, ResourceNotDefinedError, SchemaNotFoundError
|
|
11
9
|
from ..graphql import Mutation, Query
|
|
12
10
|
from ..schema import GenericSchemaAPI, RelationshipCardinality, RelationshipKind
|
|
13
11
|
from ..utils import compare_lists, generate_short_id, get_flat_value
|
|
@@ -30,48 +28,6 @@ if TYPE_CHECKING:
|
|
|
30
28
|
from ..types import Order
|
|
31
29
|
|
|
32
30
|
|
|
33
|
-
def generate_relationship_property(node: InfrahubNode | InfrahubNodeSync, name: str) -> property:
|
|
34
|
-
"""Generates a property that stores values under a private non-public name.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
node (Union[InfrahubNode, InfrahubNodeSync]): The node instance.
|
|
38
|
-
name (str): The name of the relationship property.
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
A property object for managing the relationship.
|
|
42
|
-
|
|
43
|
-
"""
|
|
44
|
-
internal_name = "_" + name.lower()
|
|
45
|
-
external_name = name
|
|
46
|
-
|
|
47
|
-
def prop_getter(self: InfrahubNodeBase) -> Any:
|
|
48
|
-
return getattr(self, internal_name)
|
|
49
|
-
|
|
50
|
-
def prop_setter(self: InfrahubNodeBase, value: Any) -> None:
|
|
51
|
-
if isinstance(value, RelatedNodeBase) or value is None:
|
|
52
|
-
setattr(self, internal_name, value)
|
|
53
|
-
else:
|
|
54
|
-
schema = [rel for rel in self._schema.relationships if rel.name == external_name][0]
|
|
55
|
-
if isinstance(node, InfrahubNode):
|
|
56
|
-
setattr(
|
|
57
|
-
self,
|
|
58
|
-
internal_name,
|
|
59
|
-
RelatedNode(
|
|
60
|
-
name=external_name, branch=node._branch, client=node._client, schema=schema, data=value
|
|
61
|
-
),
|
|
62
|
-
)
|
|
63
|
-
else:
|
|
64
|
-
setattr(
|
|
65
|
-
self,
|
|
66
|
-
internal_name,
|
|
67
|
-
RelatedNodeSync(
|
|
68
|
-
name=external_name, branch=node._branch, client=node._client, schema=schema, data=value
|
|
69
|
-
),
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
return property(prop_getter, prop_setter)
|
|
73
|
-
|
|
74
|
-
|
|
75
31
|
class InfrahubNodeBase:
|
|
76
32
|
"""Base class for InfrahubNode and InfrahubNodeSync"""
|
|
77
33
|
|
|
@@ -86,6 +42,7 @@ class InfrahubNodeBase:
|
|
|
86
42
|
self._data = data
|
|
87
43
|
self._branch = branch
|
|
88
44
|
self._existing: bool = True
|
|
45
|
+
self._attribute_data: dict[str, Attribute] = {}
|
|
89
46
|
|
|
90
47
|
# Generate a unique ID only to be used inside the SDK
|
|
91
48
|
# The format if this ID is purposely different from the ID used by the API
|
|
@@ -180,12 +137,18 @@ class InfrahubNodeBase:
|
|
|
180
137
|
def _init_attributes(self, data: dict | None = None) -> None:
|
|
181
138
|
for attr_schema in self._schema.attributes:
|
|
182
139
|
attr_data = data.get(attr_schema.name, None) if isinstance(data, dict) else None
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
attr_schema.name,
|
|
186
|
-
Attribute(name=attr_schema.name, schema=attr_schema, data=attr_data),
|
|
140
|
+
self._attribute_data[attr_schema.name] = Attribute(
|
|
141
|
+
name=attr_schema.name, schema=attr_schema, data=attr_data
|
|
187
142
|
)
|
|
188
143
|
|
|
144
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
145
|
+
"""Set values for attributes that exist or revert to normal behaviour"""
|
|
146
|
+
if "_attribute_data" in self.__dict__ and name in self._attribute_data:
|
|
147
|
+
self._attribute_data[name].value = value
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
super().__setattr__(name, value)
|
|
151
|
+
|
|
189
152
|
def _get_request_context(self, request_context: RequestContext | None = None) -> dict[str, Any] | None:
|
|
190
153
|
if request_context:
|
|
191
154
|
return request_context.model_dump(exclude_none=True)
|
|
@@ -487,6 +450,12 @@ class InfrahubNodeBase:
|
|
|
487
450
|
}}
|
|
488
451
|
"""
|
|
489
452
|
|
|
453
|
+
def _get_attribute(self, name: str) -> Attribute:
|
|
454
|
+
if name in self._attribute_data:
|
|
455
|
+
return self._attribute_data[name]
|
|
456
|
+
|
|
457
|
+
raise ResourceNotDefinedError(message=f"The node doesn't have an attribute for {name}")
|
|
458
|
+
|
|
490
459
|
|
|
491
460
|
class InfrahubNode(InfrahubNodeBase):
|
|
492
461
|
"""Represents a Infrahub node in an asynchronous context."""
|
|
@@ -506,11 +475,13 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
506
475
|
data: Optional data to initialize the node.
|
|
507
476
|
"""
|
|
508
477
|
self._client = client
|
|
509
|
-
self.__class__ = type(f"{schema.kind}InfrahubNode", (self.__class__,), {})
|
|
510
478
|
|
|
511
479
|
if isinstance(data, dict) and isinstance(data.get("node"), dict):
|
|
512
480
|
data = data.get("node")
|
|
513
481
|
|
|
482
|
+
self._relationship_cardinality_many_data: dict[str, RelationshipManager] = {}
|
|
483
|
+
self._relationship_cardinality_one_data: dict[str, RelatedNode] = {}
|
|
484
|
+
|
|
514
485
|
super().__init__(schema=schema, branch=branch or client.default_branch, data=data)
|
|
515
486
|
|
|
516
487
|
@classmethod
|
|
@@ -535,26 +506,45 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
535
506
|
rel_data = data.get(rel_schema.name, None) if isinstance(data, dict) else None
|
|
536
507
|
|
|
537
508
|
if rel_schema.cardinality == "one":
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
self.__class__,
|
|
541
|
-
rel_schema.name,
|
|
542
|
-
generate_relationship_property(name=rel_schema.name, node=self),
|
|
509
|
+
self._relationship_cardinality_one_data[rel_schema.name] = RelatedNode(
|
|
510
|
+
name=rel_schema.name, branch=self._branch, client=self._client, schema=rel_schema, data=rel_data
|
|
543
511
|
)
|
|
544
|
-
setattr(self, rel_schema.name, rel_data)
|
|
545
512
|
else:
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
513
|
+
self._relationship_cardinality_many_data[rel_schema.name] = RelationshipManager(
|
|
514
|
+
name=rel_schema.name,
|
|
515
|
+
client=self._client,
|
|
516
|
+
node=self,
|
|
517
|
+
branch=self._branch,
|
|
518
|
+
schema=rel_schema,
|
|
519
|
+
data=rel_data,
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
def __getattr__(self, name: str) -> Attribute | RelationshipManager | RelatedNode:
|
|
523
|
+
if "_attribute_data" in self.__dict__ and name in self._attribute_data:
|
|
524
|
+
return self._attribute_data[name]
|
|
525
|
+
if "_relationship_cardinality_many_data" in self.__dict__ and name in self._relationship_cardinality_many_data:
|
|
526
|
+
return self._relationship_cardinality_many_data[name]
|
|
527
|
+
if "_relationship_cardinality_one_data" in self.__dict__ and name in self._relationship_cardinality_one_data:
|
|
528
|
+
return self._relationship_cardinality_one_data[name]
|
|
529
|
+
|
|
530
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
|
|
531
|
+
|
|
532
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
533
|
+
"""Set values for relationship names that exist or revert to normal behaviour"""
|
|
534
|
+
if "_relationship_cardinality_one_data" in self.__dict__ and name in self._relationship_cardinality_one_data:
|
|
535
|
+
rel_schemas = [rel_schema for rel_schema in self._schema.relationships if rel_schema.name == name]
|
|
536
|
+
if not rel_schemas:
|
|
537
|
+
raise SchemaNotFoundError(
|
|
538
|
+
identifier=self._schema.kind,
|
|
539
|
+
message=f"Unable to find relationship schema for '{name}' on {self._schema.kind}",
|
|
557
540
|
)
|
|
541
|
+
rel_schema = rel_schemas[0]
|
|
542
|
+
self._relationship_cardinality_one_data[name] = RelatedNode(
|
|
543
|
+
name=rel_schema.name, branch=self._branch, client=self._client, schema=rel_schema, data=value
|
|
544
|
+
)
|
|
545
|
+
return
|
|
546
|
+
|
|
547
|
+
super().__setattr__(name, value)
|
|
558
548
|
|
|
559
549
|
async def generate(self, nodes: list[str] | None = None) -> None:
|
|
560
550
|
self._validate_artifact_definition_support(ARTIFACT_DEFINITION_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE)
|
|
@@ -568,14 +558,14 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
568
558
|
self._validate_artifact_support(ARTIFACT_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE)
|
|
569
559
|
|
|
570
560
|
artifact = await self._client.get(kind="CoreArtifact", name__value=name, object__ids=[self.id])
|
|
571
|
-
await artifact.definition.fetch()
|
|
572
|
-
await artifact.definition.peer.generate([artifact.id])
|
|
561
|
+
await artifact._get_relationship_one(name="definition").fetch()
|
|
562
|
+
await artifact._get_relationship_one(name="definition").peer.generate([artifact.id])
|
|
573
563
|
|
|
574
564
|
async def artifact_fetch(self, name: str) -> str | dict[str, Any]:
|
|
575
565
|
self._validate_artifact_support(ARTIFACT_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE)
|
|
576
566
|
|
|
577
567
|
artifact = await self._client.get(kind="CoreArtifact", name__value=name, object__ids=[self.id])
|
|
578
|
-
content = await self._client.object_store.get(identifier=artifact.storage_id.value)
|
|
568
|
+
content = await self._client.object_store.get(identifier=artifact._get_attribute(name="storage_id").value)
|
|
579
569
|
return content
|
|
580
570
|
|
|
581
571
|
async def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None:
|
|
@@ -1018,6 +1008,27 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
1018
1008
|
return [edge["node"] for edge in response[graphql_query_name]["edges"]]
|
|
1019
1009
|
return []
|
|
1020
1010
|
|
|
1011
|
+
def _get_relationship_many(self, name: str) -> RelationshipManager:
|
|
1012
|
+
if name in self._relationship_cardinality_many_data:
|
|
1013
|
+
return self._relationship_cardinality_many_data[name]
|
|
1014
|
+
|
|
1015
|
+
raise ResourceNotDefinedError(message=f"The node doesn't have a cardinality=many relationship for {name}")
|
|
1016
|
+
|
|
1017
|
+
def _get_relationship_one(self, name: str) -> RelatedNode:
|
|
1018
|
+
if name in self._relationship_cardinality_one_data:
|
|
1019
|
+
return self._relationship_cardinality_one_data[name]
|
|
1020
|
+
|
|
1021
|
+
raise ResourceNotDefinedError(message=f"The node doesn't have a cardinality=one relationship for {name}")
|
|
1022
|
+
|
|
1023
|
+
def __dir__(self) -> Iterable[str]:
|
|
1024
|
+
base = list(super().__dir__())
|
|
1025
|
+
return sorted(
|
|
1026
|
+
base
|
|
1027
|
+
+ list(self._attribute_data.keys())
|
|
1028
|
+
+ list(self._relationship_cardinality_many_data.keys())
|
|
1029
|
+
+ list(self._relationship_cardinality_one_data.keys())
|
|
1030
|
+
)
|
|
1031
|
+
|
|
1021
1032
|
|
|
1022
1033
|
class InfrahubNodeSync(InfrahubNodeBase):
|
|
1023
1034
|
"""Represents a Infrahub node in a synchronous context."""
|
|
@@ -1036,12 +1047,14 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1036
1047
|
branch (Optional[str]): The branch where the node resides.
|
|
1037
1048
|
data (Optional[dict]): Optional data to initialize the node.
|
|
1038
1049
|
"""
|
|
1039
|
-
self.__class__ = type(f"{schema.kind}InfrahubNodeSync", (self.__class__,), {})
|
|
1040
1050
|
self._client = client
|
|
1041
1051
|
|
|
1042
1052
|
if isinstance(data, dict) and isinstance(data.get("node"), dict):
|
|
1043
1053
|
data = data.get("node")
|
|
1044
1054
|
|
|
1055
|
+
self._relationship_cardinality_many_data: dict[str, RelationshipManagerSync] = {}
|
|
1056
|
+
self._relationship_cardinality_one_data: dict[str, RelatedNodeSync] = {}
|
|
1057
|
+
|
|
1045
1058
|
super().__init__(schema=schema, branch=branch or client.default_branch, data=data)
|
|
1046
1059
|
|
|
1047
1060
|
@classmethod
|
|
@@ -1066,27 +1079,47 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1066
1079
|
rel_data = data.get(rel_schema.name, None) if isinstance(data, dict) else None
|
|
1067
1080
|
|
|
1068
1081
|
if rel_schema.cardinality == "one":
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
self.__class__,
|
|
1072
|
-
rel_schema.name,
|
|
1073
|
-
generate_relationship_property(name=rel_schema.name, node=self),
|
|
1082
|
+
self._relationship_cardinality_one_data[rel_schema.name] = RelatedNodeSync(
|
|
1083
|
+
name=rel_schema.name, branch=self._branch, client=self._client, schema=rel_schema, data=rel_data
|
|
1074
1084
|
)
|
|
1075
|
-
|
|
1085
|
+
|
|
1076
1086
|
else:
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
branch=self._branch,
|
|
1085
|
-
schema=rel_schema,
|
|
1086
|
-
data=rel_data,
|
|
1087
|
-
),
|
|
1087
|
+
self._relationship_cardinality_many_data[rel_schema.name] = RelationshipManagerSync(
|
|
1088
|
+
name=rel_schema.name,
|
|
1089
|
+
client=self._client,
|
|
1090
|
+
node=self,
|
|
1091
|
+
branch=self._branch,
|
|
1092
|
+
schema=rel_schema,
|
|
1093
|
+
data=rel_data,
|
|
1088
1094
|
)
|
|
1089
1095
|
|
|
1096
|
+
def __getattr__(self, name: str) -> Attribute | RelationshipManagerSync | RelatedNodeSync:
|
|
1097
|
+
if "_attribute_data" in self.__dict__ and name in self._attribute_data:
|
|
1098
|
+
return self._attribute_data[name]
|
|
1099
|
+
if "_relationship_cardinality_many_data" in self.__dict__ and name in self._relationship_cardinality_many_data:
|
|
1100
|
+
return self._relationship_cardinality_many_data[name]
|
|
1101
|
+
if "_relationship_cardinality_one_data" in self.__dict__ and name in self._relationship_cardinality_one_data:
|
|
1102
|
+
return self._relationship_cardinality_one_data[name]
|
|
1103
|
+
|
|
1104
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
|
|
1105
|
+
|
|
1106
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
1107
|
+
"""Set values for relationship names that exist or revert to normal behaviour"""
|
|
1108
|
+
if "_relationship_cardinality_one_data" in self.__dict__ and name in self._relationship_cardinality_one_data:
|
|
1109
|
+
rel_schemas = [rel_schema for rel_schema in self._schema.relationships if rel_schema.name == name]
|
|
1110
|
+
if not rel_schemas:
|
|
1111
|
+
raise SchemaNotFoundError(
|
|
1112
|
+
identifier=self._schema.kind,
|
|
1113
|
+
message=f"Unable to find relationship schema for '{name}' on {self._schema.kind}",
|
|
1114
|
+
)
|
|
1115
|
+
rel_schema = rel_schemas[0]
|
|
1116
|
+
self._relationship_cardinality_one_data[name] = RelatedNodeSync(
|
|
1117
|
+
name=rel_schema.name, branch=self._branch, client=self._client, schema=rel_schema, data=value
|
|
1118
|
+
)
|
|
1119
|
+
return
|
|
1120
|
+
|
|
1121
|
+
super().__setattr__(name, value)
|
|
1122
|
+
|
|
1090
1123
|
def generate(self, nodes: list[str] | None = None) -> None:
|
|
1091
1124
|
self._validate_artifact_definition_support(ARTIFACT_DEFINITION_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE)
|
|
1092
1125
|
nodes = nodes or []
|
|
@@ -1097,13 +1130,13 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1097
1130
|
def artifact_generate(self, name: str) -> None:
|
|
1098
1131
|
self._validate_artifact_support(ARTIFACT_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE)
|
|
1099
1132
|
artifact = self._client.get(kind="CoreArtifact", name__value=name, object__ids=[self.id])
|
|
1100
|
-
artifact.definition.fetch()
|
|
1101
|
-
artifact.definition.peer.generate([artifact.id])
|
|
1133
|
+
artifact._get_relationship_one(name="definition").fetch()
|
|
1134
|
+
artifact._get_relationship_one(name="definition").peer.generate([artifact.id])
|
|
1102
1135
|
|
|
1103
1136
|
def artifact_fetch(self, name: str) -> str | dict[str, Any]:
|
|
1104
1137
|
self._validate_artifact_support(ARTIFACT_FETCH_FEATURE_NOT_SUPPORTED_MESSAGE)
|
|
1105
1138
|
artifact = self._client.get(kind="CoreArtifact", name__value=name, object__ids=[self.id])
|
|
1106
|
-
content = self._client.object_store.get(identifier=artifact.storage_id.value)
|
|
1139
|
+
content = self._client.object_store.get(identifier=artifact._get_attribute(name="storage_id").value)
|
|
1107
1140
|
return content
|
|
1108
1141
|
|
|
1109
1142
|
def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None:
|
|
@@ -1545,3 +1578,24 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1545
1578
|
if response[graphql_query_name].get("count", 0):
|
|
1546
1579
|
return [edge["node"] for edge in response[graphql_query_name]["edges"]]
|
|
1547
1580
|
return []
|
|
1581
|
+
|
|
1582
|
+
def _get_relationship_many(self, name: str) -> RelationshipManager | RelationshipManagerSync:
|
|
1583
|
+
if name in self._relationship_cardinality_many_data:
|
|
1584
|
+
return self._relationship_cardinality_many_data[name]
|
|
1585
|
+
|
|
1586
|
+
raise ResourceNotDefinedError(message=f"The node doesn't have a cardinality=many relationship for {name}")
|
|
1587
|
+
|
|
1588
|
+
def _get_relationship_one(self, name: str) -> RelatedNode | RelatedNodeSync:
|
|
1589
|
+
if name in self._relationship_cardinality_one_data:
|
|
1590
|
+
return self._relationship_cardinality_one_data[name]
|
|
1591
|
+
|
|
1592
|
+
raise ResourceNotDefinedError(message=f"The node doesn't have a cardinality=one relationship for {name}")
|
|
1593
|
+
|
|
1594
|
+
def __dir__(self) -> Iterable[str]:
|
|
1595
|
+
base = list(super().__dir__())
|
|
1596
|
+
return sorted(
|
|
1597
|
+
base
|
|
1598
|
+
+ list(self._attribute_data.keys())
|
|
1599
|
+
+ list(self._relationship_cardinality_many_data.keys())
|
|
1600
|
+
+ list(self._relationship_cardinality_one_data.keys())
|
|
1601
|
+
)
|
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
7
7
|
import ujson
|
|
8
8
|
from httpx import HTTPStatusError
|
|
9
9
|
|
|
10
|
+
from ...node import InfrahubNode
|
|
10
11
|
from ..exceptions import OutputMatchError, PythonTransformDefinitionError
|
|
11
12
|
from ..models import InfrahubTestExpectedResult
|
|
12
13
|
from .base import InfrahubItem
|
|
@@ -41,7 +42,7 @@ class InfrahubPythonTransformItem(InfrahubItem):
|
|
|
41
42
|
)
|
|
42
43
|
client = self.session.infrahub_client # type: ignore[attr-defined]
|
|
43
44
|
# TODO: Look into seeing how a transform class may use the branch, but set as a empty string for the time being to keep current behaviour
|
|
44
|
-
self.transform_instance = transform_class(branch="", client=client)
|
|
45
|
+
self.transform_instance = transform_class(branch="", client=client, infrahub_node=InfrahubNode)
|
|
45
46
|
|
|
46
47
|
def run_transform(self, variables: dict[str, Any]) -> Any:
|
|
47
48
|
self.instantiate_transform()
|
infrahub_sdk/query_groups.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Sequence
|
|
3
4
|
from typing import TYPE_CHECKING, Any
|
|
4
5
|
|
|
5
6
|
from .constants import InfrahubClientMode
|
|
@@ -19,7 +20,7 @@ class InfrahubGroupContextBase:
|
|
|
19
20
|
self.related_node_ids: list[str] = []
|
|
20
21
|
self.related_group_ids: list[str] = []
|
|
21
22
|
self.unused_member_ids: list[str] | None = None
|
|
22
|
-
self.previous_members:
|
|
23
|
+
self.previous_members: Sequence[RelatedNodeBase] | None = None
|
|
23
24
|
self.previous_children: list[RelatedNodeBase] | None = None
|
|
24
25
|
self.identifier: str | None = None
|
|
25
26
|
self.params: dict[str, str] = {}
|
|
@@ -101,7 +102,7 @@ class InfrahubGroupContext(InfrahubGroupContextBase):
|
|
|
101
102
|
if not store_peers:
|
|
102
103
|
return group
|
|
103
104
|
|
|
104
|
-
self.previous_members = group.members.peers
|
|
105
|
+
self.previous_members = group._get_relationship_many(name="members").peers
|
|
105
106
|
return group
|
|
106
107
|
|
|
107
108
|
async def delete_unused(self) -> None:
|
|
@@ -195,7 +196,7 @@ class InfrahubGroupContextSync(InfrahubGroupContextBase):
|
|
|
195
196
|
if not store_peers:
|
|
196
197
|
return group
|
|
197
198
|
|
|
198
|
-
self.previous_members = group.members.peers
|
|
199
|
+
self.previous_members = group._get_relationship_many(name="members").peers
|
|
199
200
|
return group
|
|
200
201
|
|
|
201
202
|
def delete_unused(self) -> None:
|
infrahub_sdk/utils.py
CHANGED
|
@@ -240,21 +240,6 @@ def is_valid_url(url: str) -> bool:
|
|
|
240
240
|
return False
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
def find_files(extension: str | list[str], directory: str | Path = ".") -> list[Path]:
|
|
244
|
-
files: list[Path] = []
|
|
245
|
-
|
|
246
|
-
if isinstance(extension, str):
|
|
247
|
-
extension = [extension]
|
|
248
|
-
if isinstance(directory, str):
|
|
249
|
-
directory = Path(directory)
|
|
250
|
-
|
|
251
|
-
for ext in extension:
|
|
252
|
-
files.extend(list(directory.glob(f"**/*.{ext}")))
|
|
253
|
-
files.extend(list(directory.glob(f"**/.*.{ext}")))
|
|
254
|
-
|
|
255
|
-
return files
|
|
256
|
-
|
|
257
|
-
|
|
258
243
|
def get_branch(branch: str | None = None, directory: str | Path = ".") -> str:
|
|
259
244
|
"""If branch isn't provide, return the name of the local Git branch."""
|
|
260
245
|
if branch:
|
|
@@ -351,14 +336,16 @@ def write_to_file(path: Path, value: Any) -> bool:
|
|
|
351
336
|
return written is not None
|
|
352
337
|
|
|
353
338
|
|
|
354
|
-
def read_file(
|
|
355
|
-
if not
|
|
356
|
-
raise FileNotValidError(name=str(
|
|
339
|
+
def read_file(file_path: Path) -> str:
|
|
340
|
+
if not file_path.is_file():
|
|
341
|
+
raise FileNotValidError(name=str(file_path.name), message=f"{file_path.name}: not found at {file_path.parent}")
|
|
357
342
|
try:
|
|
358
|
-
with Path.open(
|
|
343
|
+
with Path.open(file_path, encoding="utf-8") as fobj:
|
|
359
344
|
return fobj.read()
|
|
360
345
|
except UnicodeDecodeError as exc:
|
|
361
|
-
raise FileNotValidError(
|
|
346
|
+
raise FileNotValidError(
|
|
347
|
+
name=str(file_path.name), message=f"Unable to read {file_path.name} with utf-8 encoding"
|
|
348
|
+
) from exc
|
|
362
349
|
|
|
363
350
|
|
|
364
351
|
def get_user_permissions(data: list[dict]) -> dict:
|
infrahub_sdk/yaml.py
CHANGED
|
@@ -10,7 +10,7 @@ from typing_extensions import Self
|
|
|
10
10
|
from yaml.parser import ParserError
|
|
11
11
|
|
|
12
12
|
from .exceptions import FileNotValidError
|
|
13
|
-
from .utils import
|
|
13
|
+
from .utils import read_file
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class InfrahubFileApiVersion(str, Enum):
|
|
@@ -121,12 +121,13 @@ class YamlFile(LocalFile):
|
|
|
121
121
|
def load_from_disk(cls, paths: list[Path]) -> list[Self]:
|
|
122
122
|
yaml_files: list[Self] = []
|
|
123
123
|
for file_path in paths:
|
|
124
|
-
if file_path.is_file():
|
|
124
|
+
if file_path.is_file() and file_path.suffix in [".yaml", ".yml", ".json"]:
|
|
125
125
|
yaml_files.extend(cls.load_file_from_disk(path=file_path))
|
|
126
126
|
elif file_path.is_dir():
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
sub_paths = [Path(sub_file_path) for sub_file_path in file_path.glob("*")]
|
|
128
|
+
sub_files = cls.load_from_disk(paths=sub_paths)
|
|
129
|
+
sorted_sub_files = sorted(sub_files, key=lambda x: x.location)
|
|
130
|
+
yaml_files.extend(sorted_sub_files)
|
|
130
131
|
else:
|
|
131
132
|
raise FileNotValidError(name=str(file_path), message=f"{file_path} does not exist!")
|
|
132
133
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: infrahub-server
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.0b6
|
|
4
4
|
Summary: Infrahub is taking a new approach to Infrastructure Management by providing a new generation of datastore to organize and control all the data that defines how an infrastructure should run.
|
|
5
5
|
License: AGPL-3.0-only
|
|
6
6
|
Author: OpsMill
|
|
@@ -55,7 +55,7 @@ Requires-Dist: toml (>=0.10,<0.11)
|
|
|
55
55
|
Requires-Dist: typer (==0.12.5)
|
|
56
56
|
Requires-Dist: ujson (>=5,<6)
|
|
57
57
|
Requires-Dist: uvicorn[standard] (>=0.32,<0.33)
|
|
58
|
-
Requires-Dist: whenever (==0.7.
|
|
58
|
+
Requires-Dist: whenever (==0.7.3)
|
|
59
59
|
Project-URL: Documentation, https://docs.infrahub.app/
|
|
60
60
|
Project-URL: Homepage, https://opsmill.com
|
|
61
61
|
Project-URL: Repository, https://github.com/opsmill/infrahub
|