infrahub-server 1.4.3__py3-none-any.whl → 1.4.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/__init__.py +84 -17
- infrahub/core/account.py +60 -34
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/migrations/graph/__init__.py +2 -0
- infrahub/core/migrations/graph/m038_redo_0000_prefix_fix.py +63 -0
- infrahub/generators/tasks.py +9 -6
- infrahub/git/tasks.py +9 -6
- infrahub/graphql/auth/query_permission_checker/object_permission_checker.py +31 -19
- infrahub/lock.py +5 -4
- infrahub/proposed_change/tasks.py +16 -10
- infrahub/tasks/registry.py +13 -3
- infrahub_sdk/branch.py +3 -2
- infrahub_sdk/client.py +17 -12
- infrahub_sdk/ctl/cli_commands.py +11 -5
- infrahub_sdk/graphql.py +3 -1
- infrahub_sdk/node/node.py +26 -16
- {infrahub_server-1.4.3.dist-info → infrahub_server-1.4.5.dist-info}/METADATA +1 -1
- {infrahub_server-1.4.3.dist-info → infrahub_server-1.4.5.dist-info}/RECORD +21 -20
- {infrahub_server-1.4.3.dist-info → infrahub_server-1.4.5.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.4.3.dist-info → infrahub_server-1.4.5.dist-info}/WHEEL +0 -0
- {infrahub_server-1.4.3.dist-info → infrahub_server-1.4.5.dist-info}/entry_points.txt +0 -0
infrahub/cli/__init__.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from asyncio import run as aiorun
|
|
2
|
-
|
|
3
1
|
import typer
|
|
4
2
|
from infrahub_sdk.async_typer import AsyncTyper
|
|
5
3
|
|
|
@@ -43,18 +41,87 @@ async def _init_shell(config_file: str) -> None:
|
|
|
43
41
|
|
|
44
42
|
|
|
45
43
|
@app.command()
|
|
46
|
-
def shell(
|
|
47
|
-
"""Start a python shell within Infrahub context."""
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
from
|
|
53
|
-
from
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
44
|
+
def shell() -> None:
|
|
45
|
+
"""Start a python shell within Infrahub context (requires IPython)."""
|
|
46
|
+
from infrahub_sdk import InfrahubClient
|
|
47
|
+
from IPython import start_ipython
|
|
48
|
+
from traitlets.config import Config
|
|
49
|
+
|
|
50
|
+
from infrahub import config
|
|
51
|
+
from infrahub.components import ComponentType
|
|
52
|
+
from infrahub.core.branch import Branch
|
|
53
|
+
from infrahub.core.initialization import initialization
|
|
54
|
+
from infrahub.core.manager import NodeManager
|
|
55
|
+
from infrahub.core.registry import registry
|
|
56
|
+
from infrahub.dependencies.registry import build_component_registry
|
|
57
|
+
from infrahub.lock import initialize_lock
|
|
58
|
+
from infrahub.services import InfrahubServices
|
|
59
|
+
from infrahub.workers.dependencies import (
|
|
60
|
+
get_cache,
|
|
61
|
+
get_component,
|
|
62
|
+
get_database,
|
|
63
|
+
get_workflow,
|
|
64
|
+
set_component_type,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
async def initialize_service() -> InfrahubServices:
|
|
68
|
+
config.load_and_exit()
|
|
69
|
+
client = InfrahubClient()
|
|
70
|
+
|
|
71
|
+
component_type = ComponentType.GIT_AGENT
|
|
72
|
+
set_component_type(component_type=component_type)
|
|
73
|
+
|
|
74
|
+
database = await get_database()
|
|
75
|
+
|
|
76
|
+
build_component_registry()
|
|
77
|
+
|
|
78
|
+
workflow = get_workflow()
|
|
79
|
+
cache = await get_cache()
|
|
80
|
+
component = await get_component()
|
|
81
|
+
service = await InfrahubServices.new(
|
|
82
|
+
cache=cache,
|
|
83
|
+
client=client,
|
|
84
|
+
database=database,
|
|
85
|
+
workflow=workflow,
|
|
86
|
+
component=component,
|
|
87
|
+
component_type=component_type,
|
|
88
|
+
)
|
|
89
|
+
initialize_lock(service=service)
|
|
90
|
+
|
|
91
|
+
async with service.database as db:
|
|
92
|
+
await initialization(db=db)
|
|
93
|
+
await service.component.refresh_schema_hash()
|
|
94
|
+
|
|
95
|
+
return service
|
|
96
|
+
|
|
97
|
+
def welcome() -> None:
|
|
98
|
+
print("--------------------------------------")
|
|
99
|
+
print("infrahub interactive shell initialized")
|
|
100
|
+
print("--------------------------------------")
|
|
101
|
+
print("Available objects:")
|
|
102
|
+
print("* db: InfrahubDatabase")
|
|
103
|
+
print("* Branch: Branch")
|
|
104
|
+
print("* NodeManager: NodeManager")
|
|
105
|
+
print("* registry: Registry")
|
|
106
|
+
print("* service: InfrahubServices")
|
|
107
|
+
print()
|
|
108
|
+
print("Example use:")
|
|
109
|
+
print("In [1] tags = await NodeManager.query(schema='BuiltinTag', db=db)")
|
|
110
|
+
|
|
111
|
+
c = Config()
|
|
112
|
+
c.InteractiveShellApp.exec_lines = [
|
|
113
|
+
"service = await initialize_service()",
|
|
114
|
+
"db = service.database",
|
|
115
|
+
"welcome()",
|
|
116
|
+
]
|
|
117
|
+
c.TerminalInteractiveShell.colors = "Neutral"
|
|
118
|
+
|
|
119
|
+
user_ns = {
|
|
120
|
+
"initialize_service": initialize_service,
|
|
121
|
+
"welcome": welcome,
|
|
122
|
+
"NodeManager": NodeManager,
|
|
123
|
+
"Branch": Branch,
|
|
124
|
+
"registry": registry,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
start_ipython(argv=[], config=c, user_ns=user_ns)
|
infrahub/core/account.py
CHANGED
|
@@ -5,9 +5,10 @@ from typing import TYPE_CHECKING, Any
|
|
|
5
5
|
|
|
6
6
|
from typing_extensions import Self
|
|
7
7
|
|
|
8
|
-
from infrahub.core.constants import InfrahubKind, PermissionDecision
|
|
8
|
+
from infrahub.core.constants import NULL_VALUE, InfrahubKind, PermissionDecision
|
|
9
9
|
from infrahub.core.query import Query, QueryType
|
|
10
10
|
from infrahub.core.registry import registry
|
|
11
|
+
from infrahub.core.timestamp import Timestamp
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
13
14
|
from infrahub.core.branch import Branch
|
|
@@ -519,47 +520,72 @@ class AccountTokenValidateQuery(Query):
|
|
|
519
520
|
super().__init__(**kwargs)
|
|
520
521
|
|
|
521
522
|
async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
|
|
522
|
-
|
|
523
|
-
|
|
523
|
+
branch_filter, branch_params = self.branch.get_query_filter_path(
|
|
524
|
+
at=self.at.to_string(), branch_agnostic=self.branch_agnostic, is_isolated=False
|
|
524
525
|
)
|
|
525
|
-
self.params.update(
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
526
|
+
self.params.update(branch_params)
|
|
527
|
+
self.params.update(
|
|
528
|
+
{
|
|
529
|
+
"token_attr_name": "token",
|
|
530
|
+
"token_relationship_name": "account__token",
|
|
531
|
+
"token_value": self.token,
|
|
532
|
+
"null_value": NULL_VALUE,
|
|
533
|
+
}
|
|
529
534
|
)
|
|
530
|
-
self.params.update(account_params)
|
|
531
535
|
|
|
532
|
-
self.params["token_value"] = self.token
|
|
533
|
-
|
|
534
|
-
# ruff: noqa: E501
|
|
535
536
|
query = """
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
537
|
+
// --------------
|
|
538
|
+
// get the active token node for this token value, if it exists
|
|
539
|
+
// --------------
|
|
540
|
+
MATCH (token_node:%(token_node_kind)s)-[r1:HAS_ATTRIBUTE]->(:Attribute {name: $token_attr_name})
|
|
541
|
+
-[r2:HAS_VALUE]->(av:AttributeValueIndexed { value: $token_value })
|
|
542
|
+
WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
|
|
543
|
+
ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
|
|
544
|
+
LIMIT 1
|
|
545
|
+
WITH token_node
|
|
546
|
+
WHERE r1.status = "active" AND r2.status = "active"
|
|
547
|
+
// --------------
|
|
548
|
+
// get the expiration time
|
|
549
|
+
// --------------
|
|
550
|
+
OPTIONAL MATCH (token_node)-[r1:HAS_ATTRIBUTE]->(:Attribute {name: "expiration"})
|
|
551
|
+
-[r2:HAS_VALUE]->(av)
|
|
552
|
+
WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
|
|
553
|
+
ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
|
|
554
|
+
LIMIT 1
|
|
555
|
+
WITH token_node, CASE
|
|
556
|
+
WHEN r1.status = "active" AND r2.status = "active" AND av.value <> $null_value THEN av.value
|
|
557
|
+
ELSE NULL
|
|
558
|
+
END AS expiration
|
|
559
|
+
// --------------
|
|
560
|
+
// get the linked account node from the token node
|
|
561
|
+
// --------------
|
|
562
|
+
MATCH (token_node)-[r1:IS_RELATED]-(:Relationship {name: $token_relationship_name})-[r2:IS_RELATED]-(account_node:%(account_node_kind)s)
|
|
563
|
+
WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
|
|
564
|
+
ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
|
|
565
|
+
LIMIT 1
|
|
566
|
+
WITH expiration, account_node
|
|
567
|
+
WHERE r1.status = "active" AND r2.status = "active"
|
|
568
|
+
""" % {
|
|
569
|
+
"branch_filter": branch_filter,
|
|
570
|
+
"token_node_kind": InfrahubKind.ACCOUNTTOKEN,
|
|
571
|
+
"account_node_kind": InfrahubKind.GENERICACCOUNT,
|
|
572
|
+
}
|
|
546
573
|
self.add_to_query(query)
|
|
547
|
-
|
|
548
|
-
self.return_labels = ["at", "av", "acc"]
|
|
549
|
-
|
|
550
|
-
def get_account_name(self) -> str | None:
|
|
551
|
-
"""Return the account name that matched the query or None."""
|
|
552
|
-
if result := self.get_result():
|
|
553
|
-
return result.get("av").get("value")
|
|
554
|
-
|
|
555
|
-
return None
|
|
574
|
+
self.return_labels = ["account_node.uuid AS account_uuid", "expiration"]
|
|
556
575
|
|
|
557
576
|
def get_account_id(self) -> str | None:
|
|
558
577
|
"""Return the account id that matched the query or a None."""
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
578
|
+
result = self.get_result()
|
|
579
|
+
if not result:
|
|
580
|
+
return None
|
|
581
|
+
account_uuid = result.get_as_str(label="account_uuid")
|
|
582
|
+
expiration_with_tz = result.get_as_str(label="expiration")
|
|
583
|
+
if expiration_with_tz is None:
|
|
584
|
+
return account_uuid
|
|
585
|
+
expiration = Timestamp(expiration_with_tz)
|
|
586
|
+
if expiration < Timestamp():
|
|
587
|
+
return None
|
|
588
|
+
return account_uuid
|
|
563
589
|
|
|
564
590
|
|
|
565
591
|
async def validate_token(token: str, db: InfrahubDatabase, branch: Branch | str | None = None) -> str | None:
|
infrahub/core/graph/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
GRAPH_VERSION =
|
|
1
|
+
GRAPH_VERSION = 38
|
|
@@ -39,6 +39,7 @@ from .m034_find_orphaned_schema_fields import Migration034
|
|
|
39
39
|
from .m035_orphan_relationships import Migration035
|
|
40
40
|
from .m036_drop_attr_value_index import Migration036
|
|
41
41
|
from .m037_index_attr_vals import Migration037
|
|
42
|
+
from .m038_redo_0000_prefix_fix import Migration038
|
|
42
43
|
|
|
43
44
|
if TYPE_CHECKING:
|
|
44
45
|
from infrahub.core.root import Root
|
|
@@ -83,6 +84,7 @@ MIGRATIONS: list[type[GraphMigration | InternalSchemaMigration | ArbitraryMigrat
|
|
|
83
84
|
Migration035,
|
|
84
85
|
Migration036,
|
|
85
86
|
Migration037,
|
|
87
|
+
Migration038,
|
|
86
88
|
]
|
|
87
89
|
|
|
88
90
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import ipaddress
|
|
4
|
+
from typing import TYPE_CHECKING, Sequence
|
|
5
|
+
|
|
6
|
+
from infrahub.core.branch.models import Branch
|
|
7
|
+
from infrahub.core.initialization import initialization
|
|
8
|
+
from infrahub.core.ipam.reconciler import IpamReconciler
|
|
9
|
+
from infrahub.core.manager import NodeManager
|
|
10
|
+
from infrahub.core.migrations.shared import MigrationResult
|
|
11
|
+
from infrahub.core.timestamp import Timestamp
|
|
12
|
+
from infrahub.lock import initialize_lock
|
|
13
|
+
from infrahub.log import get_logger
|
|
14
|
+
|
|
15
|
+
from ..shared import InternalSchemaMigration, SchemaMigration
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from infrahub.database import InfrahubDatabase
|
|
19
|
+
|
|
20
|
+
log = get_logger()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Migration038(InternalSchemaMigration):
|
|
24
|
+
"""
|
|
25
|
+
Re-run migration 026 after Migration037 updates AttributeValueIndexed vertices correctly so that the call to
|
|
26
|
+
NodeManager.query will work
|
|
27
|
+
|
|
28
|
+
If someone is upgrading from 1.2.4 (release before migration 026) or earlier to 1.4.x or later, then migration 026
|
|
29
|
+
fail to find any 0.0.0.0 prefix nodes even if they exist. So we run it again here after migration 037 makes the
|
|
30
|
+
AttributeValueIndexed changes to be sure it completes correctly.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
name: str = "038_prefix_0000_fix"
|
|
34
|
+
minimum_version: int = 37
|
|
35
|
+
migrations: Sequence[SchemaMigration] = []
|
|
36
|
+
|
|
37
|
+
async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
|
|
38
|
+
return MigrationResult()
|
|
39
|
+
|
|
40
|
+
async def execute(self, db: InfrahubDatabase) -> MigrationResult:
|
|
41
|
+
# load schemas from database into registry
|
|
42
|
+
initialize_lock()
|
|
43
|
+
await initialization(db=db)
|
|
44
|
+
|
|
45
|
+
at = Timestamp()
|
|
46
|
+
for branch in await Branch.get_list(db=db):
|
|
47
|
+
prefix_0000s = await NodeManager.query(
|
|
48
|
+
db=db, schema="BuiltinIPPrefix", branch=branch, filters={"prefix__values": ["0.0.0.0/0", "::/0"]}
|
|
49
|
+
)
|
|
50
|
+
if not prefix_0000s:
|
|
51
|
+
continue
|
|
52
|
+
ipam_reconciler = IpamReconciler(db=db, branch=branch)
|
|
53
|
+
for prefix in prefix_0000s:
|
|
54
|
+
ip_namespace = await prefix.ip_namespace.get_peer(db=db)
|
|
55
|
+
ip_network = ipaddress.ip_network(prefix.prefix.value)
|
|
56
|
+
await ipam_reconciler.reconcile(
|
|
57
|
+
ip_value=ip_network,
|
|
58
|
+
namespace=ip_namespace,
|
|
59
|
+
node_uuid=prefix.get_id(),
|
|
60
|
+
at=at,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return MigrationResult()
|
infrahub/generators/tasks.py
CHANGED
|
@@ -168,6 +168,15 @@ async def request_generator_definition_run(
|
|
|
168
168
|
|
|
169
169
|
client = get_client()
|
|
170
170
|
|
|
171
|
+
# Needs to be fetched before fetching group members otherwise `object` relationship would override
|
|
172
|
+
# existing node in client store without the `name` attribute due to #521
|
|
173
|
+
existing_instances = await client.filters(
|
|
174
|
+
kind=InfrahubKind.GENERATORINSTANCE,
|
|
175
|
+
definition__ids=[model.generator_definition.definition_id],
|
|
176
|
+
include=["object"],
|
|
177
|
+
branch=model.branch,
|
|
178
|
+
)
|
|
179
|
+
|
|
171
180
|
group = await client.get(
|
|
172
181
|
kind=InfrahubKind.GENERICGROUP,
|
|
173
182
|
prefetch_relationships=True,
|
|
@@ -177,12 +186,6 @@ async def request_generator_definition_run(
|
|
|
177
186
|
)
|
|
178
187
|
await group.members.fetch()
|
|
179
188
|
|
|
180
|
-
existing_instances = await client.filters(
|
|
181
|
-
kind=InfrahubKind.GENERATORINSTANCE,
|
|
182
|
-
definition__ids=[model.generator_definition.definition_id],
|
|
183
|
-
include=["object"],
|
|
184
|
-
branch=model.branch,
|
|
185
|
-
)
|
|
186
189
|
instance_by_member = {}
|
|
187
190
|
for instance in existing_instances:
|
|
188
191
|
instance_by_member[instance.object.peer.id] = instance.id
|
infrahub/git/tasks.py
CHANGED
|
@@ -310,6 +310,15 @@ async def generate_request_artifact_definition(
|
|
|
310
310
|
|
|
311
311
|
client = get_client()
|
|
312
312
|
|
|
313
|
+
# Needs to be fetched before fetching group members otherwise `object` relationship would override
|
|
314
|
+
# existing node in client store without the `name` attribute due to #521
|
|
315
|
+
existing_artifacts = await client.filters(
|
|
316
|
+
kind=CoreArtifact,
|
|
317
|
+
definition__ids=[model.artifact_definition_id],
|
|
318
|
+
include=["object"],
|
|
319
|
+
branch=model.branch,
|
|
320
|
+
)
|
|
321
|
+
|
|
313
322
|
artifact_definition = await client.get(
|
|
314
323
|
kind=CoreArtifactDefinition, id=model.artifact_definition_id, branch=model.branch
|
|
315
324
|
)
|
|
@@ -319,12 +328,6 @@ async def generate_request_artifact_definition(
|
|
|
319
328
|
await group.members.fetch()
|
|
320
329
|
current_members = [member.id for member in group.members.peers]
|
|
321
330
|
|
|
322
|
-
existing_artifacts = await client.filters(
|
|
323
|
-
kind=CoreArtifact,
|
|
324
|
-
definition__ids=[model.artifact_definition_id],
|
|
325
|
-
include=["object"],
|
|
326
|
-
branch=model.branch,
|
|
327
|
-
)
|
|
328
331
|
artifacts_by_member = {}
|
|
329
332
|
for artifact in existing_artifacts:
|
|
330
333
|
if artifact.object.id in current_members:
|
|
@@ -7,7 +7,7 @@ from infrahub.core.constants import GLOBAL_BRANCH_NAME, GlobalPermissions, Infra
|
|
|
7
7
|
from infrahub.core.manager import get_schema
|
|
8
8
|
from infrahub.core.schema.node_schema import NodeSchema
|
|
9
9
|
from infrahub.database import InfrahubDatabase
|
|
10
|
-
from infrahub.graphql.analyzer import InfrahubGraphQLQueryAnalyzer
|
|
10
|
+
from infrahub.graphql.analyzer import GraphQLOperation, InfrahubGraphQLQueryAnalyzer
|
|
11
11
|
from infrahub.graphql.initialization import GraphqlParams
|
|
12
12
|
from infrahub.permissions.constants import PermissionDecisionFlag
|
|
13
13
|
from infrahub.utils import extract_camelcase_words
|
|
@@ -119,34 +119,46 @@ class PermissionManagerPermissionChecker(GraphQLQueryPermissionCheckerInterface)
|
|
|
119
119
|
permission_required = GlobalPermission(
|
|
120
120
|
action=GlobalPermissions.MANAGE_PERMISSIONS.value, decision=PermissionDecision.ALLOW_ALL.value
|
|
121
121
|
)
|
|
122
|
+
# Map kinds and the relationship to protect from being read
|
|
123
|
+
kind_relationship_to_check = {
|
|
124
|
+
InfrahubKind.ACCOUNTROLE: "permissions",
|
|
125
|
+
InfrahubKind.BASEPERMISSION: "roles",
|
|
126
|
+
InfrahubKind.GLOBALPERMISSION: "roles",
|
|
127
|
+
InfrahubKind.OBJECTPERMISSION: "roles",
|
|
128
|
+
}
|
|
122
129
|
|
|
123
130
|
async def supports(self, db: InfrahubDatabase, account_session: AccountSession, branch: Branch) -> bool: # noqa: ARG002
|
|
124
131
|
return config.SETTINGS.main.allow_anonymous_access or account_session.authenticated
|
|
125
132
|
|
|
126
133
|
async def check(
|
|
127
134
|
self,
|
|
128
|
-
db: InfrahubDatabase,
|
|
135
|
+
db: InfrahubDatabase, # noqa: ARG002
|
|
129
136
|
account_session: AccountSession, # noqa: ARG002
|
|
130
137
|
analyzed_query: InfrahubGraphQLQueryAnalyzer,
|
|
131
138
|
query_parameters: GraphqlParams,
|
|
132
|
-
branch: Branch,
|
|
139
|
+
branch: Branch, # noqa: ARG002
|
|
133
140
|
) -> CheckerResolution:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
141
|
+
for kind, relationship in self.kind_relationship_to_check.items():
|
|
142
|
+
if (
|
|
143
|
+
kind in analyzed_query.query_report.requested_read
|
|
144
|
+
and relationship in analyzed_query.query_report.requested_read[kind].relationships
|
|
145
|
+
):
|
|
146
|
+
query_parameters.context.active_permissions.raise_for_permission(permission=self.permission_required)
|
|
147
|
+
|
|
148
|
+
for query in analyzed_query.query_report.queries:
|
|
149
|
+
if not query.infrahub_model:
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
# Prevent mutations on permissions and account roles
|
|
153
|
+
if (
|
|
154
|
+
query.operation == GraphQLOperation.MUTATION
|
|
155
|
+
and isinstance(query.infrahub_model, NodeSchema)
|
|
156
|
+
and (
|
|
157
|
+
InfrahubKind.BASEPERMISSION in query.infrahub_model.inherit_from
|
|
158
|
+
or query.infrahub_model.kind == InfrahubKind.ACCOUNTROLE
|
|
159
|
+
)
|
|
160
|
+
):
|
|
161
|
+
query_parameters.context.active_permissions.raise_for_permission(permission=self.permission_required)
|
|
150
162
|
|
|
151
163
|
return CheckerResolution.NEXT_CHECKER
|
|
152
164
|
|
infrahub/lock.py
CHANGED
|
@@ -13,6 +13,7 @@ from redis.asyncio.lock import Lock as GlobalLock
|
|
|
13
13
|
|
|
14
14
|
from infrahub import config
|
|
15
15
|
from infrahub.core.timestamp import current_timestamp
|
|
16
|
+
from infrahub.worker import WORKER_IDENTITY
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from types import TracebackType
|
|
@@ -92,7 +93,7 @@ class NATSLock:
|
|
|
92
93
|
await self.release()
|
|
93
94
|
|
|
94
95
|
async def acquire(self) -> None:
|
|
95
|
-
token = current_timestamp()
|
|
96
|
+
token = f"{current_timestamp()}::{WORKER_IDENTITY}"
|
|
96
97
|
while True:
|
|
97
98
|
if await self.do_acquire(token):
|
|
98
99
|
self.token = token
|
|
@@ -138,9 +139,9 @@ class InfrahubLock:
|
|
|
138
139
|
if self.use_local:
|
|
139
140
|
self.local = LocalLock()
|
|
140
141
|
elif config.SETTINGS.cache.driver == config.CacheDriver.Redis:
|
|
141
|
-
self.remote = GlobalLock(redis=self.connection, name=self.name)
|
|
142
|
+
self.remote = GlobalLock(redis=self.connection, name=f"lock.{self.name}")
|
|
142
143
|
else:
|
|
143
|
-
self.remote = NATSLock(service=self.connection, name=self.name)
|
|
144
|
+
self.remote = NATSLock(service=self.connection, name=f"lock.{self.name}")
|
|
144
145
|
|
|
145
146
|
async def __aenter__(self):
|
|
146
147
|
await self.acquire()
|
|
@@ -156,7 +157,7 @@ class InfrahubLock:
|
|
|
156
157
|
async def acquire(self) -> None:
|
|
157
158
|
with LOCK_ACQUIRE_TIME_METRICS.labels(self.name, self.lock_type).time():
|
|
158
159
|
if not self.use_local:
|
|
159
|
-
await self.remote.acquire(token=current_timestamp())
|
|
160
|
+
await self.remote.acquire(token=f"{current_timestamp()}::{WORKER_IDENTITY}")
|
|
160
161
|
else:
|
|
161
162
|
await self.local.acquire()
|
|
162
163
|
self.acquire_time = time.time_ns()
|
|
@@ -646,16 +646,19 @@ async def validate_artifacts_generation(model: RequestArtifactDefinitionCheck, c
|
|
|
646
646
|
context=context,
|
|
647
647
|
)
|
|
648
648
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
await group.members.fetch()
|
|
652
|
-
|
|
649
|
+
# Needs to be fetched before fetching group members otherwise `object` relationship would override
|
|
650
|
+
# existing node in client store without the `name` attribute due to #521
|
|
653
651
|
existing_artifacts = await client.filters(
|
|
654
652
|
kind=InfrahubKind.ARTIFACT,
|
|
655
653
|
definition__ids=[model.artifact_definition.definition_id],
|
|
656
654
|
include=["object"],
|
|
657
655
|
branch=model.source_branch,
|
|
658
656
|
)
|
|
657
|
+
|
|
658
|
+
await artifact_definition.targets.fetch()
|
|
659
|
+
group = artifact_definition.targets.peer
|
|
660
|
+
await group.members.fetch()
|
|
661
|
+
|
|
659
662
|
artifacts_by_member = {}
|
|
660
663
|
for artifact in existing_artifacts:
|
|
661
664
|
artifacts_by_member[artifact.object.peer.id] = artifact.id
|
|
@@ -907,6 +910,15 @@ async def request_generator_definition_check(model: RequestGeneratorDefinitionCh
|
|
|
907
910
|
context=context,
|
|
908
911
|
)
|
|
909
912
|
|
|
913
|
+
# Needs to be fetched before fetching group members otherwise `object` relationship would override
|
|
914
|
+
# existing node in client store without the `name` attribute due to #521
|
|
915
|
+
existing_instances = await client.filters(
|
|
916
|
+
kind=InfrahubKind.GENERATORINSTANCE,
|
|
917
|
+
definition__ids=[model.generator_definition.definition_id],
|
|
918
|
+
include=["object"],
|
|
919
|
+
branch=model.source_branch,
|
|
920
|
+
)
|
|
921
|
+
|
|
910
922
|
group = await client.get(
|
|
911
923
|
kind=InfrahubKind.GENERICGROUP,
|
|
912
924
|
prefetch_relationships=True,
|
|
@@ -916,12 +928,6 @@ async def request_generator_definition_check(model: RequestGeneratorDefinitionCh
|
|
|
916
928
|
)
|
|
917
929
|
await group.members.fetch()
|
|
918
930
|
|
|
919
|
-
existing_instances = await client.filters(
|
|
920
|
-
kind=InfrahubKind.GENERATORINSTANCE,
|
|
921
|
-
definition__ids=[model.generator_definition.definition_id],
|
|
922
|
-
include=["object"],
|
|
923
|
-
branch=model.source_branch,
|
|
924
|
-
)
|
|
925
931
|
instance_by_member = {}
|
|
926
932
|
for instance in existing_instances:
|
|
927
933
|
instance_by_member[instance.object.peer.id] = instance.id
|
infrahub/tasks/registry.py
CHANGED
|
@@ -42,7 +42,7 @@ async def create_branch_registry(db: InfrahubDatabase, branch: Branch) -> None:
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
async def update_branch_registry(db: InfrahubDatabase, branch: Branch) -> None:
|
|
45
|
-
"""Update the registry for a branch if the schema hash has changed."""
|
|
45
|
+
"""Update the registry for a branch if the schema hash has changed or the branch was rebased."""
|
|
46
46
|
|
|
47
47
|
existing_branch: Branch = registry.branch[branch.name]
|
|
48
48
|
|
|
@@ -50,13 +50,23 @@ async def update_branch_registry(db: InfrahubDatabase, branch: Branch) -> None:
|
|
|
50
50
|
log.warning("Branch schema hash is not set, cannot update branch registry")
|
|
51
51
|
return
|
|
52
52
|
|
|
53
|
-
if existing_branch.schema_hash
|
|
53
|
+
if existing_branch.schema_hash.main == branch.active_schema_hash.main:
|
|
54
54
|
log.debug(
|
|
55
|
-
"Branch schema hash is the same, no need to
|
|
55
|
+
"Branch schema hash is the same, no need to refresh the GraphQL schema within the registry",
|
|
56
56
|
branch=branch.name,
|
|
57
57
|
hash=existing_branch.schema_hash.main,
|
|
58
58
|
worker=WORKER_IDENTITY,
|
|
59
59
|
)
|
|
60
|
+
if existing_branch.branched_from != branch.branched_from:
|
|
61
|
+
# If the hash is the same but the branched_from timestamp differs it means
|
|
62
|
+
# that the branch has been rebased and these timestamps need to be refreshed
|
|
63
|
+
# in the registry even though the schema doesn't need to be reloaded.
|
|
64
|
+
log.info(
|
|
65
|
+
"Updating branched_from property in registry for rebased branch",
|
|
66
|
+
branch=branch.name,
|
|
67
|
+
worker=WORKER_IDENTITY,
|
|
68
|
+
)
|
|
69
|
+
registry.branch[branch.name] = branch
|
|
60
70
|
return
|
|
61
71
|
|
|
62
72
|
log.info(
|
infrahub_sdk/branch.py
CHANGED
|
@@ -292,13 +292,14 @@ class InfrahubBranchManagerSync(InfraHubBranchManagerBase):
|
|
|
292
292
|
},
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
mutation_query = MUTATION_QUERY_TASK if background_execution else MUTATION_QUERY_DATA
|
|
296
|
+
query = Mutation(mutation="BranchCreate", input_data=input_data, query=mutation_query)
|
|
296
297
|
response = self.client.execute_graphql(query=query.render(), tracker="mutation-branch-create")
|
|
297
298
|
|
|
298
299
|
# Make sure server version is recent enough to support background execution, as previously
|
|
299
300
|
# using background_execution=True had no effect.
|
|
300
301
|
if background_execution and "task" in response["BranchCreate"]:
|
|
301
|
-
return
|
|
302
|
+
return response["BranchCreate"]["task"]["id"]
|
|
302
303
|
return BranchData(**response["BranchCreate"]["object"])
|
|
303
304
|
|
|
304
305
|
def delete(self, branch_name: str) -> bool:
|
infrahub_sdk/client.py
CHANGED
|
@@ -209,7 +209,7 @@ class BaseClient:
|
|
|
209
209
|
delete_unused_nodes=delete_unused_nodes,
|
|
210
210
|
group_type=group_type,
|
|
211
211
|
group_params=group_params,
|
|
212
|
-
branch=branch,
|
|
212
|
+
branch=branch or self.default_branch,
|
|
213
213
|
)
|
|
214
214
|
|
|
215
215
|
def _graphql_url(
|
|
@@ -310,8 +310,7 @@ class InfrahubClient(BaseClient):
|
|
|
310
310
|
|
|
311
311
|
async def get_user(self) -> dict:
|
|
312
312
|
"""Return user information"""
|
|
313
|
-
|
|
314
|
-
return user_info
|
|
313
|
+
return await self.execute_graphql(query=QUERY_USER)
|
|
315
314
|
|
|
316
315
|
async def get_user_permissions(self) -> dict:
|
|
317
316
|
"""Return user permissions"""
|
|
@@ -540,6 +539,7 @@ class InfrahubClient(BaseClient):
|
|
|
540
539
|
schema_kind: str,
|
|
541
540
|
branch: str,
|
|
542
541
|
prefetch_relationships: bool,
|
|
542
|
+
include: list[str] | None,
|
|
543
543
|
timeout: int | None = None,
|
|
544
544
|
) -> ProcessRelationsNode:
|
|
545
545
|
"""Processes InfrahubNode and their Relationships from the GraphQL query response.
|
|
@@ -564,9 +564,12 @@ class InfrahubClient(BaseClient):
|
|
|
564
564
|
node = await InfrahubNode.from_graphql(client=self, branch=branch, data=item, timeout=timeout)
|
|
565
565
|
nodes.append(node)
|
|
566
566
|
|
|
567
|
-
if prefetch_relationships:
|
|
567
|
+
if prefetch_relationships or (include and any(rel in include for rel in node._relationships)):
|
|
568
568
|
await node._process_relationships(
|
|
569
|
-
node_data=item,
|
|
569
|
+
node_data=item,
|
|
570
|
+
branch=branch,
|
|
571
|
+
related_nodes=related_nodes,
|
|
572
|
+
timeout=timeout,
|
|
570
573
|
)
|
|
571
574
|
|
|
572
575
|
return ProcessRelationsNode(nodes=nodes, related_nodes=related_nodes)
|
|
@@ -816,6 +819,7 @@ class InfrahubClient(BaseClient):
|
|
|
816
819
|
branch=branch,
|
|
817
820
|
prefetch_relationships=prefetch_relationships,
|
|
818
821
|
timeout=timeout,
|
|
822
|
+
include=include,
|
|
819
823
|
)
|
|
820
824
|
return response, process_result
|
|
821
825
|
|
|
@@ -1103,13 +1107,13 @@ class InfrahubClient(BaseClient):
|
|
|
1103
1107
|
) -> dict:
|
|
1104
1108
|
url = f"{self.address}/api/query/{name}"
|
|
1105
1109
|
url_params = copy.deepcopy(params or {})
|
|
1110
|
+
url_params["branch"] = branch_name or self.default_branch
|
|
1111
|
+
|
|
1106
1112
|
headers = copy.copy(self.headers or {})
|
|
1107
1113
|
|
|
1108
1114
|
if self.insert_tracker and tracker:
|
|
1109
1115
|
headers["X-Infrahub-Tracker"] = tracker
|
|
1110
1116
|
|
|
1111
|
-
if branch_name:
|
|
1112
|
-
url_params["branch"] = branch_name
|
|
1113
1117
|
if at:
|
|
1114
1118
|
url_params["at"] = at
|
|
1115
1119
|
|
|
@@ -1565,8 +1569,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1565
1569
|
|
|
1566
1570
|
def get_user(self) -> dict:
|
|
1567
1571
|
"""Return user information"""
|
|
1568
|
-
|
|
1569
|
-
return user_info
|
|
1572
|
+
return self.execute_graphql(query=QUERY_USER)
|
|
1570
1573
|
|
|
1571
1574
|
def get_user_permissions(self) -> dict:
|
|
1572
1575
|
"""Return user permissions"""
|
|
@@ -1831,6 +1834,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1831
1834
|
schema_kind: str,
|
|
1832
1835
|
branch: str,
|
|
1833
1836
|
prefetch_relationships: bool,
|
|
1837
|
+
include: list[str] | None,
|
|
1834
1838
|
timeout: int | None = None,
|
|
1835
1839
|
) -> ProcessRelationsNodeSync:
|
|
1836
1840
|
"""Processes InfrahubNodeSync and their Relationships from the GraphQL query response.
|
|
@@ -1855,7 +1859,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1855
1859
|
node = InfrahubNodeSync.from_graphql(client=self, branch=branch, data=item, timeout=timeout)
|
|
1856
1860
|
nodes.append(node)
|
|
1857
1861
|
|
|
1858
|
-
if prefetch_relationships:
|
|
1862
|
+
if prefetch_relationships or (include and any(rel in include for rel in node._relationships)):
|
|
1859
1863
|
node._process_relationships(node_data=item, branch=branch, related_nodes=related_nodes, timeout=timeout)
|
|
1860
1864
|
|
|
1861
1865
|
return ProcessRelationsNodeSync(nodes=nodes, related_nodes=related_nodes)
|
|
@@ -1980,6 +1984,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1980
1984
|
branch=branch,
|
|
1981
1985
|
prefetch_relationships=prefetch_relationships,
|
|
1982
1986
|
timeout=timeout,
|
|
1987
|
+
include=include,
|
|
1983
1988
|
)
|
|
1984
1989
|
return response, process_result
|
|
1985
1990
|
|
|
@@ -2242,13 +2247,13 @@ class InfrahubClientSync(BaseClient):
|
|
|
2242
2247
|
) -> dict:
|
|
2243
2248
|
url = f"{self.address}/api/query/{name}"
|
|
2244
2249
|
url_params = copy.deepcopy(params or {})
|
|
2250
|
+
url_params["branch"] = branch_name or self.default_branch
|
|
2251
|
+
|
|
2245
2252
|
headers = copy.copy(self.headers or {})
|
|
2246
2253
|
|
|
2247
2254
|
if self.insert_tracker and tracker:
|
|
2248
2255
|
headers["X-Infrahub-Tracker"] = tracker
|
|
2249
2256
|
|
|
2250
|
-
if branch_name:
|
|
2251
|
-
url_params["branch"] = branch_name
|
|
2252
2257
|
if at:
|
|
2253
2258
|
url_params["at"] = at
|
|
2254
2259
|
if subscribers:
|
infrahub_sdk/ctl/cli_commands.py
CHANGED
|
@@ -409,7 +409,6 @@ def info( # noqa: PLR0915
|
|
|
409
409
|
_: str = CONFIG_PARAM,
|
|
410
410
|
) -> None:
|
|
411
411
|
"""Display the status of the Python SDK."""
|
|
412
|
-
|
|
413
412
|
info: dict[str, Any] = {
|
|
414
413
|
"error": None,
|
|
415
414
|
"status": ":x:",
|
|
@@ -417,12 +416,17 @@ def info( # noqa: PLR0915
|
|
|
417
416
|
"user_info": {},
|
|
418
417
|
"groups": {},
|
|
419
418
|
}
|
|
419
|
+
client = initialize_client_sync()
|
|
420
|
+
fetch_user_details = bool(client.config.username) or bool(client.config.api_token)
|
|
421
|
+
|
|
420
422
|
try:
|
|
421
|
-
client = initialize_client_sync()
|
|
422
423
|
info["infrahub_version"] = client.get_version()
|
|
423
|
-
|
|
424
|
+
|
|
425
|
+
if fetch_user_details:
|
|
426
|
+
info["user_info"] = client.get_user()
|
|
427
|
+
info["groups"] = client.get_user_permissions()
|
|
428
|
+
|
|
424
429
|
info["status"] = ":white_heavy_check_mark:"
|
|
425
|
-
info["groups"] = client.get_user_permissions()
|
|
426
430
|
except Exception as e:
|
|
427
431
|
info["error"] = f"{e!s} ({e.__class__.__name__})"
|
|
428
432
|
|
|
@@ -469,7 +473,7 @@ def info( # noqa: PLR0915
|
|
|
469
473
|
pretty_model = Pretty(client.config.model_dump(), expand_all=True)
|
|
470
474
|
layout["client_info"].update(Panel(pretty_model, title="Client Info"))
|
|
471
475
|
|
|
472
|
-
# Infrahub information
|
|
476
|
+
# Infrahub information panel
|
|
473
477
|
infrahub_info = Table(show_header=False, box=None)
|
|
474
478
|
if info["user_info"]:
|
|
475
479
|
infrahub_info.add_row("User:", info["user_info"]["AccountProfile"]["display_label"])
|
|
@@ -487,6 +491,8 @@ def info( # noqa: PLR0915
|
|
|
487
491
|
infrahub_info.add_row("Groups:", "")
|
|
488
492
|
for group, roles in groups.items():
|
|
489
493
|
infrahub_info.add_row("", group, ", ".join(roles))
|
|
494
|
+
else:
|
|
495
|
+
infrahub_info.add_row("User:", "anonymous")
|
|
490
496
|
|
|
491
497
|
layout["infrahub_info"].update(Panel(infrahub_info, title="Infrahub Info"))
|
|
492
498
|
|
infrahub_sdk/graphql.py
CHANGED
|
@@ -8,7 +8,9 @@ from pydantic import BaseModel
|
|
|
8
8
|
VARIABLE_TYPE_MAPPING = ((str, "String!"), (int, "Int!"), (float, "Float!"), (bool, "Boolean!"))
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def convert_to_graphql_as_string(value:
|
|
11
|
+
def convert_to_graphql_as_string(value: Any, convert_enum: bool = False) -> str: # noqa: PLR0911
|
|
12
|
+
if value is None:
|
|
13
|
+
return "null"
|
|
12
14
|
if isinstance(value, str) and value.startswith("$"):
|
|
13
15
|
return value
|
|
14
16
|
if isinstance(value, Enum):
|
infrahub_sdk/node/node.py
CHANGED
|
@@ -234,15 +234,10 @@ class InfrahubNodeBase:
|
|
|
234
234
|
|
|
235
235
|
rel: RelatedNodeBase | RelationshipManagerBase = getattr(self, item_name)
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
# and self._schema.get_relationship(item_name).cardinality == "one"
|
|
242
|
-
# ):
|
|
243
|
-
# data[item_name] = None
|
|
244
|
-
# continue
|
|
245
|
-
# el
|
|
237
|
+
if rel_schema.cardinality == RelationshipCardinality.ONE and rel_schema.optional and not rel.initialized:
|
|
238
|
+
data[item_name] = None
|
|
239
|
+
continue
|
|
240
|
+
|
|
246
241
|
if rel is None or not rel.initialized:
|
|
247
242
|
continue
|
|
248
243
|
|
|
@@ -315,7 +310,16 @@ class InfrahubNodeBase:
|
|
|
315
310
|
variables.pop(variable_key)
|
|
316
311
|
|
|
317
312
|
# TODO: I do not feel _great_ about this
|
|
318
|
-
|
|
313
|
+
# -> I don't even know who you are (but this is not great indeed) -- gmazoyer (quoting Thanos)
|
|
314
|
+
original_data_item = original_data.get(item)
|
|
315
|
+
original_data_item_is_none = original_data_item is None
|
|
316
|
+
if isinstance(original_data_item, dict):
|
|
317
|
+
if "node" in original_data_item:
|
|
318
|
+
original_data_item_is_none = original_data_item["node"] is None
|
|
319
|
+
elif "id" not in original_data_item:
|
|
320
|
+
original_data_item_is_none = True
|
|
321
|
+
|
|
322
|
+
if item in data and (data_item in ({}, []) or (data_item is None and original_data_item_is_none)):
|
|
319
323
|
data.pop(item)
|
|
320
324
|
|
|
321
325
|
def _strip_unmodified(self, data: dict, variables: dict) -> tuple[dict, dict]:
|
|
@@ -324,7 +328,9 @@ class InfrahubNodeBase:
|
|
|
324
328
|
relationship_property = getattr(self, relationship)
|
|
325
329
|
if not relationship_property or relationship not in data:
|
|
326
330
|
continue
|
|
327
|
-
if not relationship_property.initialized
|
|
331
|
+
if not relationship_property.initialized and (
|
|
332
|
+
not isinstance(relationship_property, RelatedNodeBase) or not relationship_property.schema.optional
|
|
333
|
+
):
|
|
328
334
|
data.pop(relationship)
|
|
329
335
|
elif isinstance(relationship_property, RelationshipManagerBase) and not relationship_property.has_update:
|
|
330
336
|
data.pop(relationship)
|
|
@@ -742,12 +748,11 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
742
748
|
continue
|
|
743
749
|
|
|
744
750
|
peer_data: dict[str, Any] = {}
|
|
745
|
-
|
|
751
|
+
should_fetch_relationship = prefetch_relationships or (include is not None and rel_name in include)
|
|
752
|
+
if rel_schema and should_fetch_relationship:
|
|
746
753
|
peer_schema = await self._client.schema.get(kind=rel_schema.peer, branch=self._branch)
|
|
747
754
|
peer_node = InfrahubNode(client=self._client, schema=peer_schema, branch=self._branch)
|
|
748
755
|
peer_data = await peer_node.generate_query_data_node(
|
|
749
|
-
include=include,
|
|
750
|
-
exclude=exclude,
|
|
751
756
|
property=property,
|
|
752
757
|
)
|
|
753
758
|
|
|
@@ -886,7 +891,11 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
886
891
|
await self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)
|
|
887
892
|
|
|
888
893
|
async def _process_relationships(
|
|
889
|
-
self,
|
|
894
|
+
self,
|
|
895
|
+
node_data: dict[str, Any],
|
|
896
|
+
branch: str,
|
|
897
|
+
related_nodes: list[InfrahubNode],
|
|
898
|
+
timeout: int | None = None,
|
|
890
899
|
) -> None:
|
|
891
900
|
"""Processes the Relationships of a InfrahubNode and add Related Nodes to a list.
|
|
892
901
|
|
|
@@ -1363,7 +1372,8 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1363
1372
|
continue
|
|
1364
1373
|
|
|
1365
1374
|
peer_data: dict[str, Any] = {}
|
|
1366
|
-
|
|
1375
|
+
should_fetch_relationship = prefetch_relationships or (include is not None and rel_name in include)
|
|
1376
|
+
if rel_schema and should_fetch_relationship:
|
|
1367
1377
|
peer_schema = self._client.schema.get(kind=rel_schema.peer, branch=self._branch)
|
|
1368
1378
|
peer_node = InfrahubNodeSync(client=self._client, schema=peer_schema, branch=self._branch)
|
|
1369
1379
|
peer_data = peer_node.generate_query_data_node(include=include, exclude=exclude, property=property)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: infrahub-server
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.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
|
|
@@ -36,7 +36,7 @@ infrahub/branch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
36
36
|
infrahub/branch/merge_mutation_checker.py,sha256=bKiQEWEqUqjQEIBDaOKZ2LwA9kgWCEyss80B5yGhPX8,1147
|
|
37
37
|
infrahub/branch/tasks.py,sha256=09AtjKpA5TC9NxsNt3oE--1pHeh1h1hRYvY41YfMt90,1059
|
|
38
38
|
infrahub/branch/triggers.py,sha256=4sywoEX79fY2NkaGe6tTHnmytf4k6gXDm2FJHkkRJOw,793
|
|
39
|
-
infrahub/cli/__init__.py,sha256=
|
|
39
|
+
infrahub/cli/__init__.py,sha256=d8x7c4CIq66zul2w9TdT82qjR5cMXV2zSujovJ4kV00,3948
|
|
40
40
|
infrahub/cli/constants.py,sha256=CoCeTMnfsA3j7ArdLKLZK4VPxOM7ls17qpxGJmND0m8,129
|
|
41
41
|
infrahub/cli/context.py,sha256=u2EYq9-vjzzfZdIYIbYmTG67nYSsyVFDPBtJ3KgE7KY,494
|
|
42
42
|
infrahub/cli/db.py,sha256=hqZcklxTgAKuXWOthrltOdENsiiTthq6tqySxu4HPFE,37727
|
|
@@ -61,7 +61,7 @@ infrahub/constants/database.py,sha256=WmV1iuOk4xulxZHOVvO3sS_VF1eTf7fKh0TPe_RnfV
|
|
|
61
61
|
infrahub/constants/environment.py,sha256=ry-6qsBzSumOjjiq1D3XNoquf1LWqFKiQSJj8t6nET4,32
|
|
62
62
|
infrahub/context.py,sha256=8SZRKSECkkcsNNzDaKEUJ7Nyr0EzUfToAy969LXjQVk,1554
|
|
63
63
|
infrahub/core/__init__.py,sha256=z6EJBZyCYCBqinoBtX9li6BTBbbGV8WCkE_4CrEsmDA,104
|
|
64
|
-
infrahub/core/account.py,sha256=
|
|
64
|
+
infrahub/core/account.py,sha256=6f1cIDWvL-HsbzL0UwWoCbDTzx55wzd_SkpQXiKDjcE,27477
|
|
65
65
|
infrahub/core/attribute.py,sha256=f1-XLuRzbpG7T8y6pqQQqxQkbGDWhS5AZA2_r_mzY-A,44537
|
|
66
66
|
infrahub/core/branch/__init__.py,sha256=h0oIj0gHp1xI-N1cYW8_N6VZ81CBOmLuiUt5cS5nKuk,49
|
|
67
67
|
infrahub/core/branch/enums.py,sha256=vGnaTCzikvMcLikKN25TJ8uCmhnD448dp1ve1_tLjwQ,186
|
|
@@ -139,7 +139,7 @@ infrahub/core/diff/repository/deserializer.py,sha256=bhN9ao8HxqKyRz273QGLNV9z9_S
|
|
|
139
139
|
infrahub/core/diff/repository/repository.py,sha256=u0QTMY1e2dknG_DuRAwzFt-Lp1_mdj5lqF2ymt77k9E,25581
|
|
140
140
|
infrahub/core/diff/tasks.py,sha256=jSXlenTJ5Fc189Xvm971e3-gBDRnfN19cxNaWvEFwAE,3306
|
|
141
141
|
infrahub/core/enums.py,sha256=qGbhRVoH43Xi0iDkUfWdQiKapJbLT9UKsCobFk_paIk,491
|
|
142
|
-
infrahub/core/graph/__init__.py,sha256=
|
|
142
|
+
infrahub/core/graph/__init__.py,sha256=O8Xci_50VdpSOWWUsegCGQvL7gUWJAJNc1ompQbvhf0,19
|
|
143
143
|
infrahub/core/graph/constraints.py,sha256=lmuzrKDFoeSKRiLtycB9PXi6zhMYghczKrPYvfWyy90,10396
|
|
144
144
|
infrahub/core/graph/index.py,sha256=A9jzEE_wldBJsEsflODeMt4GM8sPmmbHAJRNdFioR1k,1736
|
|
145
145
|
infrahub/core/graph/schema.py,sha256=o50Jcy6GBRk55RkDJSMIDDwHhLD7y_RWOirI9rCex4A,10776
|
|
@@ -158,7 +158,7 @@ infrahub/core/ipam/utilization.py,sha256=d-zpXCaWsHgJxBLopCDd7y4sJYvHcIzzpYhbTMI
|
|
|
158
158
|
infrahub/core/manager.py,sha256=xMXPwlaGNnghkRUW0ILwJAUlBQJZqo9cGp9GVyqkqYk,47564
|
|
159
159
|
infrahub/core/merge.py,sha256=TNZpxjNYcl3dnvE8eYXaWSXFDYeEa8DDsS9XbR2XKlA,11217
|
|
160
160
|
infrahub/core/migrations/__init__.py,sha256=dIExw90CrdTByeJqpiWkaZBclpAfzatG2H6fXx54su0,1305
|
|
161
|
-
infrahub/core/migrations/graph/__init__.py,sha256=
|
|
161
|
+
infrahub/core/migrations/graph/__init__.py,sha256=8NNpXMWWxKbuliktUJg7JllIePGERZxOnumC-UmkpX0,4161
|
|
162
162
|
infrahub/core/migrations/graph/m001_add_version_to_graph.py,sha256=YcLN6cFjE6IGheXR4Ujb6CcyY8bJ7WE289hcKJaENOc,1515
|
|
163
163
|
infrahub/core/migrations/graph/m002_attribute_is_default.py,sha256=wB6f2N_ChTvGajqHD-OWCG5ahRMDhhXZuwo79ieq_II,1036
|
|
164
164
|
infrahub/core/migrations/graph/m003_relationship_parent_optional.py,sha256=Aya-s98XfE9C7YluOwEjilwgnjaBnZxp27w_Xdv_NmU,2330
|
|
@@ -196,6 +196,7 @@ infrahub/core/migrations/graph/m034_find_orphaned_schema_fields.py,sha256=Fekohf
|
|
|
196
196
|
infrahub/core/migrations/graph/m035_orphan_relationships.py,sha256=K0J5gzFF5gY-QMom0tRGDckqw19aN0uSV8AZ8KdKSMo,1371
|
|
197
197
|
infrahub/core/migrations/graph/m036_drop_attr_value_index.py,sha256=z2BplzX0mue3lOxrM7xnWDNrs7N3TGdFKHZR-u0wDDY,1439
|
|
198
198
|
infrahub/core/migrations/graph/m037_index_attr_vals.py,sha256=bJB4yPWE73XA_ErUcnY90CR09_jbtA0jW6tE5U0GvQ4,22730
|
|
199
|
+
infrahub/core/migrations/graph/m038_redo_0000_prefix_fix.py,sha256=8seWnXQhgEJDFLWxYHVcnMNDPcHq5C24c0RYrtn_WGE,2411
|
|
199
200
|
infrahub/core/migrations/query/__init__.py,sha256=JoWOUWlV6IzwxWxObsfCnAAKUOHJkE7dZlOsfB64ZEo,876
|
|
200
201
|
infrahub/core/migrations/query/attribute_add.py,sha256=oitzB-PPAclfyNtcwCWJY3RdI5Zi4oEnR62BDzn1UQk,4835
|
|
201
202
|
infrahub/core/migrations/query/attribute_rename.py,sha256=onb9Nanht1Tz47JgneAcFsuhqqvPS6dvI2nNjRupLLo,6892
|
|
@@ -433,7 +434,7 @@ infrahub/events/validator_action.py,sha256=nQJH-RWcgr3-tzmIldvPmu5O7dUAmv1qQnuxx
|
|
|
433
434
|
infrahub/exceptions.py,sha256=cbM-f_2U-5ZFVZ_MaaXgs64k4M7uJ7fqDU2iCRoWlYY,11861
|
|
434
435
|
infrahub/generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
435
436
|
infrahub/generators/models.py,sha256=9qhSfsoG-uYux35HClAxSq7TRfkosqN3i_eQkeTokLs,1916
|
|
436
|
-
infrahub/generators/tasks.py,sha256=
|
|
437
|
+
infrahub/generators/tasks.py,sha256=Ci6lIbnUS6faGzbUjw1ggROpv17guZ-Z9HH9f6cAZv4,9563
|
|
437
438
|
infrahub/git/__init__.py,sha256=KeQ9U8UI5jDj6KB6j00Oal7MZmtOD9vKqVgiezG_EQA,281
|
|
438
439
|
infrahub/git/base.py,sha256=RNXow4RzTBJyjTmT1vZO9_DZSx4Dyv12M-bK_xTBTbg,38657
|
|
439
440
|
infrahub/git/constants.py,sha256=XpzcAkXbsgXZgrXey74id1sXV8Q6EHb_4FNw7BndxyY,106
|
|
@@ -441,7 +442,7 @@ infrahub/git/directory.py,sha256=fozxLXXJPweHG95yQwQkR5yy3sfTdmHiczCAJnsUX54,861
|
|
|
441
442
|
infrahub/git/integrator.py,sha256=C9h1qo8EVE8FjwzGWHhTD50I8TuCTH9asgC8-z5eK-g,62818
|
|
442
443
|
infrahub/git/models.py,sha256=ozk9alxQ8Ops1lw1g8iR3O7INuw1VPsEUr5Wceh9HQY,12152
|
|
443
444
|
infrahub/git/repository.py,sha256=wPsJAA9aHTHdfw0gqCfkNHvcivs7JabsDf-uazptZt0,10928
|
|
444
|
-
infrahub/git/tasks.py,sha256=
|
|
445
|
+
infrahub/git/tasks.py,sha256=aBFN7yV72UshcxFljrmHAKGSDoe0e1eVjrnyPDXQEM8,37515
|
|
445
446
|
infrahub/git/utils.py,sha256=xhWxlu_FbMqbrwanpPkex4hKRS_d2AFzlxI_6kVQllw,1741
|
|
446
447
|
infrahub/git/worktree.py,sha256=8IYJWOBytKUWwhMmMVehR4ceeO9e13nV-mvn3iVEgZY,1727
|
|
447
448
|
infrahub/git_credential/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -460,7 +461,7 @@ infrahub/graphql/auth/query_permission_checker/checker.py,sha256=OSJmoiqETvRtayY
|
|
|
460
461
|
infrahub/graphql/auth/query_permission_checker/default_branch_checker.py,sha256=QiuZXFnaTPaILeIl7MoEu4e6EYexRJd-AZLgAHwaCQc,2173
|
|
461
462
|
infrahub/graphql/auth/query_permission_checker/interface.py,sha256=p4IIicoD1QAM1Q_NiNqOMQqSAIkbNrSHJ-pAlrJfBfo,848
|
|
462
463
|
infrahub/graphql/auth/query_permission_checker/merge_operation_checker.py,sha256=_cv3jSsIA3MXQcD2etCgKzvTKaKNAhwDNqPRIlIzUo4,1640
|
|
463
|
-
infrahub/graphql/auth/query_permission_checker/object_permission_checker.py,sha256=
|
|
464
|
+
infrahub/graphql/auth/query_permission_checker/object_permission_checker.py,sha256=1IVUWIV-GOY_pc3zApii2WNdAG7xHhnw05mUUtXbN6A,9093
|
|
464
465
|
infrahub/graphql/auth/query_permission_checker/super_admin_checker.py,sha256=2RlJ1G-BmJIQW33SletzK1gIQ3nyEB2edTiX0xAjR2E,1550
|
|
465
466
|
infrahub/graphql/constants.py,sha256=iVvo3HK-ch7YmHw1Eg2E_ja3I45cNAwjpYahsnu85CI,37
|
|
466
467
|
infrahub/graphql/context.py,sha256=ahp-MvX_0glg9mSPbPVhEwvbYzrIKtaEAGt7CVnAusE,1681
|
|
@@ -550,7 +551,7 @@ infrahub/groups/models.py,sha256=eOiNtmJapT4zRQ3XbUf8TVb_bhzG2lUfVPhIBZv3Wz0,759
|
|
|
550
551
|
infrahub/groups/parsers.py,sha256=A60n-JmT-8F-7ATugV97R-mPWpRhNVNxqEbpibxiiUs,4260
|
|
551
552
|
infrahub/groups/tasks.py,sha256=yg-VNj37iWdBHyPE9BhN2QzjVo2D8glnlO37pwGcdsU,1563
|
|
552
553
|
infrahub/helpers.py,sha256=KchbQqgipU4VjfwnDbzCGjnEv-4espw_g63Zw4KAhbo,251
|
|
553
|
-
infrahub/lock.py,sha256=
|
|
554
|
+
infrahub/lock.py,sha256=EagMvKKPqWXKLvOpw2OXNPxNa1XLG0JNZgMzCU45EuA,8654
|
|
554
555
|
infrahub/log.py,sha256=4FP80DGY5sk9R7CjcDpPiTfxuow-nfbhXWVpDByCVrw,2817
|
|
555
556
|
infrahub/menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
556
557
|
infrahub/menu/constants.py,sha256=z9aAxIBlAMXrjl3dXo0vZxBU0pcfh1FQOiqIussvpD0,195
|
|
@@ -621,7 +622,7 @@ infrahub/proposed_change/branch_diff.py,sha256=IdMxf5zPmhybQKPPz7AlruNmLCKf5VISP
|
|
|
621
622
|
infrahub/proposed_change/checker.py,sha256=ZhNEVJKsQbHH2UE1O35MfOVa8cK1QGEqGyn6MsOuqSQ,1558
|
|
622
623
|
infrahub/proposed_change/constants.py,sha256=auifG94Oo2cJ4RwZx4P-XDPDpKYPtEVxh013KPfiEdU,2080
|
|
623
624
|
infrahub/proposed_change/models.py,sha256=ivWJmEAihprKmwgaBGDJ4Koq4ETciE5GfDp86KHDnns,5892
|
|
624
|
-
infrahub/proposed_change/tasks.py,sha256
|
|
625
|
+
infrahub/proposed_change/tasks.py,sha256=M1vdCE1J_IBxGwSnQLWwobxhOSDaaxuvEScgZuYbus8,63991
|
|
625
626
|
infrahub/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
626
627
|
infrahub/pytest_plugin.py,sha256=u3t0WgLMo9XmuQYeb28mccQ3xbnyv2Fv173YWl1zBiM,6678
|
|
627
628
|
infrahub/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -662,7 +663,7 @@ infrahub/tasks/check.py,sha256=37n1U1Knb3AV6kz2sw_IabL9pnlqceLVICWf9GdSxZE,687
|
|
|
662
663
|
infrahub/tasks/dummy.py,sha256=6SxlQqQXZqgTuwLaAsK-p1O1TYNKfdGmUYjNJFNHe9s,1209
|
|
663
664
|
infrahub/tasks/keepalive.py,sha256=D6yh3Vmlr1WCEpZibk2YLc2n0dCcX6tM62HCSxyGEu8,783
|
|
664
665
|
infrahub/tasks/recurring.py,sha256=RJO2zdzCU-38Kb81lmCUbFQOBhGui8qn2QizTV4vj9I,447
|
|
665
|
-
infrahub/tasks/registry.py,sha256=
|
|
666
|
+
infrahub/tasks/registry.py,sha256=ncoiZ-GAkyeuKTy5gRkGzQhtx1rSLsMX4o9uZ1A0Kkk,4543
|
|
666
667
|
infrahub/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
667
668
|
infrahub/telemetry/constants.py,sha256=_5mJAZaT_wTCaF7Yzsd---Zn1N6GZkoP_954GK8K4-c,184
|
|
668
669
|
infrahub/telemetry/database.py,sha256=9UVPOxRionVF65jjo8slRIaNBOv-KMRzq7I-7fe3wZE,3111
|
|
@@ -708,9 +709,9 @@ infrahub_sdk/_importer.py,sha256=8oHTMxa_AMO_qbfb3UXNfjSr31S5YJTcqe-YMrixY_E,225
|
|
|
708
709
|
infrahub_sdk/analyzer.py,sha256=UDJN372vdAiuAv2TEyPUlsSVoUfZN6obWkIokNNaHbA,4148
|
|
709
710
|
infrahub_sdk/async_typer.py,sha256=Gj7E8EGdjA-XF404vr9cBt20mmbroQh7N68HXhWYx00,892
|
|
710
711
|
infrahub_sdk/batch.py,sha256=LRZ_04ic56ll9FBjgXCYrJRDJcwB3wR1yX4grrQutDQ,3795
|
|
711
|
-
infrahub_sdk/branch.py,sha256=
|
|
712
|
+
infrahub_sdk/branch.py,sha256=nj0rAOFSqZiAZ5xjwjwTSXdNSso5s7zm6y_6ts6ieSQ,12791
|
|
712
713
|
infrahub_sdk/checks.py,sha256=rFHlEY8XEYcjpLCg6gd9a0R8vPnkxNp0OnXk-odsZKY,5707
|
|
713
|
-
infrahub_sdk/client.py,sha256=
|
|
714
|
+
infrahub_sdk/client.py,sha256=qO5Sd8M1Y5YcZeWXWa6ECExshJS78qajAKpwctZwQas,101899
|
|
714
715
|
infrahub_sdk/config.py,sha256=wnVRkaVO4Nd2IBLRVpLtrC-jjW399mgr1DprohTEzQQ,7936
|
|
715
716
|
infrahub_sdk/constants.py,sha256=Ca66r09eDzpmMhfFAspKFSehSxOmoflVongP-UuBDc4,138
|
|
716
717
|
infrahub_sdk/context.py,sha256=QgXZvtUrKolp6ML8TguVK87Wuu-3KyizZVV_N2F4oCw,400
|
|
@@ -718,7 +719,7 @@ infrahub_sdk/ctl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
|
718
719
|
infrahub_sdk/ctl/branch.py,sha256=GeGDNGNpew93MZblqhG0r45wqSz_p8CcQ9R8zuj_jmg,4742
|
|
719
720
|
infrahub_sdk/ctl/check.py,sha256=HWsK1rTpGF2VvRBiS5KZrRxXrsAHDXoFS3wJkmq8pik,7895
|
|
720
721
|
infrahub_sdk/ctl/cli.py,sha256=A9jJKYBo5opzIIyWYf6niyAHhy49V59g6biueMDFbpE,328
|
|
721
|
-
infrahub_sdk/ctl/cli_commands.py,sha256=
|
|
722
|
+
infrahub_sdk/ctl/cli_commands.py,sha256=fExd8OiXwzfDXPPq_JC9jPKH58k3o9JK9-yf18te2nU,18753
|
|
722
723
|
infrahub_sdk/ctl/client.py,sha256=6bmXmQta9qQCJ8HybQwt2uSF2X1Em91xNFpwiKFujxs,2083
|
|
723
724
|
infrahub_sdk/ctl/config.py,sha256=y3kTvfxDO2FKzgvaIXKPKOES7BqXT-s9Kuww7ROfs-4,3039
|
|
724
725
|
infrahub_sdk/ctl/exceptions.py,sha256=RPdBtIj5qVvNqNR9Y-mPNF7kDUxXUUCac5msyitrBXo,272
|
|
@@ -738,13 +739,13 @@ infrahub_sdk/data.py,sha256=4d8Fd1s7lTeOu8JWXsK2m2BM8t_5HG0Z73fnCZGc7Pc,841
|
|
|
738
739
|
infrahub_sdk/diff.py,sha256=Ms-3YyXo-DoF1feV9qP7GKakBYUNFsULZdy-yMEG71w,4258
|
|
739
740
|
infrahub_sdk/exceptions.py,sha256=gZLfZhyDd0M-w5WMzzfPkFwha-aZirJ739N_OMN7Ujs,5728
|
|
740
741
|
infrahub_sdk/generator.py,sha256=I00G7BdQohJFZ7wQru1SWcwO41gPbuQ3ZGEDVkLIn60,3403
|
|
741
|
-
infrahub_sdk/graphql.py,sha256=
|
|
742
|
+
infrahub_sdk/graphql.py,sha256=UQValA_5oEtdm2VC2tuzUnjm4CEj3J0qk79f70cLr84,7024
|
|
742
743
|
infrahub_sdk/groups.py,sha256=GL14ByW4GHrkqOLJ-_vGhu6bkYDxljqPtkErcQVehv0,711
|
|
743
744
|
infrahub_sdk/jinja2.py,sha256=lTfV9E_P5gApaX6RW9M8U8oixQi-0H3U8wcs8fdGVaU,1150
|
|
744
745
|
infrahub_sdk/node/__init__.py,sha256=clAUZ9lNVPFguelR5Sg9PzklAZruTKEm2xk-BaO68l8,1262
|
|
745
746
|
infrahub_sdk/node/attribute.py,sha256=oEY1qxip8ETEx9Q33NhSQo013zmzrmpVIFzSkEMUY8M,4547
|
|
746
747
|
infrahub_sdk/node/constants.py,sha256=TJO4uxvv7sc3FjoLdQdV7Ccymqz8AqxDenARst8awb4,775
|
|
747
|
-
infrahub_sdk/node/node.py,sha256=
|
|
748
|
+
infrahub_sdk/node/node.py,sha256=9ZDySD3NLRgu9hDsw71YO_LLUGKsT0JOMy2kOXzvyFU,74201
|
|
748
749
|
infrahub_sdk/node/parsers.py,sha256=sLDdT6neoYSZIjOCmq8Bgd0LK8FFoasjvJLuSz0whSU,543
|
|
749
750
|
infrahub_sdk/node/property.py,sha256=8Mjkc8bp3kLlHyllwxDJlpJTuOA1ciMgY8mtH3dFVLM,728
|
|
750
751
|
infrahub_sdk/node/related_node.py,sha256=fPMnZ83OZnnbimaPC14MdE3lR-kumAA6hbOhRlo1gms,10093
|
|
@@ -826,8 +827,8 @@ infrahub_testcontainers/models.py,sha256=ASYyvl7d_WQz_i7y8-3iab9hwwmCl3OCJavqVbe
|
|
|
826
827
|
infrahub_testcontainers/performance_test.py,sha256=hvwiy6tc_lWniYqGkqfOXVGAmA_IV15VOZqbiD9ezno,6149
|
|
827
828
|
infrahub_testcontainers/plugin.py,sha256=I3RuZQ0dARyKHuqCf0y1Yj731P2Mwf3BJUehRJKeWrs,5645
|
|
828
829
|
infrahub_testcontainers/prometheus.yml,sha256=610xQEyj3xuVJMzPkC4m1fRnCrjGpiRBrXA2ytCLa54,599
|
|
829
|
-
infrahub_server-1.4.
|
|
830
|
-
infrahub_server-1.4.
|
|
831
|
-
infrahub_server-1.4.
|
|
832
|
-
infrahub_server-1.4.
|
|
833
|
-
infrahub_server-1.4.
|
|
830
|
+
infrahub_server-1.4.5.dist-info/LICENSE.txt,sha256=7GQO7kxVoQYnZtFrjZBKLRXbrGwwwimHPPOJtqXsozQ,11340
|
|
831
|
+
infrahub_server-1.4.5.dist-info/METADATA,sha256=MHlD-kNOoe00t0MsyjiyHHPyfF4WkAneljzGh6VJg90,8277
|
|
832
|
+
infrahub_server-1.4.5.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
833
|
+
infrahub_server-1.4.5.dist-info/entry_points.txt,sha256=UXIeFWDsrV-4IllNvUEd6KieYGzQfn9paga2YyABOQI,393
|
|
834
|
+
infrahub_server-1.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|