infrahub-server 1.5.5__py3-none-any.whl → 1.6.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/api/artifact.py +5 -3
- infrahub/auth.py +5 -6
- infrahub/cli/db.py +3 -3
- infrahub/cli/db_commands/clean_duplicate_schema_fields.py +2 -2
- infrahub/cli/dev.py +30 -0
- infrahub/config.py +62 -14
- infrahub/constants/database.py +5 -5
- infrahub/core/branch/models.py +24 -6
- infrahub/core/diff/model/diff.py +2 -2
- infrahub/core/graph/constraints.py +2 -2
- infrahub/core/manager.py +155 -29
- infrahub/core/merge.py +29 -2
- infrahub/core/migrations/graph/m041_deleted_dup_edges.py +2 -3
- infrahub/core/migrations/shared.py +2 -2
- infrahub/core/node/__init__.py +1 -1
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/node_property_attribute.py +2 -2
- infrahub/core/protocols.py +7 -1
- infrahub/core/query/branch.py +11 -0
- infrahub/core/query/standard_node.py +3 -0
- infrahub/core/relationship/model.py +3 -9
- infrahub/core/schema/__init__.py +3 -3
- infrahub/core/task/user_task.py +2 -2
- infrahub/core/validators/enum.py +2 -2
- infrahub/dependencies/interface.py +2 -2
- infrahub/events/constants.py +2 -2
- infrahub/git/base.py +43 -1
- infrahub/git/models.py +2 -1
- infrahub/git/repository.py +5 -1
- infrahub/git/tasks.py +28 -1
- infrahub/git/utils.py +9 -0
- infrahub/graphql/analyzer.py +4 -4
- infrahub/graphql/mutations/computed_attribute.py +1 -1
- infrahub/graphql/mutations/convert_object_type.py +1 -1
- infrahub/graphql/mutations/display_label.py +1 -1
- infrahub/graphql/mutations/hfid.py +1 -1
- infrahub/graphql/mutations/ipam.py +1 -1
- infrahub/graphql/mutations/profile.py +1 -0
- infrahub/graphql/mutations/relationship.py +2 -2
- infrahub/graphql/mutations/resource_manager.py +1 -1
- infrahub/graphql/queries/__init__.py +2 -1
- infrahub/graphql/queries/branch.py +58 -3
- infrahub/graphql/queries/ipam.py +9 -4
- infrahub/graphql/queries/resource_manager.py +5 -8
- infrahub/graphql/queries/search.py +3 -3
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/types/__init__.py +3 -1
- infrahub/graphql/types/branch.py +98 -2
- infrahub/lock.py +6 -6
- infrahub/patch/constants.py +2 -2
- infrahub/task_manager/task.py +2 -2
- infrahub/telemetry/constants.py +2 -2
- infrahub/trigger/models.py +2 -2
- infrahub/utils.py +1 -1
- infrahub/validators/tasks.py +1 -1
- infrahub/workers/infrahub_async.py +37 -0
- infrahub_sdk/async_typer.py +2 -1
- infrahub_sdk/batch.py +2 -2
- infrahub_sdk/client.py +8 -9
- infrahub_sdk/config.py +2 -2
- infrahub_sdk/ctl/branch.py +1 -1
- infrahub_sdk/ctl/cli.py +2 -2
- infrahub_sdk/ctl/cli_commands.py +2 -1
- infrahub_sdk/ctl/graphql.py +2 -2
- infrahub_sdk/ctl/importer.py +1 -1
- infrahub_sdk/ctl/utils.py +3 -3
- infrahub_sdk/node/attribute.py +11 -10
- infrahub_sdk/node/constants.py +1 -2
- infrahub_sdk/node/node.py +54 -11
- infrahub_sdk/node/related_node.py +1 -1
- infrahub_sdk/object_store.py +4 -4
- infrahub_sdk/operation.py +2 -2
- infrahub_sdk/protocols_generator/generator.py +1 -1
- infrahub_sdk/pytest_plugin/items/jinja2_transform.py +1 -1
- infrahub_sdk/pytest_plugin/models.py +1 -1
- infrahub_sdk/pytest_plugin/plugin.py +1 -1
- infrahub_sdk/query_groups.py +2 -2
- infrahub_sdk/schema/__init__.py +10 -11
- infrahub_sdk/schema/main.py +2 -2
- infrahub_sdk/schema/repository.py +2 -2
- infrahub_sdk/spec/object.py +2 -2
- infrahub_sdk/spec/range_expansion.py +1 -1
- infrahub_sdk/template/__init__.py +2 -1
- infrahub_sdk/transfer/importer/json.py +3 -3
- infrahub_sdk/types.py +2 -2
- infrahub_sdk/utils.py +2 -2
- {infrahub_server-1.5.5.dist-info → infrahub_server-1.6.0b0.dist-info}/METADATA +58 -59
- {infrahub_server-1.5.5.dist-info → infrahub_server-1.6.0b0.dist-info}/RECORD +217 -223
- {infrahub_server-1.5.5.dist-info → infrahub_server-1.6.0b0.dist-info}/WHEEL +1 -1
- infrahub_server-1.6.0b0.dist-info/entry_points.txt +12 -0
- infrahub_testcontainers/docker-compose-cluster.test.yml +1 -1
- infrahub_testcontainers/docker-compose.test.yml +1 -1
- infrahub/core/schema/generated/__init__.py +0 -0
- infrahub/core/schema/generated/attribute_schema.py +0 -133
- infrahub/core/schema/generated/base_node_schema.py +0 -111
- infrahub/core/schema/generated/genericnode_schema.py +0 -30
- infrahub/core/schema/generated/node_schema.py +0 -40
- infrahub/core/schema/generated/relationship_schema.py +0 -141
- infrahub_server-1.5.5.dist-info/entry_points.txt +0 -13
- {infrahub_server-1.5.5.dist-info → infrahub_server-1.6.0b0.dist-info/licenses}/LICENSE.txt +0 -0
infrahub/graphql/types/branch.py
CHANGED
|
@@ -2,11 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
|
-
from graphene import Boolean, Field, Int, String
|
|
5
|
+
from graphene import Boolean, Field, Int, List, NonNull, String
|
|
6
6
|
|
|
7
7
|
from infrahub.core.branch import Branch
|
|
8
8
|
from infrahub.core.constants import GLOBAL_BRANCH_NAME
|
|
9
9
|
|
|
10
|
+
from ...exceptions import BranchNotFoundError
|
|
10
11
|
from .enums import InfrahubBranchStatus
|
|
11
12
|
from .standard_node import InfrahubObjectType
|
|
12
13
|
|
|
@@ -33,6 +34,10 @@ class BranchType(InfrahubObjectType):
|
|
|
33
34
|
name = "Branch"
|
|
34
35
|
model = Branch
|
|
35
36
|
|
|
37
|
+
@staticmethod
|
|
38
|
+
async def _map_fields_to_graphql(objs: list[Branch], fields: dict) -> list[dict[str, Any]]:
|
|
39
|
+
return [await obj.to_graphql(fields=fields) for obj in objs]
|
|
40
|
+
|
|
36
41
|
@classmethod
|
|
37
42
|
async def get_list(
|
|
38
43
|
cls,
|
|
@@ -46,4 +51,95 @@ class BranchType(InfrahubObjectType):
|
|
|
46
51
|
if not objs:
|
|
47
52
|
return []
|
|
48
53
|
|
|
49
|
-
return
|
|
54
|
+
return await cls._map_fields_to_graphql(objs=objs, fields=fields)
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
async def get_by_name(
|
|
58
|
+
cls,
|
|
59
|
+
fields: dict,
|
|
60
|
+
graphql_context: GraphqlContext,
|
|
61
|
+
name: str,
|
|
62
|
+
) -> dict[str, Any]:
|
|
63
|
+
branch_responses = await cls.get_list(fields=fields, graphql_context=graphql_context, name=name)
|
|
64
|
+
|
|
65
|
+
if branch_responses:
|
|
66
|
+
return branch_responses[0]
|
|
67
|
+
raise BranchNotFoundError(f"Branch with name '{name}' not found")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class RequiredStringValueField(InfrahubObjectType):
|
|
71
|
+
value = String(required=True)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class NonRequiredStringValueField(InfrahubObjectType):
|
|
75
|
+
value = String(required=False)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class NonRequiredIntValueField(InfrahubObjectType):
|
|
79
|
+
value = Int(required=False)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class NonRequiredBooleanValueField(InfrahubObjectType):
|
|
83
|
+
value = Boolean(required=False)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class StatusField(InfrahubObjectType):
|
|
87
|
+
value = InfrahubBranchStatus(required=True)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class InfrahubBranch(BranchType):
|
|
91
|
+
name = Field(RequiredStringValueField, required=True)
|
|
92
|
+
description = Field(NonRequiredStringValueField, required=False)
|
|
93
|
+
origin_branch = Field(NonRequiredStringValueField, required=False)
|
|
94
|
+
branched_from = Field(NonRequiredStringValueField, required=False)
|
|
95
|
+
graph_version = Field(NonRequiredIntValueField, required=False)
|
|
96
|
+
status = Field(StatusField, required=True)
|
|
97
|
+
sync_with_git = Field(NonRequiredBooleanValueField, required=False)
|
|
98
|
+
is_default = Field(NonRequiredBooleanValueField, required=False)
|
|
99
|
+
is_isolated = Field(
|
|
100
|
+
NonRequiredBooleanValueField, required=False, deprecation_reason="non isolated mode is not supported anymore"
|
|
101
|
+
)
|
|
102
|
+
has_schema_changes = Field(NonRequiredBooleanValueField, required=False)
|
|
103
|
+
|
|
104
|
+
class Meta:
|
|
105
|
+
description = "InfrahubBranch"
|
|
106
|
+
name = "InfrahubBranch"
|
|
107
|
+
|
|
108
|
+
@staticmethod
|
|
109
|
+
async def _map_fields_to_graphql(objs: list[Branch], fields: dict) -> list[dict[str, Any]]:
|
|
110
|
+
field_keys = fields.keys()
|
|
111
|
+
result: list[dict[str, Any]] = []
|
|
112
|
+
for obj in objs:
|
|
113
|
+
if obj.name == GLOBAL_BRANCH_NAME:
|
|
114
|
+
continue
|
|
115
|
+
data: dict[str, Any] = {}
|
|
116
|
+
for field in field_keys:
|
|
117
|
+
if field == "id":
|
|
118
|
+
data["id"] = obj.uuid
|
|
119
|
+
continue
|
|
120
|
+
value = getattr(obj, field, None)
|
|
121
|
+
if isinstance(fields.get(field), dict):
|
|
122
|
+
data[field] = {"value": value}
|
|
123
|
+
else:
|
|
124
|
+
data[field] = value
|
|
125
|
+
result.append(data)
|
|
126
|
+
return result
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class InfrahubBranchEdge(InfrahubObjectType):
|
|
130
|
+
node = Field(InfrahubBranch, required=True)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class InfrahubBranchType(InfrahubObjectType):
|
|
134
|
+
count = Field(Int, description="Total number of items")
|
|
135
|
+
edges = Field(NonNull(List(of_type=NonNull(InfrahubBranchEdge))))
|
|
136
|
+
default_branch = Field(
|
|
137
|
+
InfrahubBranch,
|
|
138
|
+
required=True,
|
|
139
|
+
description="The default branch of the Infrahub instance, provides a direct way to access the default branch regardless of filters.",
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
@classmethod
|
|
143
|
+
async def get_list_count(cls, graphql_context: GraphqlContext, **kwargs: Any) -> int:
|
|
144
|
+
async with graphql_context.db.start_session(read_only=True) as db:
|
|
145
|
+
return await Branch.get_list_count(db=db, **kwargs)
|
infrahub/lock.py
CHANGED
|
@@ -58,7 +58,7 @@ class InfrahubMultiLock:
|
|
|
58
58
|
self.locks = locks or []
|
|
59
59
|
self.metrics = metrics
|
|
60
60
|
|
|
61
|
-
async def __aenter__(self):
|
|
61
|
+
async def __aenter__(self) -> None:
|
|
62
62
|
await self.acquire()
|
|
63
63
|
|
|
64
64
|
async def __aexit__(
|
|
@@ -66,7 +66,7 @@ class InfrahubMultiLock:
|
|
|
66
66
|
exc_type: type[BaseException] | None,
|
|
67
67
|
exc_value: BaseException | None,
|
|
68
68
|
traceback: TracebackType | None,
|
|
69
|
-
):
|
|
69
|
+
) -> None:
|
|
70
70
|
await self.release()
|
|
71
71
|
|
|
72
72
|
async def acquire(self) -> None:
|
|
@@ -86,7 +86,7 @@ class NATSLock:
|
|
|
86
86
|
self.token = None
|
|
87
87
|
self.service = service
|
|
88
88
|
|
|
89
|
-
async def __aenter__(self):
|
|
89
|
+
async def __aenter__(self) -> None:
|
|
90
90
|
await self.acquire()
|
|
91
91
|
|
|
92
92
|
async def __aexit__(
|
|
@@ -94,7 +94,7 @@ class NATSLock:
|
|
|
94
94
|
exc_type: type[BaseException] | None,
|
|
95
95
|
exc_value: BaseException | None,
|
|
96
96
|
traceback: TracebackType | None,
|
|
97
|
-
):
|
|
97
|
+
) -> None:
|
|
98
98
|
await self.release()
|
|
99
99
|
|
|
100
100
|
async def acquire(self) -> None:
|
|
@@ -162,7 +162,7 @@ class InfrahubLock:
|
|
|
162
162
|
def acquire_time(self, value: int) -> None:
|
|
163
163
|
self._acquire_time = value
|
|
164
164
|
|
|
165
|
-
async def __aenter__(self):
|
|
165
|
+
async def __aenter__(self) -> None:
|
|
166
166
|
await self.acquire()
|
|
167
167
|
|
|
168
168
|
async def __aexit__(
|
|
@@ -170,7 +170,7 @@ class InfrahubLock:
|
|
|
170
170
|
exc_type: type[BaseException] | None,
|
|
171
171
|
exc_value: BaseException | None,
|
|
172
172
|
traceback: TracebackType | None,
|
|
173
|
-
):
|
|
173
|
+
) -> None:
|
|
174
174
|
await self.release()
|
|
175
175
|
|
|
176
176
|
async def acquire(self) -> None:
|
infrahub/patch/constants.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from enum import
|
|
1
|
+
from enum import StrEnum
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class PatchPlanFilename(
|
|
4
|
+
class PatchPlanFilename(StrEnum):
|
|
5
5
|
VERTICES_TO_ADD = "vertices_to_add.json"
|
|
6
6
|
VERTICES_TO_UPDATE = "vertices_to_update.json"
|
|
7
7
|
VERTICES_TO_DELETE = "vertices_to_delete.json"
|
infrahub/task_manager/task.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import hashlib
|
|
3
3
|
import json
|
|
4
|
-
from datetime import datetime, timedelta
|
|
4
|
+
from datetime import UTC, datetime, timedelta
|
|
5
5
|
from typing import Any
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
@@ -353,7 +353,7 @@ class PrefectTask:
|
|
|
353
353
|
logger = get_logger()
|
|
354
354
|
|
|
355
355
|
async with get_client(sync_client=False) as client:
|
|
356
|
-
cutoff = datetime.now(
|
|
356
|
+
cutoff = datetime.now(UTC) - timedelta(days=days_to_keep)
|
|
357
357
|
|
|
358
358
|
flow_run_filter = FlowRunFilter(
|
|
359
359
|
start_time=FlowRunFilterStartTime(before_=cutoff), # type: ignore[arg-type]
|
infrahub/telemetry/constants.py
CHANGED
infrahub/trigger/models.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from datetime import timedelta
|
|
4
|
-
from enum import
|
|
4
|
+
from enum import StrEnum
|
|
5
5
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
6
6
|
|
|
7
7
|
from prefect.events.actions import RunDeployment
|
|
@@ -92,7 +92,7 @@ class TriggerSetupReport(BaseModel):
|
|
|
92
92
|
return created + updated
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
class TriggerType(
|
|
95
|
+
class TriggerType(StrEnum):
|
|
96
96
|
ACTION_TRIGGER_RULE = "action_trigger_rule"
|
|
97
97
|
BUILTIN = "builtin"
|
|
98
98
|
WEBHOOK = "webhook"
|
infrahub/utils.py
CHANGED
|
@@ -76,7 +76,7 @@ def get_nested_dict(nested_dict: dict[str, Any], keys: list[str]) -> dict[str, A
|
|
|
76
76
|
return current_level if isinstance(current_level, dict) else {}
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
def get_all_subclasses(cls: AnyClass) -> list[AnyClass]:
|
|
79
|
+
def get_all_subclasses[AnyClass: type](cls: AnyClass) -> list[AnyClass]:
|
|
80
80
|
"""Recursively get all subclasses of the given class."""
|
|
81
81
|
subclasses: list[AnyClass] = []
|
|
82
82
|
for subclass in cls.__subclasses__():
|
infrahub/validators/tasks.py
CHANGED
|
@@ -12,7 +12,7 @@ from .events import send_start_validator
|
|
|
12
12
|
ValidatorType = TypeVar("ValidatorType", bound=CoreValidator)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
async def start_validator(
|
|
15
|
+
async def start_validator[ValidatorType: CoreValidator](
|
|
16
16
|
client: InfrahubClient,
|
|
17
17
|
validator: CoreValidator | None,
|
|
18
18
|
validator_type: type[ValidatorType],
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import logging
|
|
2
3
|
import os
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
from typing import Any
|
|
4
6
|
|
|
5
7
|
import typer
|
|
@@ -122,6 +124,7 @@ class InfrahubWorkerAsync(BaseWorker):
|
|
|
122
124
|
)
|
|
123
125
|
|
|
124
126
|
set_component_type(component_type=self.component_type)
|
|
127
|
+
await self.set_git_global_config()
|
|
125
128
|
await self._init_services(client=client)
|
|
126
129
|
|
|
127
130
|
if not registry.schema_has_been_initialized():
|
|
@@ -204,3 +207,37 @@ class InfrahubWorkerAsync(BaseWorker):
|
|
|
204
207
|
)
|
|
205
208
|
|
|
206
209
|
self.service = service
|
|
210
|
+
|
|
211
|
+
async def set_git_global_config(self) -> None:
|
|
212
|
+
global_config_file = config.SETTINGS.git.global_config_file
|
|
213
|
+
if not os.getenv("GIT_CONFIG_GLOBAL") and global_config_file:
|
|
214
|
+
config_dir = Path(global_config_file).parent
|
|
215
|
+
try:
|
|
216
|
+
config_dir.mkdir(exist_ok=True, parents=True)
|
|
217
|
+
except FileExistsError:
|
|
218
|
+
pass
|
|
219
|
+
os.environ["GIT_CONFIG_GLOBAL"] = global_config_file
|
|
220
|
+
self._logger.info(f"Set git config file to {global_config_file}")
|
|
221
|
+
|
|
222
|
+
await self._run_git_config_global(config.SETTINGS.git.user_name, setting_name="user.name")
|
|
223
|
+
await self._run_git_config_global(config.SETTINGS.git.user_email, setting_name="user.email")
|
|
224
|
+
await self._run_git_config_global("'*'", "--replace-all", setting_name="safe.directory")
|
|
225
|
+
await self._run_git_config_global("true", setting_name="credential.usehttppath")
|
|
226
|
+
await self._run_git_config_global(config.SETTINGS.dev.git_credential_helper, setting_name="credential.helper")
|
|
227
|
+
|
|
228
|
+
async def _run_git_config_global(self, *args: str, setting_name: str) -> None:
|
|
229
|
+
proc = await asyncio.create_subprocess_exec(
|
|
230
|
+
"git",
|
|
231
|
+
"config",
|
|
232
|
+
"--global",
|
|
233
|
+
setting_name,
|
|
234
|
+
*args,
|
|
235
|
+
stdout=asyncio.subprocess.PIPE,
|
|
236
|
+
stderr=asyncio.subprocess.PIPE,
|
|
237
|
+
)
|
|
238
|
+
_, stderr = await proc.communicate()
|
|
239
|
+
if proc.returncode != 0:
|
|
240
|
+
error_msg = stderr.decode("utf-8", errors="ignore").strip() or "unknown error"
|
|
241
|
+
self._logger.error(f"Failed to set git {setting_name}: %s", error_msg)
|
|
242
|
+
else:
|
|
243
|
+
self._logger.info(f"Git {setting_name} set")
|
infrahub_sdk/async_typer.py
CHANGED
infrahub_sdk/batch.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
-
from collections.abc import AsyncGenerator, Awaitable, Generator
|
|
4
|
+
from collections.abc import AsyncGenerator, Awaitable, Callable, Generator
|
|
5
5
|
from concurrent.futures import ThreadPoolExecutor
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from .node import InfrahubNode, InfrahubNodeSync
|
infrahub_sdk/client.py
CHANGED
|
@@ -5,14 +5,13 @@ import copy
|
|
|
5
5
|
import logging
|
|
6
6
|
import time
|
|
7
7
|
import warnings
|
|
8
|
-
from collections.abc import Coroutine, Mapping, MutableMapping
|
|
8
|
+
from collections.abc import Callable, Coroutine, Mapping, MutableMapping
|
|
9
9
|
from datetime import datetime
|
|
10
10
|
from functools import wraps
|
|
11
11
|
from time import sleep
|
|
12
12
|
from typing import (
|
|
13
13
|
TYPE_CHECKING,
|
|
14
14
|
Any,
|
|
15
|
-
Callable,
|
|
16
15
|
Literal,
|
|
17
16
|
TypedDict,
|
|
18
17
|
TypeVar,
|
|
@@ -300,7 +299,7 @@ class BaseClient:
|
|
|
300
299
|
if prefix_length:
|
|
301
300
|
input_data["prefix_length"] = prefix_length
|
|
302
301
|
if member_type:
|
|
303
|
-
if member_type not in
|
|
302
|
+
if member_type not in {"prefix", "address"}:
|
|
304
303
|
raise ValueError("member_type possible values are 'prefix' or 'address'")
|
|
305
304
|
input_data["member_type"] = member_type
|
|
306
305
|
if prefix_type:
|
|
@@ -957,7 +956,7 @@ class InfrahubClient(BaseClient):
|
|
|
957
956
|
try:
|
|
958
957
|
resp = await self._post(url=url, payload=payload, headers=headers, timeout=timeout)
|
|
959
958
|
|
|
960
|
-
if raise_for_error in
|
|
959
|
+
if raise_for_error in {None, True}:
|
|
961
960
|
resp.raise_for_status()
|
|
962
961
|
|
|
963
962
|
retry = False
|
|
@@ -971,7 +970,7 @@ class InfrahubClient(BaseClient):
|
|
|
971
970
|
self.log.error(f"Unable to connect to {self.address} .. ")
|
|
972
971
|
raise
|
|
973
972
|
except httpx.HTTPStatusError as exc:
|
|
974
|
-
if exc.response.status_code in
|
|
973
|
+
if exc.response.status_code in {401, 403}:
|
|
975
974
|
response = decode_json(response=exc.response)
|
|
976
975
|
errors = response.get("errors", [])
|
|
977
976
|
messages = [error.get("message") for error in errors]
|
|
@@ -1209,7 +1208,7 @@ class InfrahubClient(BaseClient):
|
|
|
1209
1208
|
timeout=timeout or self.default_timeout,
|
|
1210
1209
|
)
|
|
1211
1210
|
|
|
1212
|
-
if raise_for_error in
|
|
1211
|
+
if raise_for_error in {None, True}:
|
|
1213
1212
|
resp.raise_for_status()
|
|
1214
1213
|
|
|
1215
1214
|
return decode_json(response=resp)
|
|
@@ -1818,7 +1817,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1818
1817
|
try:
|
|
1819
1818
|
resp = self._post(url=url, payload=payload, headers=headers, timeout=timeout)
|
|
1820
1819
|
|
|
1821
|
-
if raise_for_error in
|
|
1820
|
+
if raise_for_error in {None, True}:
|
|
1822
1821
|
resp.raise_for_status()
|
|
1823
1822
|
|
|
1824
1823
|
retry = False
|
|
@@ -1832,7 +1831,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1832
1831
|
self.log.error(f"Unable to connect to {self.address} .. ")
|
|
1833
1832
|
raise
|
|
1834
1833
|
except httpx.HTTPStatusError as exc:
|
|
1835
|
-
if exc.response.status_code in
|
|
1834
|
+
if exc.response.status_code in {401, 403}:
|
|
1836
1835
|
response = decode_json(response=exc.response)
|
|
1837
1836
|
errors = response.get("errors", [])
|
|
1838
1837
|
messages = [error.get("message") for error in errors]
|
|
@@ -2447,7 +2446,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
2447
2446
|
timeout=timeout or self.default_timeout,
|
|
2448
2447
|
)
|
|
2449
2448
|
|
|
2450
|
-
if raise_for_error in
|
|
2449
|
+
if raise_for_error in {None, True}:
|
|
2451
2450
|
resp.raise_for_status()
|
|
2452
2451
|
|
|
2453
2452
|
return decode_json(response=resp)
|
infrahub_sdk/config.py
CHANGED
|
@@ -173,7 +173,7 @@ class Config(ConfigBase):
|
|
|
173
173
|
# When using structlog the logger doesn't expose the expected methods by looking at the
|
|
174
174
|
# object to pydantic rejects them. This is a workaround to allow structlog to be used
|
|
175
175
|
# as a logger
|
|
176
|
-
return self.log # type: ignore
|
|
176
|
+
return self.log # type: ignore[return-value]
|
|
177
177
|
|
|
178
178
|
@model_validator(mode="before")
|
|
179
179
|
@classmethod
|
|
@@ -194,7 +194,7 @@ class Config(ConfigBase):
|
|
|
194
194
|
"log": self.log,
|
|
195
195
|
}
|
|
196
196
|
covered_keys = list(config.keys())
|
|
197
|
-
for field in Config.model_fields
|
|
197
|
+
for field in Config.model_fields:
|
|
198
198
|
if field not in covered_keys:
|
|
199
199
|
config[field] = deepcopy(getattr(self, field))
|
|
200
200
|
|
infrahub_sdk/ctl/branch.py
CHANGED
|
@@ -49,7 +49,7 @@ async def list_branch(_: str = CONFIG_PARAM) -> None:
|
|
|
49
49
|
table.add_column("Status")
|
|
50
50
|
|
|
51
51
|
# identify the default branch and always print it first
|
|
52
|
-
default_branch =
|
|
52
|
+
default_branch = next(branch for branch in branches.values() if branch.is_default)
|
|
53
53
|
table.add_row(
|
|
54
54
|
default_branch.name,
|
|
55
55
|
default_branch.description or " - ",
|
infrahub_sdk/ctl/cli.py
CHANGED
|
@@ -4,8 +4,8 @@ try:
|
|
|
4
4
|
from .cli_commands import app
|
|
5
5
|
except ImportError as exc:
|
|
6
6
|
sys.exit(
|
|
7
|
-
f"Module {exc.name} is not available, install the 'ctl' extra of the infrahub-sdk package,
|
|
8
|
-
"
|
|
7
|
+
f"Module {exc.name} is not available, install the 'ctl' extra of the infrahub-sdk package, "
|
|
8
|
+
f"`pip install 'infrahub-sdk[ctl]'` or run `uv sync --extra ctl`."
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
__all__ = ["app"]
|
infrahub_sdk/ctl/cli_commands.py
CHANGED
|
@@ -6,8 +6,9 @@ import importlib
|
|
|
6
6
|
import logging
|
|
7
7
|
import platform
|
|
8
8
|
import sys
|
|
9
|
+
from collections.abc import Callable
|
|
9
10
|
from pathlib import Path
|
|
10
|
-
from typing import TYPE_CHECKING, Any,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
11
12
|
|
|
12
13
|
import typer
|
|
13
14
|
import ujson
|
infrahub_sdk/ctl/graphql.py
CHANGED
|
@@ -108,7 +108,7 @@ async def export_schema(
|
|
|
108
108
|
schema_text = await client.schema.get_graphql_schema()
|
|
109
109
|
|
|
110
110
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
111
|
-
destination.write_text(schema_text)
|
|
111
|
+
destination.write_text(schema_text, encoding="utf-8")
|
|
112
112
|
console.print(f"[green]Schema exported to {destination}")
|
|
113
113
|
|
|
114
114
|
|
|
@@ -180,5 +180,5 @@ async def generate_return_types(
|
|
|
180
180
|
|
|
181
181
|
generate_result_types(directory=directory, package=package_generator, fragment=module_fragment)
|
|
182
182
|
|
|
183
|
-
for file_name in package_generator._result_types_files
|
|
183
|
+
for file_name in package_generator._result_types_files:
|
|
184
184
|
console.print(f"[green]Generated {file_name} in {directory}")
|
infrahub_sdk/ctl/importer.py
CHANGED
infrahub_sdk/ctl/utils.py
CHANGED
|
@@ -3,10 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
5
|
import traceback
|
|
6
|
-
from collections.abc import Coroutine
|
|
6
|
+
from collections.abc import Callable, Coroutine
|
|
7
7
|
from functools import wraps
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import TYPE_CHECKING, Any,
|
|
9
|
+
from typing import TYPE_CHECKING, Any, NoReturn, Optional, TypeVar
|
|
10
10
|
|
|
11
11
|
import typer
|
|
12
12
|
from click.exceptions import Exit
|
|
@@ -46,7 +46,7 @@ def init_logging(debug: bool = False) -> None:
|
|
|
46
46
|
|
|
47
47
|
log_level = "DEBUG" if debug else "INFO"
|
|
48
48
|
FORMAT = "%(message)s"
|
|
49
|
-
logging.basicConfig(level=log_level, format=FORMAT, datefmt="[%X]", handlers=[RichHandler()])
|
|
49
|
+
logging.basicConfig(level=log_level, format=FORMAT, datefmt="[%X]", handlers=[RichHandler(show_path=debug)])
|
|
50
50
|
logging.getLogger("infrahubctl")
|
|
51
51
|
|
|
52
52
|
|
infrahub_sdk/node/attribute.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ipaddress
|
|
4
|
-
from
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from typing import TYPE_CHECKING, Any, get_args
|
|
5
6
|
|
|
6
7
|
from ..protocols_base import CoreNodeBase
|
|
7
8
|
from ..uuidt import UUIDT
|
|
@@ -25,7 +26,7 @@ class Attribute:
|
|
|
25
26
|
self.name = name
|
|
26
27
|
self._schema = schema
|
|
27
28
|
|
|
28
|
-
if not isinstance(data, dict) or "value" not in data
|
|
29
|
+
if not isinstance(data, dict) or "value" not in data:
|
|
29
30
|
data = {"value": data}
|
|
30
31
|
|
|
31
32
|
self._properties_flag = PROPERTIES_FLAG
|
|
@@ -34,12 +35,12 @@ class Attribute:
|
|
|
34
35
|
|
|
35
36
|
self._read_only = ["updated_at", "is_inherited"]
|
|
36
37
|
|
|
37
|
-
self.id: str | None = data.get("id"
|
|
38
|
+
self.id: str | None = data.get("id")
|
|
38
39
|
|
|
39
|
-
self._value: Any | None = data.get("value"
|
|
40
|
+
self._value: Any | None = data.get("value")
|
|
40
41
|
self.value_has_been_mutated = False
|
|
41
|
-
self.is_default: bool | None = data.get("is_default"
|
|
42
|
-
self.is_from_profile: bool | None = data.get("is_from_profile"
|
|
42
|
+
self.is_default: bool | None = data.get("is_default")
|
|
43
|
+
self.is_from_profile: bool | None = data.get("is_from_profile")
|
|
43
44
|
|
|
44
45
|
if self._value:
|
|
45
46
|
value_mapper: dict[str, Callable] = {
|
|
@@ -49,11 +50,11 @@ class Attribute:
|
|
|
49
50
|
mapper = value_mapper.get(schema.kind, lambda value: value)
|
|
50
51
|
self._value = mapper(data.get("value"))
|
|
51
52
|
|
|
52
|
-
self.is_inherited: bool | None = data.get("is_inherited"
|
|
53
|
-
self.updated_at: str | None = data.get("updated_at"
|
|
53
|
+
self.is_inherited: bool | None = data.get("is_inherited")
|
|
54
|
+
self.updated_at: str | None = data.get("updated_at")
|
|
54
55
|
|
|
55
|
-
self.is_visible: bool | None = data.get("is_visible"
|
|
56
|
-
self.is_protected: bool | None = data.get("is_protected"
|
|
56
|
+
self.is_visible: bool | None = data.get("is_visible")
|
|
57
|
+
self.is_protected: bool | None = data.get("is_protected")
|
|
57
58
|
|
|
58
59
|
self.source: NodeProperty | None = None
|
|
59
60
|
self.owner: NodeProperty | None = None
|
infrahub_sdk/node/constants.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import ipaddress
|
|
2
2
|
import re
|
|
3
|
-
from typing import Union
|
|
4
3
|
|
|
5
4
|
PROPERTIES_FLAG = ["is_visible", "is_protected"]
|
|
6
5
|
PROPERTIES_OBJECT = ["source", "owner"]
|
|
7
6
|
SAFE_VALUE = re.compile(r"(^[\. /:a-zA-Z0-9_-]+$)|(^$)")
|
|
8
7
|
|
|
9
|
-
IP_TYPES =
|
|
8
|
+
IP_TYPES = ipaddress.IPv4Interface | ipaddress.IPv6Interface | ipaddress.IPv4Network | ipaddress.IPv6Network
|
|
10
9
|
|
|
11
10
|
ARTIFACT_FETCH_FEATURE_NOT_SUPPORTED_MESSAGE = (
|
|
12
11
|
"calling artifact_fetch is only supported for nodes that are Artifact Definition target"
|