infrahub-server 1.3.4__py3-none-any.whl → 1.3.5__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/cli/db.py +34 -0
- infrahub/core/migrations/query/node_duplicate.py +5 -1
- infrahub/core/query/diff.py +17 -3
- infrahub/core/query/relationship.py +8 -11
- infrahub/core/schema/schema_branch.py +22 -0
- infrahub/generators/tasks.py +1 -1
- infrahub/git/integrator.py +1 -1
- infrahub/git/tasks.py +2 -2
- infrahub/graphql/mutations/main.py +24 -5
- infrahub/proposed_change/tasks.py +2 -2
- infrahub_sdk/node/node.py +81 -9
- infrahub_sdk/protocols_base.py +0 -2
- infrahub_sdk/protocols_generator/constants.py +1 -0
- infrahub_sdk/utils.py +0 -17
- {infrahub_server-1.3.4.dist-info → infrahub_server-1.3.5.dist-info}/METADATA +1 -1
- {infrahub_server-1.3.4.dist-info → infrahub_server-1.3.5.dist-info}/RECORD +19 -19
- {infrahub_server-1.3.4.dist-info → infrahub_server-1.3.5.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.3.4.dist-info → infrahub_server-1.3.5.dist-info}/WHEEL +0 -0
- {infrahub_server-1.3.4.dist-info → infrahub_server-1.3.5.dist-info}/entry_points.txt +0 -0
infrahub/cli/db.py
CHANGED
|
@@ -916,5 +916,39 @@ async def run_database_checks(db: InfrahubDatabase, output_dir: Path) -> None:
|
|
|
916
916
|
else:
|
|
917
917
|
rprint(f"{SUCCESS_BADGE} No duplicated edges found")
|
|
918
918
|
|
|
919
|
+
# Check 4: Orphaned Relationships
|
|
920
|
+
rprint("\n[bold cyan]Check 4: Orphaned Relationships[/bold cyan]")
|
|
921
|
+
orphaned_rels_query = """
|
|
922
|
+
MATCH (r:Relationship)-[:IS_RELATED]-(peer:Node)
|
|
923
|
+
WITH DISTINCT r, peer
|
|
924
|
+
WITH r, count(*) AS num_peers
|
|
925
|
+
WHERE num_peers < 2
|
|
926
|
+
MATCH (r)-[e:IS_RELATED]-(peer:Node)
|
|
927
|
+
RETURN DISTINCT
|
|
928
|
+
r.name AS r_name,
|
|
929
|
+
e.branch AS branch,
|
|
930
|
+
e.status AS status,
|
|
931
|
+
e.from AS from_time,
|
|
932
|
+
e.to AS to_time,
|
|
933
|
+
peer.uuid AS peer_uuid,
|
|
934
|
+
peer.kind AS peer_kind
|
|
935
|
+
"""
|
|
936
|
+
results = await db.execute_query(query=orphaned_rels_query)
|
|
937
|
+
if results:
|
|
938
|
+
rprint(f"[red]Found {len(results)} orphaned Relationships[/red]")
|
|
939
|
+
# Write detailed results to file
|
|
940
|
+
output_file = output_dir / "orphaned_relationships.csv"
|
|
941
|
+
with output_file.open(mode="w", newline="") as f:
|
|
942
|
+
writer = DictWriter(
|
|
943
|
+
f,
|
|
944
|
+
fieldnames=["r_name", "branch", "status", "from_time", "to_time", "peer_uuid", "peer_kind"],
|
|
945
|
+
)
|
|
946
|
+
writer.writeheader()
|
|
947
|
+
for result in results:
|
|
948
|
+
writer.writerow(dict(result))
|
|
949
|
+
rprint(f" Detailed results written to: {output_file}")
|
|
950
|
+
else:
|
|
951
|
+
rprint(f"{SUCCESS_BADGE} No orphaned relationships found")
|
|
952
|
+
|
|
919
953
|
rprint(f"\n{SUCCESS_BADGE} Database health checks completed")
|
|
920
954
|
rprint(f"Detailed results saved to: {output_dir.absolute()}")
|
|
@@ -37,9 +37,11 @@ class NodeDuplicateQuery(Query):
|
|
|
37
37
|
super().__init__(**kwargs)
|
|
38
38
|
|
|
39
39
|
def render_match(self) -> str:
|
|
40
|
+
labels_str = ":".join(self.previous_node.labels)
|
|
40
41
|
query = f"""
|
|
41
42
|
// Find all the active nodes
|
|
42
|
-
MATCH (node:{
|
|
43
|
+
MATCH (node:{labels_str})
|
|
44
|
+
WITH DISTINCT node
|
|
43
45
|
"""
|
|
44
46
|
|
|
45
47
|
return query
|
|
@@ -145,6 +147,7 @@ class NodeDuplicateQuery(Query):
|
|
|
145
147
|
WITH active_node, new_node
|
|
146
148
|
// Process Outbound Relationship
|
|
147
149
|
MATCH (active_node)-[]->(peer)
|
|
150
|
+
WITH DISTINCT active_node, new_node, peer
|
|
148
151
|
CALL (active_node, peer) {
|
|
149
152
|
MATCH (active_node)-[r]->(peer)
|
|
150
153
|
WHERE %(branch_filter)s
|
|
@@ -164,6 +167,7 @@ class NodeDuplicateQuery(Query):
|
|
|
164
167
|
WITH DISTINCT active_node, new_node
|
|
165
168
|
// Process Inbound Relationship
|
|
166
169
|
MATCH (active_node)<-[]-(peer)
|
|
170
|
+
WITH DISTINCT active_node, new_node, peer
|
|
167
171
|
CALL (active_node, peer) {
|
|
168
172
|
MATCH (active_node)<-[r]-(peer)
|
|
169
173
|
WHERE %(branch_filter)s
|
infrahub/core/query/diff.py
CHANGED
|
@@ -148,7 +148,14 @@ CALL (diff_path) {
|
|
|
148
148
|
OR type(base_r_node) <> "IS_RELATED" OR type(base_r_prop) <> "IS_RELATED"
|
|
149
149
|
)
|
|
150
150
|
WITH latest_base_path, base_r_root, base_r_node, base_r_prop
|
|
151
|
-
|
|
151
|
+
// status="active" ordering is for tie-breaking edges added and deleted at the same time, we want the active one
|
|
152
|
+
ORDER BY
|
|
153
|
+
base_r_prop.from DESC,
|
|
154
|
+
base_r_prop.status = "active" DESC,
|
|
155
|
+
base_r_node.from DESC,
|
|
156
|
+
base_r_node.status = "active" DESC,
|
|
157
|
+
base_r_root.from DESC,
|
|
158
|
+
base_r_root.status = "active" DESC
|
|
152
159
|
LIMIT 1
|
|
153
160
|
RETURN latest_base_path
|
|
154
161
|
}
|
|
@@ -172,8 +179,6 @@ CALL (penultimate_path) {
|
|
|
172
179
|
AND %(id_func)s(peer_r_node) = %(id_func)s(r_node)
|
|
173
180
|
AND [%(id_func)s(n), type(peer_r_node)] <> [%(id_func)s(peer), type(r_peer)]
|
|
174
181
|
AND r_peer.from < $to_time
|
|
175
|
-
// filter out paths where an earlier from time follows a later from time
|
|
176
|
-
AND peer_r_node.from <= r_peer.from
|
|
177
182
|
// filter out paths where a base branch edge follows a branch edge
|
|
178
183
|
AND (peer_r_node.branch = $base_branch_name OR r_peer.branch = $branch_name)
|
|
179
184
|
// filter out paths where an active edge follows a deleted edge
|
|
@@ -663,6 +668,15 @@ AND ALL(
|
|
|
663
668
|
AND ((r_pair[0]).status = "active" OR (r_pair[1]).status = "deleted")
|
|
664
669
|
// filter out paths where an earlier from time follows a later from time
|
|
665
670
|
AND (r_pair[0]).from <= (r_pair[1]).from
|
|
671
|
+
// if both are deleted, then the deeper edge must have been deleted first
|
|
672
|
+
AND ((r_pair[0]).status = "active" OR (r_pair[1]).status = "active" OR (r_pair[0]).from >= (r_pair[1].from))
|
|
673
|
+
AND (
|
|
674
|
+
(r_pair[0]).status = (r_pair[1]).status
|
|
675
|
+
OR (
|
|
676
|
+
(r_pair[0]).from <= (r_pair[1]).from
|
|
677
|
+
AND ((r_pair[0]).to IS NULL OR (r_pair[0]).to >= (r_pair[1]).from)
|
|
678
|
+
)
|
|
679
|
+
)
|
|
666
680
|
// require adjacent edge pairs to have overlapping times, but only if on the same branch
|
|
667
681
|
AND (
|
|
668
682
|
(r_pair[0]).branch <> (r_pair[1]).branch
|
|
@@ -643,12 +643,9 @@ class RelationshipGetPeerQuery(Query):
|
|
|
643
643
|
|
|
644
644
|
arrows = self.schema.get_query_arrows()
|
|
645
645
|
|
|
646
|
-
path_str = (
|
|
647
|
-
f"{arrows.left.start}[:IS_RELATED]{arrows.left.end}(rl){arrows.right.start}[:IS_RELATED]{arrows.right.end}"
|
|
648
|
-
)
|
|
646
|
+
path_str = f"{arrows.left.start}[r1:IS_RELATED]{arrows.left.end}(rl){arrows.right.start}[r2:IS_RELATED]{arrows.right.end}"
|
|
649
647
|
|
|
650
648
|
branch_level_str = "reduce(br_lvl = 0, r in relationships(path) | br_lvl + r.branch_level)"
|
|
651
|
-
froms_str = db.render_list_comprehension(items="relationships(path)", item_name="from")
|
|
652
649
|
query = """
|
|
653
650
|
MATCH (source_node:Node)%(arrow_left_start)s[:IS_RELATED]%(arrow_left_end)s(rl:Relationship { name: $rel_identifier })
|
|
654
651
|
WHERE source_node.uuid IN $source_ids
|
|
@@ -659,24 +656,24 @@ class RelationshipGetPeerQuery(Query):
|
|
|
659
656
|
$source_kind IN LABELS(source_node) AND
|
|
660
657
|
peer.uuid <> source_node.uuid AND
|
|
661
658
|
$peer_kind IN LABELS(peer) AND
|
|
662
|
-
all(r IN
|
|
663
|
-
WITH source_node, peer, rl,
|
|
664
|
-
RETURN peer as peer,
|
|
665
|
-
|
|
659
|
+
all(r IN [r1, r2] WHERE (%(branch_filter)s))
|
|
660
|
+
WITH source_node, peer, rl, r1, r2, %(branch_level)s AS branch_level
|
|
661
|
+
RETURN peer as peer, r1.status = "active" AND r2.status = "active" AS is_active, [r1, r2] AS rels
|
|
662
|
+
// status is required as a tiebreaker for migrated-kind nodes
|
|
663
|
+
ORDER BY branch_level DESC, r2.from DESC, r2.status ASC, r1.from DESC, r1.status ASC
|
|
666
664
|
LIMIT 1
|
|
667
665
|
}
|
|
668
|
-
WITH peer,
|
|
666
|
+
WITH peer, rl, is_active, rels, source_node
|
|
669
667
|
""" % {
|
|
670
668
|
"path": path_str,
|
|
671
669
|
"branch_filter": branch_filter,
|
|
672
670
|
"branch_level": branch_level_str,
|
|
673
|
-
"froms": froms_str,
|
|
674
671
|
"arrow_left_start": arrows.left.start,
|
|
675
672
|
"arrow_left_end": arrows.left.end,
|
|
676
673
|
}
|
|
677
674
|
|
|
678
675
|
self.add_to_query(query)
|
|
679
|
-
where_clause = [
|
|
676
|
+
where_clause = ["is_active = TRUE"]
|
|
680
677
|
clean_filters = extract_field_filters(field_name=self.schema.name, filters=self.filters)
|
|
681
678
|
|
|
682
679
|
if (clean_filters and "id" in clean_filters) or "ids" in clean_filters:
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
import hashlib
|
|
5
|
+
import keyword
|
|
5
6
|
from collections import defaultdict
|
|
6
7
|
from itertools import chain, combinations
|
|
7
8
|
from typing import Any
|
|
@@ -518,6 +519,7 @@ class SchemaBranch:
|
|
|
518
519
|
|
|
519
520
|
def process_validate(self) -> None:
|
|
520
521
|
self.validate_names()
|
|
522
|
+
self.validate_python_keywords()
|
|
521
523
|
self.validate_kinds()
|
|
522
524
|
self.validate_computed_attributes()
|
|
523
525
|
self.validate_attribute_parameters()
|
|
@@ -987,6 +989,26 @@ class SchemaBranch:
|
|
|
987
989
|
):
|
|
988
990
|
raise ValueError(f"{node.kind}: {rel.name} isn't allowed as a relationship name.")
|
|
989
991
|
|
|
992
|
+
def validate_python_keywords(self) -> None:
|
|
993
|
+
"""Validate that attribute and relationship names don't use Python keywords."""
|
|
994
|
+
for name in self.all_names:
|
|
995
|
+
node = self.get(name=name, duplicate=False)
|
|
996
|
+
|
|
997
|
+
# Check for Python keywords in attribute names
|
|
998
|
+
for attribute in node.attributes:
|
|
999
|
+
if keyword.iskeyword(attribute.name):
|
|
1000
|
+
raise ValueError(
|
|
1001
|
+
f"Python keyword '{attribute.name}' cannot be used as an attribute name on '{node.kind}'"
|
|
1002
|
+
)
|
|
1003
|
+
|
|
1004
|
+
# Check for Python keywords in relationship names
|
|
1005
|
+
if config.SETTINGS.main.schema_strict_mode:
|
|
1006
|
+
for relationship in node.relationships:
|
|
1007
|
+
if keyword.iskeyword(relationship.name):
|
|
1008
|
+
raise ValueError(
|
|
1009
|
+
f"Python keyword '{relationship.name}' cannot be used as a relationship name on '{node.kind}' when using strict mode"
|
|
1010
|
+
)
|
|
1011
|
+
|
|
990
1012
|
def _validate_common_parent(self, node: NodeSchema, rel: RelationshipSchema) -> None:
|
|
991
1013
|
if not rel.common_parent:
|
|
992
1014
|
return
|
infrahub/generators/tasks.py
CHANGED
|
@@ -214,7 +214,7 @@ async def request_generator_definition_run(
|
|
|
214
214
|
repository_kind=repository.typename,
|
|
215
215
|
branch_name=model.branch,
|
|
216
216
|
query=model.generator_definition.query_name,
|
|
217
|
-
variables=member.extract(params=model.generator_definition.parameters),
|
|
217
|
+
variables=await member.extract(params=model.generator_definition.parameters),
|
|
218
218
|
target_id=member.id,
|
|
219
219
|
target_name=member.display_label,
|
|
220
220
|
)
|
infrahub/git/integrator.py
CHANGED
|
@@ -1294,7 +1294,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1294
1294
|
query: CoreGraphQLQuery,
|
|
1295
1295
|
) -> ArtifactGenerateResult:
|
|
1296
1296
|
"""It doesn't look like this is used anywhere today ... we should either remove it or refactor render_artifact below to use this."""
|
|
1297
|
-
variables = target.extract(params=definition.parameters.value)
|
|
1297
|
+
variables = await target.extract(params=definition.parameters.value)
|
|
1298
1298
|
response = await self.sdk.query_gql_query(
|
|
1299
1299
|
name=query.name.value,
|
|
1300
1300
|
variables=variables,
|
infrahub/git/tasks.py
CHANGED
|
@@ -365,7 +365,7 @@ async def generate_request_artifact_definition(
|
|
|
365
365
|
repository_kind=repository.get_kind(),
|
|
366
366
|
branch_name=model.branch,
|
|
367
367
|
query=query.name.value,
|
|
368
|
-
variables=member.extract(params=artifact_definition.parameters.value),
|
|
368
|
+
variables=await member.extract(params=artifact_definition.parameters.value),
|
|
369
369
|
target_id=member.id,
|
|
370
370
|
target_name=member.display_label,
|
|
371
371
|
target_kind=member.get_kind(),
|
|
@@ -583,7 +583,7 @@ async def trigger_repository_user_checks_definitions(
|
|
|
583
583
|
branch_name=model.branch_name,
|
|
584
584
|
check_definition_id=model.check_definition_id,
|
|
585
585
|
proposed_change=model.proposed_change,
|
|
586
|
-
variables=member.extract(params=definition.parameters.value),
|
|
586
|
+
variables=await member.extract(params=definition.parameters.value),
|
|
587
587
|
branch_diff=model.branch_diff,
|
|
588
588
|
timeout=definition.timeout.value,
|
|
589
589
|
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import hashlib
|
|
3
4
|
from dataclasses import dataclass, field
|
|
4
5
|
from typing import TYPE_CHECKING, Any
|
|
5
6
|
|
|
@@ -152,7 +153,7 @@ class InfrahubMutationMixin:
|
|
|
152
153
|
"""
|
|
153
154
|
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
154
155
|
lock_names = _get_kind_lock_names_on_object_mutation(
|
|
155
|
-
kind=cls._meta.active_schema.kind, branch=branch, schema_branch=schema_branch
|
|
156
|
+
kind=cls._meta.active_schema.kind, branch=branch, schema_branch=schema_branch, data=data
|
|
156
157
|
)
|
|
157
158
|
if lock_names:
|
|
158
159
|
async with InfrahubMultiLock(lock_registry=lock.registry, locks=lock_names):
|
|
@@ -216,7 +217,7 @@ class InfrahubMutationMixin:
|
|
|
216
217
|
|
|
217
218
|
schema_branch = db.schema.get_schema_branch(name=branch.name)
|
|
218
219
|
lock_names = _get_kind_lock_names_on_object_mutation(
|
|
219
|
-
kind=cls._meta.active_schema.kind, branch=branch, schema_branch=schema_branch
|
|
220
|
+
kind=cls._meta.active_schema.kind, branch=branch, schema_branch=schema_branch, data=data
|
|
220
221
|
)
|
|
221
222
|
|
|
222
223
|
if db.is_transaction:
|
|
@@ -266,7 +267,6 @@ class InfrahubMutationMixin:
|
|
|
266
267
|
obj = node or await NodeManager.find_object(
|
|
267
268
|
db=db, kind=cls._meta.active_schema.kind, id=data.get("id"), hfid=data.get("hfid"), branch=branch
|
|
268
269
|
)
|
|
269
|
-
|
|
270
270
|
obj, result = await cls._call_mutate_update(info=info, data=data, db=db, branch=branch, obj=obj)
|
|
271
271
|
|
|
272
272
|
return obj, result
|
|
@@ -517,15 +517,34 @@ def _should_kind_be_locked_on_any_branch(kind: str, schema_branch: SchemaBranch)
|
|
|
517
517
|
return False
|
|
518
518
|
|
|
519
519
|
|
|
520
|
-
def
|
|
520
|
+
def _hash(value: str) -> str:
|
|
521
|
+
# Do not use builtin `hash` for lock names as due to randomization results would differ between
|
|
522
|
+
# different processes.
|
|
523
|
+
return hashlib.sha256(value.encode()).hexdigest()
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def _get_kind_lock_names_on_object_mutation(
|
|
527
|
+
kind: str, branch: Branch, schema_branch: SchemaBranch, data: InputObjectType
|
|
528
|
+
) -> list[str]:
|
|
521
529
|
"""
|
|
522
530
|
Return objects kind for which we want to avoid concurrent mutation (create/update). Except for some specific kinds,
|
|
523
531
|
concurrent mutations are only allowed on non-main branch as objects validations will be performed at least when merging in main branch.
|
|
524
532
|
"""
|
|
525
533
|
|
|
526
|
-
if not branch.is_default and not _should_kind_be_locked_on_any_branch(kind, schema_branch):
|
|
534
|
+
if not branch.is_default and not _should_kind_be_locked_on_any_branch(kind=kind, schema_branch=schema_branch):
|
|
527
535
|
return []
|
|
528
536
|
|
|
537
|
+
if kind == InfrahubKind.GRAPHQLQUERYGROUP:
|
|
538
|
+
# Lock on name as well to improve performances
|
|
539
|
+
try:
|
|
540
|
+
name = data.name.value
|
|
541
|
+
return [build_object_lock_name(kind + "." + _hash(name))]
|
|
542
|
+
except AttributeError:
|
|
543
|
+
# We might reach here if we are updating a CoreGraphQLQueryGroup without updating the name,
|
|
544
|
+
# in which case we would not need to lock. This is not supposed to happen as current `update`
|
|
545
|
+
# logic first fetches the node with its name.
|
|
546
|
+
return []
|
|
547
|
+
|
|
529
548
|
lock_kinds = _get_kinds_to_lock_on_object_mutation(kind, schema_branch)
|
|
530
549
|
lock_names = [build_object_lock_name(kind) for kind in lock_kinds]
|
|
531
550
|
return lock_names
|
|
@@ -652,7 +652,7 @@ async def validate_artifacts_generation(
|
|
|
652
652
|
repository_kind=repository.kind,
|
|
653
653
|
branch_name=model.source_branch,
|
|
654
654
|
query=model.artifact_definition.query_name,
|
|
655
|
-
variables=member.extract(params=artifact_definition.parameters.value),
|
|
655
|
+
variables=await member.extract(params=artifact_definition.parameters.value),
|
|
656
656
|
target_id=member.id,
|
|
657
657
|
target_kind=member.get_kind(),
|
|
658
658
|
target_name=member.display_label,
|
|
@@ -913,7 +913,7 @@ async def request_generator_definition_check(
|
|
|
913
913
|
repository_kind=repository.kind,
|
|
914
914
|
branch_name=model.source_branch,
|
|
915
915
|
query=model.generator_definition.query_name,
|
|
916
|
-
variables=member.extract(params=model.generator_definition.parameters),
|
|
916
|
+
variables=await member.extract(params=model.generator_definition.parameters),
|
|
917
917
|
target_id=member.id,
|
|
918
918
|
target_name=member.display_label,
|
|
919
919
|
validator_id=validator.id,
|
infrahub_sdk/node/node.py
CHANGED
|
@@ -8,7 +8,7 @@ from ..constants import InfrahubClientMode
|
|
|
8
8
|
from ..exceptions import FeatureNotSupportedError, NodeNotFoundError, ResourceNotDefinedError, SchemaNotFoundError
|
|
9
9
|
from ..graphql import Mutation, Query
|
|
10
10
|
from ..schema import GenericSchemaAPI, RelationshipCardinality, RelationshipKind
|
|
11
|
-
from ..utils import compare_lists, generate_short_id
|
|
11
|
+
from ..utils import compare_lists, generate_short_id
|
|
12
12
|
from .attribute import Attribute
|
|
13
13
|
from .constants import (
|
|
14
14
|
ARTIFACT_DEFINITION_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE,
|
|
@@ -418,14 +418,6 @@ class InfrahubNodeBase:
|
|
|
418
418
|
|
|
419
419
|
return data
|
|
420
420
|
|
|
421
|
-
def extract(self, params: dict[str, str]) -> dict[str, Any]:
|
|
422
|
-
"""Extract some datapoints defined in a flat notation."""
|
|
423
|
-
result: dict[str, Any] = {}
|
|
424
|
-
for key, value in params.items():
|
|
425
|
-
result[key] = get_flat_value(self, key=value)
|
|
426
|
-
|
|
427
|
-
return result
|
|
428
|
-
|
|
429
421
|
def __hash__(self) -> int:
|
|
430
422
|
return hash(self.id)
|
|
431
423
|
|
|
@@ -1036,6 +1028,46 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
1036
1028
|
|
|
1037
1029
|
raise ResourceNotDefinedError(message=f"The node doesn't have a cardinality=one relationship for {name}")
|
|
1038
1030
|
|
|
1031
|
+
async def get_flat_value(self, key: str, separator: str = "__") -> Any:
|
|
1032
|
+
"""Query recursively a value defined in a flat notation (string), on a hierarchy of objects
|
|
1033
|
+
|
|
1034
|
+
Examples:
|
|
1035
|
+
name__value
|
|
1036
|
+
module.object.value
|
|
1037
|
+
"""
|
|
1038
|
+
if separator not in key:
|
|
1039
|
+
return getattr(self, key)
|
|
1040
|
+
|
|
1041
|
+
first, remaining = key.split(separator, maxsplit=1)
|
|
1042
|
+
|
|
1043
|
+
if first in self._schema.attribute_names:
|
|
1044
|
+
attr = getattr(self, first)
|
|
1045
|
+
for part in remaining.split(separator):
|
|
1046
|
+
attr = getattr(attr, part)
|
|
1047
|
+
return attr
|
|
1048
|
+
|
|
1049
|
+
try:
|
|
1050
|
+
rel = self._schema.get_relationship(name=first)
|
|
1051
|
+
except ValueError as exc:
|
|
1052
|
+
raise ValueError(f"No attribute or relationship named '{first}' for '{self._schema.kind}'") from exc
|
|
1053
|
+
|
|
1054
|
+
if rel.cardinality != RelationshipCardinality.ONE:
|
|
1055
|
+
raise ValueError(
|
|
1056
|
+
f"Can only look up flat value for relationships of cardinality {RelationshipCardinality.ONE.value}"
|
|
1057
|
+
)
|
|
1058
|
+
|
|
1059
|
+
related_node: RelatedNode = getattr(self, first)
|
|
1060
|
+
await related_node.fetch()
|
|
1061
|
+
return await related_node.peer.get_flat_value(key=remaining, separator=separator)
|
|
1062
|
+
|
|
1063
|
+
async def extract(self, params: dict[str, str]) -> dict[str, Any]:
|
|
1064
|
+
"""Extract some datapoints defined in a flat notation."""
|
|
1065
|
+
result: dict[str, Any] = {}
|
|
1066
|
+
for key, value in params.items():
|
|
1067
|
+
result[key] = await self.get_flat_value(key=value)
|
|
1068
|
+
|
|
1069
|
+
return result
|
|
1070
|
+
|
|
1039
1071
|
def __dir__(self) -> Iterable[str]:
|
|
1040
1072
|
base = list(super().__dir__())
|
|
1041
1073
|
return sorted(
|
|
@@ -1622,6 +1654,46 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1622
1654
|
|
|
1623
1655
|
raise ResourceNotDefinedError(message=f"The node doesn't have a cardinality=one relationship for {name}")
|
|
1624
1656
|
|
|
1657
|
+
def get_flat_value(self, key: str, separator: str = "__") -> Any:
|
|
1658
|
+
"""Query recursively a value defined in a flat notation (string), on a hierarchy of objects
|
|
1659
|
+
|
|
1660
|
+
Examples:
|
|
1661
|
+
name__value
|
|
1662
|
+
module.object.value
|
|
1663
|
+
"""
|
|
1664
|
+
if separator not in key:
|
|
1665
|
+
return getattr(self, key)
|
|
1666
|
+
|
|
1667
|
+
first, remaining = key.split(separator, maxsplit=1)
|
|
1668
|
+
|
|
1669
|
+
if first in self._schema.attribute_names:
|
|
1670
|
+
attr = getattr(self, first)
|
|
1671
|
+
for part in remaining.split(separator):
|
|
1672
|
+
attr = getattr(attr, part)
|
|
1673
|
+
return attr
|
|
1674
|
+
|
|
1675
|
+
try:
|
|
1676
|
+
rel = self._schema.get_relationship(name=first)
|
|
1677
|
+
except ValueError as exc:
|
|
1678
|
+
raise ValueError(f"No attribute or relationship named '{first}' for '{self._schema.kind}'") from exc
|
|
1679
|
+
|
|
1680
|
+
if rel.cardinality != RelationshipCardinality.ONE:
|
|
1681
|
+
raise ValueError(
|
|
1682
|
+
f"Can only look up flat value for relationships of cardinality {RelationshipCardinality.ONE.value}"
|
|
1683
|
+
)
|
|
1684
|
+
|
|
1685
|
+
related_node: RelatedNodeSync = getattr(self, first)
|
|
1686
|
+
related_node.fetch()
|
|
1687
|
+
return related_node.peer.get_flat_value(key=remaining, separator=separator)
|
|
1688
|
+
|
|
1689
|
+
def extract(self, params: dict[str, str]) -> dict[str, Any]:
|
|
1690
|
+
"""Extract some datapoints defined in a flat notation."""
|
|
1691
|
+
result: dict[str, Any] = {}
|
|
1692
|
+
for key, value in params.items():
|
|
1693
|
+
result[key] = self.get_flat_value(key=value)
|
|
1694
|
+
|
|
1695
|
+
return result
|
|
1696
|
+
|
|
1625
1697
|
def __dir__(self) -> Iterable[str]:
|
|
1626
1698
|
base = list(super().__dir__())
|
|
1627
1699
|
return sorted(
|
infrahub_sdk/protocols_base.py
CHANGED
infrahub_sdk/utils.py
CHANGED
|
@@ -190,23 +190,6 @@ def str_to_bool(value: str) -> bool:
|
|
|
190
190
|
raise ValueError(f"{value} can not be converted into a boolean") from exc
|
|
191
191
|
|
|
192
192
|
|
|
193
|
-
def get_flat_value(obj: Any, key: str, separator: str = "__") -> Any:
|
|
194
|
-
"""Query recursively an value defined in a flat notation (string), on a hierarchy of objects
|
|
195
|
-
|
|
196
|
-
Examples:
|
|
197
|
-
name__value
|
|
198
|
-
module.object.value
|
|
199
|
-
"""
|
|
200
|
-
if separator not in key:
|
|
201
|
-
return getattr(obj, key)
|
|
202
|
-
|
|
203
|
-
first_part, remaining_part = key.split(separator, maxsplit=1)
|
|
204
|
-
sub_obj = getattr(obj, first_part)
|
|
205
|
-
if not sub_obj:
|
|
206
|
-
return None
|
|
207
|
-
return get_flat_value(obj=sub_obj, key=remaining_part, separator=separator)
|
|
208
|
-
|
|
209
|
-
|
|
210
193
|
def generate_request_filename(request: httpx.Request) -> str:
|
|
211
194
|
"""Return a filename for a request sent to the Infrahub API
|
|
212
195
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: infrahub-server
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.5
|
|
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: Apache-2.0
|
|
6
6
|
Author: OpsMill
|
|
@@ -38,7 +38,7 @@ infrahub/branch/triggers.py,sha256=4sywoEX79fY2NkaGe6tTHnmytf4k6gXDm2FJHkkRJOw,7
|
|
|
38
38
|
infrahub/cli/__init__.py,sha256=zQjE9zMrwAmk_4qb5mbUgNi06g3HKvrPwQvJLQmv9JY,1814
|
|
39
39
|
infrahub/cli/constants.py,sha256=CoCeTMnfsA3j7ArdLKLZK4VPxOM7ls17qpxGJmND0m8,129
|
|
40
40
|
infrahub/cli/context.py,sha256=20CJj_D1VhigR9uhTDPHiVHnV7vzsgK8v-uLKs06kzA,398
|
|
41
|
-
infrahub/cli/db.py,sha256=
|
|
41
|
+
infrahub/cli/db.py,sha256=43u7i1iBkuv_TJMix9H_yLt6erJOgs5p-CoQZaAPIak,37362
|
|
42
42
|
infrahub/cli/events.py,sha256=nJmowQgTxRs6qaT41A71Ei9jm6qtYaL2amAT5TA1H_k,1726
|
|
43
43
|
infrahub/cli/git_agent.py,sha256=ajT9-kdd3xLIysOPe8GqZyCDMkpNyhqfWjBg9HPWVcg,5240
|
|
44
44
|
infrahub/cli/patch.py,sha256=ztOkWyo0l_Wo0WX10bvSqGZibKzowrwx82oi69cjwkY,6018
|
|
@@ -193,7 +193,7 @@ infrahub/core/migrations/query/__init__.py,sha256=JoWOUWlV6IzwxWxObsfCnAAKUOHJkE
|
|
|
193
193
|
infrahub/core/migrations/query/attribute_add.py,sha256=LlhkIfVOR3TFSUJEV_4kU5JBKXsWwTsRiX1ySUPe4TU,3655
|
|
194
194
|
infrahub/core/migrations/query/attribute_rename.py,sha256=onb9Nanht1Tz47JgneAcFsuhqqvPS6dvI2nNjRupLLo,6892
|
|
195
195
|
infrahub/core/migrations/query/delete_element_in_schema.py,sha256=QYw2LIpJGQXBPOTm6w9gFdCltZRd-V_YUh5l9HmGthg,7402
|
|
196
|
-
infrahub/core/migrations/query/node_duplicate.py,sha256=
|
|
196
|
+
infrahub/core/migrations/query/node_duplicate.py,sha256=sW7jRFdKM_AAkd5lbfqxgNZVcEu_e_u1K8epmoAVgaM,8698
|
|
197
197
|
infrahub/core/migrations/query/relationship_duplicate.py,sha256=hjUFjNqhaFc2tEg79BXR2xDr_4Wdmu9fVF02cTEICTk,7319
|
|
198
198
|
infrahub/core/migrations/query/schema_attribute_update.py,sha256=fLclNEgoikO_ddlFEo1ts-dZwTXITA85kdJ00fXFxqo,3382
|
|
199
199
|
infrahub/core/migrations/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -230,10 +230,10 @@ infrahub/core/query/__init__.py,sha256=2qIMaODLwJ6pK6BUd5vODTlA15Aecf5I8_-J44UlC
|
|
|
230
230
|
infrahub/core/query/attribute.py,sha256=DzwbElgTaZs6-nBYGmnDpBr9n0lmUPK3p7eyI30Snh8,11783
|
|
231
231
|
infrahub/core/query/branch.py,sha256=B3QEqpwbJrs_8juWQPaHrdwLNJR-1tSkvMuixCFFdt4,3680
|
|
232
232
|
infrahub/core/query/delete.py,sha256=7tPP1qtNV6QGYtmgE1RKsuQ9oxENnMTVkttLvJ2PiKg,1927
|
|
233
|
-
infrahub/core/query/diff.py,sha256=
|
|
233
|
+
infrahub/core/query/diff.py,sha256=Dc70L5u1wokt106g84QNFJdKhnTTCxmCgAGsBilCgEo,36514
|
|
234
234
|
infrahub/core/query/ipam.py,sha256=0glfVQmcKqMvNyK4GU_zRl2O9pjl7JBeavyE8VC-De4,28234
|
|
235
235
|
infrahub/core/query/node.py,sha256=Rq0jR8Pbs7rPkPMCXnwHFp5Dcl8iLpgrFl4UFRfJ5is,67646
|
|
236
|
-
infrahub/core/query/relationship.py,sha256=
|
|
236
|
+
infrahub/core/query/relationship.py,sha256=KmS9zrcr-RViXxiITXOjq1t0s-AfsICHk3wyyirZBfA,47817
|
|
237
237
|
infrahub/core/query/resource_manager.py,sha256=NpxHVayh-HleoRz-bk54z2_PuBHBdU7ng3pCqKWObbo,16584
|
|
238
238
|
infrahub/core/query/standard_node.py,sha256=mPBXyqk4RzoWRUX4NoojoVi8zk-sJ03GmzmUaWqOgSI,4825
|
|
239
239
|
infrahub/core/query/subquery.py,sha256=UE071w3wccdU_dtKLV-7mdeQ53DKXjPmNxDV0zd5Tpg,7588
|
|
@@ -294,7 +294,7 @@ infrahub/core/schema/manager.py,sha256=Vz6EJo8pDq9u5apRU7wgFMtcsCHDEt9BHwS0VRlct
|
|
|
294
294
|
infrahub/core/schema/node_schema.py,sha256=ld_Wrqf-RsoEUVz_lKE0tcSf5n_oYZYtRI0lTqtd63o,6150
|
|
295
295
|
infrahub/core/schema/profile_schema.py,sha256=cOPSOt5KLgQ0nbqrAN_o33hY_pUtrKmiwSbY_YpVolI,1092
|
|
296
296
|
infrahub/core/schema/relationship_schema.py,sha256=R-1iC1d70bBW0vWhgJhDB0_J3tRpOqcJmmLzh39NuYs,8501
|
|
297
|
-
infrahub/core/schema/schema_branch.py,sha256=
|
|
297
|
+
infrahub/core/schema/schema_branch.py,sha256=Yms2QdNZxqWjtK2sEAgxfRMQmeLEXA16VyqyHErwXgE,106138
|
|
298
298
|
infrahub/core/schema/schema_branch_computed.py,sha256=14UUsQJDLMHkYhg7QMqeLiTF3PO8c8rGa90ul3F2ZZo,10629
|
|
299
299
|
infrahub/core/schema/template_schema.py,sha256=O-PBS9IRM4JX6PxeoyZKwqZ0u0SdQ2zxWMc01PJ2_EA,1084
|
|
300
300
|
infrahub/core/task/__init__.py,sha256=Ied1NvKGJUDmff27z_-yWW8ArenHxGvSvQTaQyx1iHs,128
|
|
@@ -423,15 +423,15 @@ infrahub/events/validator_action.py,sha256=nQJH-RWcgr3-tzmIldvPmu5O7dUAmv1qQnuxx
|
|
|
423
423
|
infrahub/exceptions.py,sha256=cbM-f_2U-5ZFVZ_MaaXgs64k4M7uJ7fqDU2iCRoWlYY,11861
|
|
424
424
|
infrahub/generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
425
425
|
infrahub/generators/models.py,sha256=9qhSfsoG-uYux35HClAxSq7TRfkosqN3i_eQkeTokLs,1916
|
|
426
|
-
infrahub/generators/tasks.py,sha256=
|
|
426
|
+
infrahub/generators/tasks.py,sha256=9K7r9yt2s9kSUfaENeTBEU8Sf-omVuOxLyz_N1DjzxE,9475
|
|
427
427
|
infrahub/git/__init__.py,sha256=KeQ9U8UI5jDj6KB6j00Oal7MZmtOD9vKqVgiezG_EQA,281
|
|
428
428
|
infrahub/git/base.py,sha256=pMkavzZn34j50exrOYBzvlRrW5aGoP5XdWPCg6lMmx4,38802
|
|
429
429
|
infrahub/git/constants.py,sha256=XpzcAkXbsgXZgrXey74id1sXV8Q6EHb_4FNw7BndxyY,106
|
|
430
430
|
infrahub/git/directory.py,sha256=fozxLXXJPweHG95yQwQkR5yy3sfTdmHiczCAJnsUX54,861
|
|
431
|
-
infrahub/git/integrator.py,sha256=
|
|
431
|
+
infrahub/git/integrator.py,sha256=Oh181VNRn-YkllULu8J_J6Vh8VD5BfGQYCriOgZdd_w,62403
|
|
432
432
|
infrahub/git/models.py,sha256=ozk9alxQ8Ops1lw1g8iR3O7INuw1VPsEUr5Wceh9HQY,12152
|
|
433
433
|
infrahub/git/repository.py,sha256=mjYeH3pKWRM3UuvcwRCWeE793FuPbSdY8VF1IYK-BxA,11603
|
|
434
|
-
infrahub/git/tasks.py,sha256=
|
|
434
|
+
infrahub/git/tasks.py,sha256=7NPJxmzOcDworKT-veRcSoL3nM_Lj27VGgdQp3TsYEg,37345
|
|
435
435
|
infrahub/git/utils.py,sha256=xhWxlu_FbMqbrwanpPkex4hKRS_d2AFzlxI_6kVQllw,1741
|
|
436
436
|
infrahub/git/worktree.py,sha256=8IYJWOBytKUWwhMmMVehR4ceeO9e13nV-mvn3iVEgZY,1727
|
|
437
437
|
infrahub/git_credential/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -477,7 +477,7 @@ infrahub/graphql/mutations/diff_conflict.py,sha256=JngQfyKXCVlmtlqQ_VyabmrOEDOEK
|
|
|
477
477
|
infrahub/graphql/mutations/generator.py,sha256=Ulw4whZm8Gc8lJjwfUFoFSsR0cOUliFKl87Oca4B9O0,3579
|
|
478
478
|
infrahub/graphql/mutations/graphql_query.py,sha256=mp_O2byChneCihUrEAFEiIAgJ1gW9WrgtwPetUQmkJw,3562
|
|
479
479
|
infrahub/graphql/mutations/ipam.py,sha256=wIN8OcTNCHVy32YgatWZi2Of-snFYBd4wlxOAJvE-AY,15961
|
|
480
|
-
infrahub/graphql/mutations/main.py,sha256=
|
|
480
|
+
infrahub/graphql/mutations/main.py,sha256=eqUSbjcnDvigmIeLrPA0nyiVHCHdzqDocfbSx-q63lA,21626
|
|
481
481
|
infrahub/graphql/mutations/menu.py,sha256=u2UbOA-TFDRcZRGFkgYTmpGxN2IAUgOvJXd7SnsufyI,3708
|
|
482
482
|
infrahub/graphql/mutations/models.py,sha256=ilkSLr8OxVO9v3Ra_uDyUTJT9qPOmdPMqQbuWIydJMo,264
|
|
483
483
|
infrahub/graphql/mutations/node_getter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -604,7 +604,7 @@ infrahub/proposed_change/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
604
604
|
infrahub/proposed_change/branch_diff.py,sha256=Oerw3cHo51XPKwBsAmpO0T470Fg9mkpWViHVY51hToY,2303
|
|
605
605
|
infrahub/proposed_change/constants.py,sha256=w8fPxKWJM1DzeClRd7Vr53hxkzl2Bq-rnXWfE2y3Bz0,1296
|
|
606
606
|
infrahub/proposed_change/models.py,sha256=ivWJmEAihprKmwgaBGDJ4Koq4ETciE5GfDp86KHDnns,5892
|
|
607
|
-
infrahub/proposed_change/tasks.py,sha256=
|
|
607
|
+
infrahub/proposed_change/tasks.py,sha256=WJuXXJ4zR3MNSpr9ko2hF8HvLU92g3cYWwxSS9h0P6o,61877
|
|
608
608
|
infrahub/pytest_plugin.py,sha256=u3t0WgLMo9XmuQYeb28mccQ3xbnyv2Fv173YWl1zBiM,6678
|
|
609
609
|
infrahub/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
610
610
|
infrahub/schema/tasks.py,sha256=vEaWWksqrfwwCAIgPxscVU81W9PIxODX552Rtkte1Cs,947
|
|
@@ -725,7 +725,7 @@ infrahub_sdk/jinja2.py,sha256=lTfV9E_P5gApaX6RW9M8U8oixQi-0H3U8wcs8fdGVaU,1150
|
|
|
725
725
|
infrahub_sdk/node/__init__.py,sha256=clAUZ9lNVPFguelR5Sg9PzklAZruTKEm2xk-BaO68l8,1262
|
|
726
726
|
infrahub_sdk/node/attribute.py,sha256=oEY1qxip8ETEx9Q33NhSQo013zmzrmpVIFzSkEMUY8M,4547
|
|
727
727
|
infrahub_sdk/node/constants.py,sha256=TJO4uxvv7sc3FjoLdQdV7Ccymqz8AqxDenARst8awb4,775
|
|
728
|
-
infrahub_sdk/node/node.py,sha256=
|
|
728
|
+
infrahub_sdk/node/node.py,sha256=0EuD7N3KyjCK6RkZ48EY0t5LZ68wHrH_wa8PG0tUtZw,73473
|
|
729
729
|
infrahub_sdk/node/parsers.py,sha256=sLDdT6neoYSZIjOCmq8Bgd0LK8FFoasjvJLuSz0whSU,543
|
|
730
730
|
infrahub_sdk/node/property.py,sha256=8Mjkc8bp3kLlHyllwxDJlpJTuOA1ciMgY8mtH3dFVLM,728
|
|
731
731
|
infrahub_sdk/node/related_node.py,sha256=fPMnZ83OZnnbimaPC14MdE3lR-kumAA6hbOhRlo1gms,10093
|
|
@@ -734,9 +734,9 @@ infrahub_sdk/object_store.py,sha256=d-EDnxPpw_7BsbjbGbH50rjt-1-Ojj2zNrhFansP5hA,
|
|
|
734
734
|
infrahub_sdk/operation.py,sha256=hsbZSjLbLsqvjZg5R5x_bOxxlteXJAk0fQy3mLrZhn4,2730
|
|
735
735
|
infrahub_sdk/playback.py,sha256=ubkY1LiW_wFwm4auerdQ0zFJcFJZ1SYQT6-d4bxzaLg,1906
|
|
736
736
|
infrahub_sdk/protocols.py,sha256=lmjBSrmpc-7j9H7mn0DaLpJa8eD2gQk2oy0u2HvGLOk,24209
|
|
737
|
-
infrahub_sdk/protocols_base.py,sha256=
|
|
737
|
+
infrahub_sdk/protocols_base.py,sha256=rw5gP9IEuV2e-DeFHMUoL43nVfxEeGmQKjoE3YZCV78,5616
|
|
738
738
|
infrahub_sdk/protocols_generator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
739
|
-
infrahub_sdk/protocols_generator/constants.py,sha256=
|
|
739
|
+
infrahub_sdk/protocols_generator/constants.py,sha256=8y5L7aqxhez6_10Cl2zUfNlHJCCosIVnxrOPKrwNVEw,820
|
|
740
740
|
infrahub_sdk/protocols_generator/generator.py,sha256=hhBxxMw0Pgbih6GiC81xjb9R9TBT8I4y-O2cIdcbChs,5264
|
|
741
741
|
infrahub_sdk/protocols_generator/template.j2,sha256=cm2wsKXHXOiW7N_byxnE2vLnn8gHQ99rs56qVquTTDw,3722
|
|
742
742
|
infrahub_sdk/pytest_plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -791,7 +791,7 @@ infrahub_sdk/transfer/importer/json.py,sha256=-Tlmg22TiBrEqXOSLMnUzlCFOZ2M0Q8lWy
|
|
|
791
791
|
infrahub_sdk/transfer/schema_sorter.py,sha256=ZoBjJGFT-6jQoKOLaoOPMAWzs7vGOeo7x6zOOP4LNv0,1244
|
|
792
792
|
infrahub_sdk/transforms.py,sha256=RLiB_CkM-JQSfyifChxxQVl2FrHKOGEf_YynSMKeFZU,2340
|
|
793
793
|
infrahub_sdk/types.py,sha256=UeZ1rDp4eyH12ApTcUD9a1OOtCp3IL1YZUeeZ06qF-I,1726
|
|
794
|
-
infrahub_sdk/utils.py,sha256=
|
|
794
|
+
infrahub_sdk/utils.py,sha256=dkNqnMEzyPORQ6mw90mH3Qge1fkIclcuQ5kmxND1JAg,11748
|
|
795
795
|
infrahub_sdk/uuidt.py,sha256=Tz-4nHkJwbi39UT3gaIe2wJeZNAoBqf6tm3sw7LZbXc,2155
|
|
796
796
|
infrahub_sdk/yaml.py,sha256=PRsS7BEM-Xn5wRLAAG-YLTGRBEJy5Dnyim2YskFfe8I,5539
|
|
797
797
|
infrahub_testcontainers/__init__.py,sha256=oPpmesGgYBSdKTg1L37FGwYBeao1EHury5SJGul-CT8,216
|
|
@@ -807,8 +807,8 @@ infrahub_testcontainers/models.py,sha256=ASYyvl7d_WQz_i7y8-3iab9hwwmCl3OCJavqVbe
|
|
|
807
807
|
infrahub_testcontainers/performance_test.py,sha256=hvwiy6tc_lWniYqGkqfOXVGAmA_IV15VOZqbiD9ezno,6149
|
|
808
808
|
infrahub_testcontainers/plugin.py,sha256=I3RuZQ0dARyKHuqCf0y1Yj731P2Mwf3BJUehRJKeWrs,5645
|
|
809
809
|
infrahub_testcontainers/prometheus.yml,sha256=610xQEyj3xuVJMzPkC4m1fRnCrjGpiRBrXA2ytCLa54,599
|
|
810
|
-
infrahub_server-1.3.
|
|
811
|
-
infrahub_server-1.3.
|
|
812
|
-
infrahub_server-1.3.
|
|
813
|
-
infrahub_server-1.3.
|
|
814
|
-
infrahub_server-1.3.
|
|
810
|
+
infrahub_server-1.3.5.dist-info/LICENSE.txt,sha256=7GQO7kxVoQYnZtFrjZBKLRXbrGwwwimHPPOJtqXsozQ,11340
|
|
811
|
+
infrahub_server-1.3.5.dist-info/METADATA,sha256=VciuAufvS-mwMz8x9FC8ca1qiCbS7lR0xpoZsoeeZ1k,8189
|
|
812
|
+
infrahub_server-1.3.5.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
813
|
+
infrahub_server-1.3.5.dist-info/entry_points.txt,sha256=UXIeFWDsrV-4IllNvUEd6KieYGzQfn9paga2YyABOQI,393
|
|
814
|
+
infrahub_server-1.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|