infrahub-server 1.2.0b1__py3-none-any.whl → 1.2.1__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/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +1 -3
- infrahub/artifacts/tasks.py +1 -3
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +239 -11
- infrahub/computed_attribute/tasks.py +77 -442
- infrahub/computed_attribute/triggers.py +11 -45
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +57 -57
- infrahub/core/branch/tasks.py +12 -9
- infrahub/core/changelog/diff.py +16 -8
- infrahub/core/changelog/models.py +189 -26
- infrahub/core/constants/__init__.py +5 -1
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +3 -3
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +34 -34
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +9 -4
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/{m020_add_generate_template_attr.py → m022_add_generate_template_attr.py} +3 -3
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +18 -21
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +29 -28
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +5 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +24 -24
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +40 -46
- infrahub/core/schema/attribute_schema.py +9 -9
- infrahub/core/schema/basenode_schema.py +93 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +13 -19
- infrahub/core/schema/definitions/core/account.py +151 -148
- infrahub/core/schema/definitions/core/artifact.py +122 -113
- infrahub/core/schema/definitions/core/builtin.py +19 -16
- infrahub/core/schema/definitions/core/check.py +61 -53
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +89 -85
- infrahub/core/schema/definitions/core/graphql_query.py +72 -70
- infrahub/core/schema/definitions/core/group.py +96 -93
- infrahub/core/schema/definitions/core/ipam.py +176 -235
- infrahub/core/schema/definitions/core/lineage.py +18 -16
- infrahub/core/schema/definitions/core/menu.py +42 -40
- infrahub/core/schema/definitions/core/permission.py +144 -142
- infrahub/core/schema/definitions/core/profile.py +16 -27
- infrahub/core/schema/definitions/core/propose_change.py +88 -79
- infrahub/core/schema/definitions/core/propose_change_comment.py +170 -165
- infrahub/core/schema/definitions/core/propose_change_validator.py +290 -288
- infrahub/core/schema/definitions/core/repository.py +231 -225
- infrahub/core/schema/definitions/core/resource_pool.py +156 -166
- infrahub/core/schema/definitions/core/template.py +27 -12
- infrahub/core/schema/definitions/core/transform.py +85 -76
- infrahub/core/schema/definitions/core/webhook.py +127 -101
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +7 -7
- infrahub/core/schema/schema_branch.py +276 -138
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +26 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +13 -25
- infrahub/events/branch_action.py +26 -18
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +10 -24
- infrahub/events/models.py +10 -16
- infrahub/events/node_action.py +87 -32
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +23 -24
- infrahub/generators/models.py +1 -3
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +26 -25
- infrahub/git/models.py +22 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +67 -49
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +6 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +13 -10
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/computed_attribute.py +4 -5
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +50 -70
- infrahub/graphql/mutations/main.py +164 -141
- infrahub/graphql/mutations/menu.py +5 -5
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +67 -35
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +4 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/queries/diff/tree.py +4 -4
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/event.py +20 -11
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/menu/generator.py +7 -7
- infrahub/menu/menu.py +0 -10
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/messages/__init__.py +1 -11
- infrahub/message_bus/messages/check_generator_run.py +2 -0
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/operations/__init__.py +0 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/generator_definition.py +19 -19
- infrahub/message_bus/operations/requests/proposed_change.py +3 -1
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/tasks.py +37 -28
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +1 -2
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/task_manager/event.py +23 -9
- infrahub/tasks/artifact.py +2 -4
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +2 -5
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +14 -1
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -90
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +22 -5
- infrahub/webhook/tasks.py +44 -19
- infrahub/webhook/triggers.py +22 -5
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +28 -20
- infrahub/workflows/initialization.py +1 -3
- infrahub/workflows/models.py +1 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +27 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +69 -20
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +10 -0
- infrahub_sdk/task/manager.py +12 -6
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +12 -4
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +3 -2
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +289 -260
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
infrahub_sdk/client.py
CHANGED
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import copy
|
|
5
5
|
import logging
|
|
6
|
+
import time
|
|
6
7
|
from collections.abc import Coroutine, MutableMapping
|
|
7
8
|
from functools import wraps
|
|
8
9
|
from time import sleep
|
|
@@ -38,6 +39,7 @@ from .exceptions import (
|
|
|
38
39
|
NodeNotFoundError,
|
|
39
40
|
ServerNotReachableError,
|
|
40
41
|
ServerNotResponsiveError,
|
|
42
|
+
URLNotFoundError,
|
|
41
43
|
)
|
|
42
44
|
from .graphql import Mutation, Query
|
|
43
45
|
from .node import (
|
|
@@ -58,6 +60,8 @@ from .utils import decode_json, get_user_permissions, is_valid_uuid
|
|
|
58
60
|
if TYPE_CHECKING:
|
|
59
61
|
from types import TracebackType
|
|
60
62
|
|
|
63
|
+
from .context import RequestContext
|
|
64
|
+
|
|
61
65
|
|
|
62
66
|
SchemaType = TypeVar("SchemaType", bound=CoreNode)
|
|
63
67
|
SchemaTypeSync = TypeVar("SchemaTypeSync", bound=CoreNodeSync)
|
|
@@ -139,6 +143,7 @@ class BaseClient:
|
|
|
139
143
|
self.identifier = self.config.identifier
|
|
140
144
|
self.group_context: InfrahubGroupContext | InfrahubGroupContextSync
|
|
141
145
|
self._initialize()
|
|
146
|
+
self._request_context: RequestContext | None = None
|
|
142
147
|
|
|
143
148
|
def _initialize(self) -> None:
|
|
144
149
|
"""Sets the properties for each version of the client"""
|
|
@@ -153,6 +158,14 @@ class BaseClient:
|
|
|
153
158
|
if variables:
|
|
154
159
|
print(f"VARIABLES:\n{ujson.dumps(variables, indent=4)}\n")
|
|
155
160
|
|
|
161
|
+
@property
|
|
162
|
+
def request_context(self) -> RequestContext | None:
|
|
163
|
+
return self._request_context
|
|
164
|
+
|
|
165
|
+
@request_context.setter
|
|
166
|
+
def request_context(self, request_context: RequestContext) -> None:
|
|
167
|
+
self._request_context = request_context
|
|
168
|
+
|
|
156
169
|
def start_tracking(
|
|
157
170
|
self,
|
|
158
171
|
identifier: str | None = None,
|
|
@@ -457,7 +470,7 @@ class InfrahubClient(BaseClient):
|
|
|
457
470
|
hfid: list[str] | None = None,
|
|
458
471
|
include: list[str] | None = None,
|
|
459
472
|
exclude: list[str] | None = None,
|
|
460
|
-
populate_store: bool =
|
|
473
|
+
populate_store: bool = True,
|
|
461
474
|
fragment: bool = False,
|
|
462
475
|
prefetch_relationships: bool = False,
|
|
463
476
|
property: bool = False,
|
|
@@ -611,7 +624,7 @@ class InfrahubClient(BaseClient):
|
|
|
611
624
|
at: Timestamp | None = None,
|
|
612
625
|
branch: str | None = None,
|
|
613
626
|
timeout: int | None = None,
|
|
614
|
-
populate_store: bool =
|
|
627
|
+
populate_store: bool = True,
|
|
615
628
|
offset: int | None = None,
|
|
616
629
|
limit: int | None = None,
|
|
617
630
|
include: list[str] | None = None,
|
|
@@ -707,7 +720,7 @@ class InfrahubClient(BaseClient):
|
|
|
707
720
|
at: Timestamp | None = None,
|
|
708
721
|
branch: str | None = None,
|
|
709
722
|
timeout: int | None = None,
|
|
710
|
-
populate_store: bool =
|
|
723
|
+
populate_store: bool = True,
|
|
711
724
|
offset: int | None = None,
|
|
712
725
|
limit: int | None = None,
|
|
713
726
|
include: list[str] | None = None,
|
|
@@ -880,7 +893,8 @@ class InfrahubClient(BaseClient):
|
|
|
880
893
|
|
|
881
894
|
retry = True
|
|
882
895
|
resp = None
|
|
883
|
-
|
|
896
|
+
start_time = time.time()
|
|
897
|
+
while retry and time.time() - start_time < self.config.max_retry_duration:
|
|
884
898
|
retry = self.retry_on_failure
|
|
885
899
|
try:
|
|
886
900
|
resp = await self._post(url=url, payload=payload, headers=headers, timeout=timeout)
|
|
@@ -904,6 +918,8 @@ class InfrahubClient(BaseClient):
|
|
|
904
918
|
errors = response.get("errors", [])
|
|
905
919
|
messages = [error.get("message") for error in errors]
|
|
906
920
|
raise AuthenticationError(" | ".join(messages)) from exc
|
|
921
|
+
if exc.response.status_code == 404:
|
|
922
|
+
raise URLNotFoundError(url=url)
|
|
907
923
|
|
|
908
924
|
if not resp:
|
|
909
925
|
raise Error("Unexpected situation, resp hasn't been initialized.")
|
|
@@ -1621,7 +1637,8 @@ class InfrahubClientSync(BaseClient):
|
|
|
1621
1637
|
|
|
1622
1638
|
retry = True
|
|
1623
1639
|
resp = None
|
|
1624
|
-
|
|
1640
|
+
start_time = time.time()
|
|
1641
|
+
while retry and time.time() - start_time < self.config.max_retry_duration:
|
|
1625
1642
|
retry = self.retry_on_failure
|
|
1626
1643
|
try:
|
|
1627
1644
|
resp = self._post(url=url, payload=payload, headers=headers, timeout=timeout)
|
|
@@ -1645,6 +1662,8 @@ class InfrahubClientSync(BaseClient):
|
|
|
1645
1662
|
errors = response.get("errors", [])
|
|
1646
1663
|
messages = [error.get("message") for error in errors]
|
|
1647
1664
|
raise AuthenticationError(" | ".join(messages)) from exc
|
|
1665
|
+
if exc.response.status_code == 404:
|
|
1666
|
+
raise URLNotFoundError(url=url)
|
|
1648
1667
|
|
|
1649
1668
|
if not resp:
|
|
1650
1669
|
raise Error("Unexpected situation, resp hasn't been initialized.")
|
|
@@ -1726,7 +1745,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1726
1745
|
at: Timestamp | None = None,
|
|
1727
1746
|
branch: str | None = None,
|
|
1728
1747
|
timeout: int | None = None,
|
|
1729
|
-
populate_store: bool =
|
|
1748
|
+
populate_store: bool = True,
|
|
1730
1749
|
offset: int | None = None,
|
|
1731
1750
|
limit: int | None = None,
|
|
1732
1751
|
include: list[str] | None = None,
|
|
@@ -1857,7 +1876,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
1857
1876
|
at: Timestamp | None = None,
|
|
1858
1877
|
branch: str | None = None,
|
|
1859
1878
|
timeout: int | None = None,
|
|
1860
|
-
populate_store: bool =
|
|
1879
|
+
populate_store: bool = True,
|
|
1861
1880
|
offset: int | None = None,
|
|
1862
1881
|
limit: int | None = None,
|
|
1863
1882
|
include: list[str] | None = None,
|
|
@@ -2110,7 +2129,7 @@ class InfrahubClientSync(BaseClient):
|
|
|
2110
2129
|
hfid: list[str] | None = None,
|
|
2111
2130
|
include: list[str] | None = None,
|
|
2112
2131
|
exclude: list[str] | None = None,
|
|
2113
|
-
populate_store: bool =
|
|
2132
|
+
populate_store: bool = True,
|
|
2114
2133
|
fragment: bool = False,
|
|
2115
2134
|
prefetch_relationships: bool = False,
|
|
2116
2135
|
property: bool = False,
|
infrahub_sdk/config.py
CHANGED
|
@@ -56,6 +56,9 @@ class ConfigBase(BaseSettings):
|
|
|
56
56
|
pagination_size: int = Field(default=50, description="Page size for queries to the server")
|
|
57
57
|
retry_delay: int = Field(default=5, description="Number of seconds to wait until attempting a retry.")
|
|
58
58
|
retry_on_failure: bool = Field(default=False, description="Retry operation in case of failure")
|
|
59
|
+
max_retry_duration: int = Field(
|
|
60
|
+
default=300, description="Maximum duration until we stop attempting to retry if enabled."
|
|
61
|
+
)
|
|
59
62
|
schema_converge_timeout: int = Field(
|
|
60
63
|
default=60, description="Number of seconds to wait for schema to have converged"
|
|
61
64
|
)
|
infrahub_sdk/context.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ContextAccount(BaseModel):
|
|
7
|
+
id: str = Field(..., description="The ID of the account")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RequestContext(BaseModel):
|
|
11
|
+
"""The context can be used to override settings such as the account within mutations."""
|
|
12
|
+
|
|
13
|
+
account: ContextAccount | None = Field(default=None, description="Account tied to the context")
|
infrahub_sdk/exceptions.py
CHANGED
|
@@ -121,6 +121,12 @@ class AuthenticationError(Error):
|
|
|
121
121
|
super().__init__(self.message)
|
|
122
122
|
|
|
123
123
|
|
|
124
|
+
class URLNotFoundError(Error):
|
|
125
|
+
def __init__(self, url: str):
|
|
126
|
+
self.message = f"`{url}` not found."
|
|
127
|
+
super().__init__(self.message)
|
|
128
|
+
|
|
129
|
+
|
|
124
130
|
class FeatureNotSupportedError(Error):
|
|
125
131
|
"""Raised when trying to use a method on a node that doesn't support it."""
|
|
126
132
|
|
infrahub_sdk/generator.py
CHANGED
|
@@ -11,6 +11,7 @@ from .exceptions import UninitializedError
|
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from .client import InfrahubClient
|
|
14
|
+
from .context import RequestContext
|
|
14
15
|
from .node import InfrahubNode
|
|
15
16
|
from .store import NodeStore
|
|
16
17
|
|
|
@@ -29,6 +30,7 @@ class InfrahubGenerator:
|
|
|
29
30
|
params: dict | None = None,
|
|
30
31
|
convert_query_response: bool = False,
|
|
31
32
|
logger: logging.Logger | None = None,
|
|
33
|
+
request_context: RequestContext | None = None,
|
|
32
34
|
) -> None:
|
|
33
35
|
self.query = query
|
|
34
36
|
self.branch = branch
|
|
@@ -44,6 +46,7 @@ class InfrahubGenerator:
|
|
|
44
46
|
self.infrahub_node = infrahub_node
|
|
45
47
|
self.convert_query_response = convert_query_response
|
|
46
48
|
self.logger = logger if logger else logging.getLogger("infrahub.tasks")
|
|
49
|
+
self.request_context = request_context
|
|
47
50
|
|
|
48
51
|
@property
|
|
49
52
|
def store(self) -> NodeStore:
|
|
@@ -122,7 +125,7 @@ class InfrahubGenerator:
|
|
|
122
125
|
await self._init_client.schema.all(branch=self.branch_name)
|
|
123
126
|
|
|
124
127
|
for kind in data:
|
|
125
|
-
if kind in self._init_client.schema.cache[self.branch_name]:
|
|
128
|
+
if kind in self._init_client.schema.cache[self.branch_name].nodes.keys():
|
|
126
129
|
for result in data[kind].get("edges", []):
|
|
127
130
|
node = await self.infrahub_node.from_graphql(
|
|
128
131
|
client=self._init_client, branch=self.branch_name, data=result
|
infrahub_sdk/graphql.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from enum import Enum
|
|
3
4
|
from typing import Any
|
|
4
5
|
|
|
5
6
|
from pydantic import BaseModel
|
|
@@ -7,19 +8,30 @@ from pydantic import BaseModel
|
|
|
7
8
|
VARIABLE_TYPE_MAPPING = ((str, "String!"), (int, "Int!"), (float, "Float!"), (bool, "Boolean!"))
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
def convert_to_graphql_as_string(value: str | bool | list) -> str:
|
|
11
|
+
def convert_to_graphql_as_string(value: str | bool | list | BaseModel | Enum | Any, convert_enum: bool = False) -> str: # noqa: PLR0911
|
|
11
12
|
if isinstance(value, str) and value.startswith("$"):
|
|
12
13
|
return value
|
|
14
|
+
if isinstance(value, Enum):
|
|
15
|
+
if convert_enum:
|
|
16
|
+
return convert_to_graphql_as_string(value=value.value, convert_enum=True)
|
|
17
|
+
return value.name
|
|
13
18
|
if isinstance(value, str):
|
|
14
19
|
return f'"{value}"'
|
|
15
20
|
if isinstance(value, bool):
|
|
16
21
|
return repr(value).lower()
|
|
17
22
|
if isinstance(value, list):
|
|
18
|
-
values_as_string = [convert_to_graphql_as_string(item) for item in value]
|
|
23
|
+
values_as_string = [convert_to_graphql_as_string(value=item, convert_enum=convert_enum) for item in value]
|
|
19
24
|
return "[" + ", ".join(values_as_string) + "]"
|
|
20
25
|
if isinstance(value, BaseModel):
|
|
21
26
|
data = value.model_dump()
|
|
22
|
-
return
|
|
27
|
+
return (
|
|
28
|
+
"{ "
|
|
29
|
+
+ ", ".join(
|
|
30
|
+
f"{key}: {convert_to_graphql_as_string(value=val, convert_enum=convert_enum)}"
|
|
31
|
+
for key, val in data.items()
|
|
32
|
+
)
|
|
33
|
+
+ " }"
|
|
34
|
+
)
|
|
23
35
|
|
|
24
36
|
return str(value)
|
|
25
37
|
|
|
@@ -38,7 +50,7 @@ def render_variables_to_string(data: dict[str, type[str | int | float | bool]])
|
|
|
38
50
|
return ", ".join([f"{key}: {value}" for key, value in vars_dict.items()])
|
|
39
51
|
|
|
40
52
|
|
|
41
|
-
def render_query_block(data: dict, offset: int = 4, indentation: int = 4) -> list[str]:
|
|
53
|
+
def render_query_block(data: dict, offset: int = 4, indentation: int = 4, convert_enum: bool = False) -> list[str]:
|
|
42
54
|
FILTERS_KEY = "@filters"
|
|
43
55
|
ALIAS_KEY = "@alias"
|
|
44
56
|
KEYWORDS_TO_SKIP = [FILTERS_KEY, ALIAS_KEY]
|
|
@@ -60,25 +72,36 @@ def render_query_block(data: dict, offset: int = 4, indentation: int = 4) -> lis
|
|
|
60
72
|
|
|
61
73
|
if value.get(FILTERS_KEY):
|
|
62
74
|
filters_str = ", ".join(
|
|
63
|
-
[
|
|
75
|
+
[
|
|
76
|
+
f"{key2}: {convert_to_graphql_as_string(value=value2, convert_enum=convert_enum)}"
|
|
77
|
+
for key2, value2 in value[FILTERS_KEY].items()
|
|
78
|
+
]
|
|
64
79
|
)
|
|
65
80
|
lines.append(f"{offset_str}{key_str}({filters_str}) " + "{")
|
|
66
81
|
else:
|
|
67
82
|
lines.append(f"{offset_str}{key_str} " + "{")
|
|
68
83
|
|
|
69
|
-
lines.extend(
|
|
84
|
+
lines.extend(
|
|
85
|
+
render_query_block(
|
|
86
|
+
data=value, offset=offset + indentation, indentation=indentation, convert_enum=convert_enum
|
|
87
|
+
)
|
|
88
|
+
)
|
|
70
89
|
lines.append(offset_str + "}")
|
|
71
90
|
|
|
72
91
|
return lines
|
|
73
92
|
|
|
74
93
|
|
|
75
|
-
def render_input_block(data: dict, offset: int = 4, indentation: int = 4) -> list[str]:
|
|
94
|
+
def render_input_block(data: dict, offset: int = 4, indentation: int = 4, convert_enum: bool = False) -> list[str]:
|
|
76
95
|
offset_str = " " * offset
|
|
77
96
|
lines = []
|
|
78
97
|
for key, value in data.items():
|
|
79
98
|
if isinstance(value, dict):
|
|
80
99
|
lines.append(f"{offset_str}{key}: " + "{")
|
|
81
|
-
lines.extend(
|
|
100
|
+
lines.extend(
|
|
101
|
+
render_input_block(
|
|
102
|
+
data=value, offset=offset + indentation, indentation=indentation, convert_enum=convert_enum
|
|
103
|
+
)
|
|
104
|
+
)
|
|
82
105
|
lines.append(offset_str + "}")
|
|
83
106
|
elif isinstance(value, list):
|
|
84
107
|
lines.append(f"{offset_str}{key}: " + "[")
|
|
@@ -90,14 +113,17 @@ def render_input_block(data: dict, offset: int = 4, indentation: int = 4) -> lis
|
|
|
90
113
|
data=item,
|
|
91
114
|
offset=offset + indentation + indentation,
|
|
92
115
|
indentation=indentation,
|
|
116
|
+
convert_enum=convert_enum,
|
|
93
117
|
)
|
|
94
118
|
)
|
|
95
119
|
lines.append(f"{offset_str}{' ' * indentation}" + "},")
|
|
96
120
|
else:
|
|
97
|
-
lines.append(
|
|
121
|
+
lines.append(
|
|
122
|
+
f"{offset_str}{' ' * indentation}{convert_to_graphql_as_string(value=item, convert_enum=convert_enum)},"
|
|
123
|
+
)
|
|
98
124
|
lines.append(offset_str + "]")
|
|
99
125
|
else:
|
|
100
|
-
lines.append(f"{offset_str}{key}: {convert_to_graphql_as_string(value)}")
|
|
126
|
+
lines.append(f"{offset_str}{key}: {convert_to_graphql_as_string(value=value, convert_enum=convert_enum)}")
|
|
101
127
|
return lines
|
|
102
128
|
|
|
103
129
|
|
|
@@ -127,9 +153,13 @@ class BaseGraphQLQuery:
|
|
|
127
153
|
class Query(BaseGraphQLQuery):
|
|
128
154
|
query_type = "query"
|
|
129
155
|
|
|
130
|
-
def render(self) -> str:
|
|
156
|
+
def render(self, convert_enum: bool = False) -> str:
|
|
131
157
|
lines = [self.render_first_line()]
|
|
132
|
-
lines.extend(
|
|
158
|
+
lines.extend(
|
|
159
|
+
render_query_block(
|
|
160
|
+
data=self.query, indentation=self.indentation, offset=self.indentation, convert_enum=convert_enum
|
|
161
|
+
)
|
|
162
|
+
)
|
|
133
163
|
lines.append("}")
|
|
134
164
|
|
|
135
165
|
return "\n" + "\n".join(lines) + "\n"
|
|
@@ -143,7 +173,7 @@ class Mutation(BaseGraphQLQuery):
|
|
|
143
173
|
self.mutation = mutation
|
|
144
174
|
super().__init__(*args, **kwargs)
|
|
145
175
|
|
|
146
|
-
def render(self) -> str:
|
|
176
|
+
def render(self, convert_enum: bool = False) -> str:
|
|
147
177
|
lines = [self.render_first_line()]
|
|
148
178
|
lines.append(" " * self.indentation + f"{self.mutation}(")
|
|
149
179
|
lines.extend(
|
|
@@ -151,6 +181,7 @@ class Mutation(BaseGraphQLQuery):
|
|
|
151
181
|
data=self.input_data,
|
|
152
182
|
indentation=self.indentation,
|
|
153
183
|
offset=self.indentation * 2,
|
|
184
|
+
convert_enum=convert_enum,
|
|
154
185
|
)
|
|
155
186
|
)
|
|
156
187
|
lines.append(" " * self.indentation + "){")
|
|
@@ -159,6 +190,7 @@ class Mutation(BaseGraphQLQuery):
|
|
|
159
190
|
data=self.query,
|
|
160
191
|
indentation=self.indentation,
|
|
161
192
|
offset=self.indentation * 2,
|
|
193
|
+
convert_enum=convert_enum,
|
|
162
194
|
)
|
|
163
195
|
)
|
|
164
196
|
lines.append(" " * self.indentation + "}")
|
infrahub_sdk/node.py
CHANGED
|
@@ -22,6 +22,7 @@ if TYPE_CHECKING:
|
|
|
22
22
|
from typing_extensions import Self
|
|
23
23
|
|
|
24
24
|
from .client import InfrahubClient, InfrahubClientSync
|
|
25
|
+
from .context import RequestContext
|
|
25
26
|
from .schema import AttributeSchemaAPI, MainSchemaTypesAPI, RelationshipSchemaAPI
|
|
26
27
|
from .types import Order
|
|
27
28
|
|
|
@@ -187,6 +188,7 @@ class RelatedNodeBase:
|
|
|
187
188
|
if node_data:
|
|
188
189
|
self._id = node_data.get("id", None)
|
|
189
190
|
self._hfid = node_data.get("hfid", None)
|
|
191
|
+
self._kind = node_data.get("kind", None)
|
|
190
192
|
self._display_label = node_data.get("display_label", None)
|
|
191
193
|
self._typename = node_data.get("__typename", None)
|
|
192
194
|
|
|
@@ -255,6 +257,8 @@ class RelatedNodeBase:
|
|
|
255
257
|
data["id"] = self.id
|
|
256
258
|
elif self.hfid is not None:
|
|
257
259
|
data["hfid"] = self.hfid
|
|
260
|
+
if self._kind is not None:
|
|
261
|
+
data["kind"] = self._kind
|
|
258
262
|
|
|
259
263
|
for prop_name in self._properties:
|
|
260
264
|
if getattr(self, prop_name) is not None:
|
|
@@ -766,6 +770,16 @@ class InfrahubNodeBase:
|
|
|
766
770
|
Attribute(name=attr_name, schema=attr_schema, data=attr_data),
|
|
767
771
|
)
|
|
768
772
|
|
|
773
|
+
def _get_request_context(self, request_context: RequestContext | None = None) -> dict[str, Any] | None:
|
|
774
|
+
if request_context:
|
|
775
|
+
return request_context.model_dump(exclude_none=True)
|
|
776
|
+
|
|
777
|
+
client: InfrahubClient | InfrahubClientSync | None = getattr(self, "_client", None)
|
|
778
|
+
if not client or not client.request_context:
|
|
779
|
+
return None
|
|
780
|
+
|
|
781
|
+
return client.request_context.model_dump(exclude_none=True)
|
|
782
|
+
|
|
769
783
|
def _init_relationships(self, data: dict | None = None) -> None:
|
|
770
784
|
pass
|
|
771
785
|
|
|
@@ -794,7 +808,12 @@ class InfrahubNodeBase:
|
|
|
794
808
|
def get_raw_graphql_data(self) -> dict | None:
|
|
795
809
|
return self._data
|
|
796
810
|
|
|
797
|
-
def _generate_input_data(
|
|
811
|
+
def _generate_input_data( # noqa: C901
|
|
812
|
+
self,
|
|
813
|
+
exclude_unmodified: bool = False,
|
|
814
|
+
exclude_hfid: bool = False,
|
|
815
|
+
request_context: RequestContext | None = None,
|
|
816
|
+
) -> dict[str, dict]:
|
|
798
817
|
"""Generate a dictionary that represent the input data required by a mutation.
|
|
799
818
|
|
|
800
819
|
Returns:
|
|
@@ -872,7 +891,15 @@ class InfrahubNodeBase:
|
|
|
872
891
|
elif self.hfid is not None and not exclude_hfid:
|
|
873
892
|
data["hfid"] = self.hfid
|
|
874
893
|
|
|
875
|
-
|
|
894
|
+
mutation_payload = {"data": data}
|
|
895
|
+
if context_data := self._get_request_context(request_context=request_context):
|
|
896
|
+
mutation_payload["context"] = context_data
|
|
897
|
+
|
|
898
|
+
return {
|
|
899
|
+
"data": mutation_payload,
|
|
900
|
+
"variables": variables,
|
|
901
|
+
"mutation_variables": mutation_variables,
|
|
902
|
+
}
|
|
876
903
|
|
|
877
904
|
@staticmethod
|
|
878
905
|
def _strip_unmodified_dict(data: dict, original_data: dict, variables: dict, item: str) -> None:
|
|
@@ -1129,8 +1156,11 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
1129
1156
|
content = await self._client.object_store.get(identifier=artifact.storage_id.value) # type: ignore[attr-defined]
|
|
1130
1157
|
return content
|
|
1131
1158
|
|
|
1132
|
-
async def delete(self, timeout: int | None = None) -> None:
|
|
1159
|
+
async def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None:
|
|
1133
1160
|
input_data = {"data": {"id": self.id}}
|
|
1161
|
+
if context_data := self._get_request_context(request_context=request_context):
|
|
1162
|
+
input_data["context"] = context_data
|
|
1163
|
+
|
|
1134
1164
|
mutation_query = {"ok": None}
|
|
1135
1165
|
query = Mutation(
|
|
1136
1166
|
mutation=f"{self._schema.kind}Delete",
|
|
@@ -1145,12 +1175,16 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
1145
1175
|
)
|
|
1146
1176
|
|
|
1147
1177
|
async def save(
|
|
1148
|
-
self,
|
|
1178
|
+
self,
|
|
1179
|
+
allow_upsert: bool = False,
|
|
1180
|
+
update_group_context: bool | None = None,
|
|
1181
|
+
timeout: int | None = None,
|
|
1182
|
+
request_context: RequestContext | None = None,
|
|
1149
1183
|
) -> None:
|
|
1150
1184
|
if self._existing is False or allow_upsert is True:
|
|
1151
|
-
await self.create(allow_upsert=allow_upsert, timeout=timeout)
|
|
1185
|
+
await self.create(allow_upsert=allow_upsert, timeout=timeout, request_context=request_context)
|
|
1152
1186
|
else:
|
|
1153
|
-
await self.update(timeout=timeout)
|
|
1187
|
+
await self.update(timeout=timeout, request_context=request_context)
|
|
1154
1188
|
|
|
1155
1189
|
if update_group_context is None and self._client.mode == InfrahubClientMode.TRACKING:
|
|
1156
1190
|
update_group_context = True
|
|
@@ -1379,15 +1413,17 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
1379
1413
|
await related_node.fetch(timeout=timeout)
|
|
1380
1414
|
setattr(self, rel_name, related_node)
|
|
1381
1415
|
|
|
1382
|
-
async def create(
|
|
1416
|
+
async def create(
|
|
1417
|
+
self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
|
|
1418
|
+
) -> None:
|
|
1383
1419
|
mutation_query = self._generate_mutation_query()
|
|
1384
1420
|
|
|
1385
1421
|
if allow_upsert:
|
|
1386
|
-
input_data = self._generate_input_data(exclude_hfid=False)
|
|
1422
|
+
input_data = self._generate_input_data(exclude_hfid=False, request_context=request_context)
|
|
1387
1423
|
mutation_name = f"{self._schema.kind}Upsert"
|
|
1388
1424
|
tracker = f"mutation-{str(self._schema.kind).lower()}-upsert"
|
|
1389
1425
|
else:
|
|
1390
|
-
input_data = self._generate_input_data(exclude_hfid=True)
|
|
1426
|
+
input_data = self._generate_input_data(exclude_hfid=True, request_context=request_context)
|
|
1391
1427
|
mutation_name = f"{self._schema.kind}Create"
|
|
1392
1428
|
tracker = f"mutation-{str(self._schema.kind).lower()}-create"
|
|
1393
1429
|
query = Mutation(
|
|
@@ -1405,8 +1441,10 @@ class InfrahubNode(InfrahubNodeBase):
|
|
|
1405
1441
|
)
|
|
1406
1442
|
await self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)
|
|
1407
1443
|
|
|
1408
|
-
async def update(
|
|
1409
|
-
|
|
1444
|
+
async def update(
|
|
1445
|
+
self, do_full_update: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
|
|
1446
|
+
) -> None:
|
|
1447
|
+
input_data = self._generate_input_data(exclude_unmodified=not do_full_update, request_context=request_context)
|
|
1410
1448
|
mutation_query = self._generate_mutation_query()
|
|
1411
1449
|
mutation_name = f"{self._schema.kind}Update"
|
|
1412
1450
|
|
|
@@ -1645,8 +1683,11 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1645
1683
|
content = self._client.object_store.get(identifier=artifact.storage_id.value) # type: ignore[attr-defined]
|
|
1646
1684
|
return content
|
|
1647
1685
|
|
|
1648
|
-
def delete(self, timeout: int | None = None) -> None:
|
|
1686
|
+
def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None:
|
|
1649
1687
|
input_data = {"data": {"id": self.id}}
|
|
1688
|
+
if context_data := self._get_request_context(request_context=request_context):
|
|
1689
|
+
input_data["context"] = context_data
|
|
1690
|
+
|
|
1650
1691
|
mutation_query = {"ok": None}
|
|
1651
1692
|
query = Mutation(
|
|
1652
1693
|
mutation=f"{self._schema.kind}Delete",
|
|
@@ -1661,12 +1702,16 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1661
1702
|
)
|
|
1662
1703
|
|
|
1663
1704
|
def save(
|
|
1664
|
-
self,
|
|
1705
|
+
self,
|
|
1706
|
+
allow_upsert: bool = False,
|
|
1707
|
+
update_group_context: bool | None = None,
|
|
1708
|
+
timeout: int | None = None,
|
|
1709
|
+
request_context: RequestContext | None = None,
|
|
1665
1710
|
) -> None:
|
|
1666
1711
|
if self._existing is False or allow_upsert is True:
|
|
1667
|
-
self.create(allow_upsert=allow_upsert, timeout=timeout)
|
|
1712
|
+
self.create(allow_upsert=allow_upsert, timeout=timeout, request_context=request_context)
|
|
1668
1713
|
else:
|
|
1669
|
-
self.update(timeout=timeout)
|
|
1714
|
+
self.update(timeout=timeout, request_context=request_context)
|
|
1670
1715
|
|
|
1671
1716
|
if update_group_context is None and self._client.mode == InfrahubClientMode.TRACKING:
|
|
1672
1717
|
update_group_context = True
|
|
@@ -1890,15 +1935,17 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1890
1935
|
related_node.fetch(timeout=timeout)
|
|
1891
1936
|
setattr(self, rel_name, related_node)
|
|
1892
1937
|
|
|
1893
|
-
def create(
|
|
1938
|
+
def create(
|
|
1939
|
+
self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
|
|
1940
|
+
) -> None:
|
|
1894
1941
|
mutation_query = self._generate_mutation_query()
|
|
1895
1942
|
|
|
1896
1943
|
if allow_upsert:
|
|
1897
|
-
input_data = self._generate_input_data(exclude_hfid=False)
|
|
1944
|
+
input_data = self._generate_input_data(exclude_hfid=False, request_context=request_context)
|
|
1898
1945
|
mutation_name = f"{self._schema.kind}Upsert"
|
|
1899
1946
|
tracker = f"mutation-{str(self._schema.kind).lower()}-upsert"
|
|
1900
1947
|
else:
|
|
1901
|
-
input_data = self._generate_input_data(exclude_hfid=True)
|
|
1948
|
+
input_data = self._generate_input_data(exclude_hfid=True, request_context=request_context)
|
|
1902
1949
|
mutation_name = f"{self._schema.kind}Create"
|
|
1903
1950
|
tracker = f"mutation-{str(self._schema.kind).lower()}-create"
|
|
1904
1951
|
query = Mutation(
|
|
@@ -1917,8 +1964,10 @@ class InfrahubNodeSync(InfrahubNodeBase):
|
|
|
1917
1964
|
)
|
|
1918
1965
|
self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)
|
|
1919
1966
|
|
|
1920
|
-
def update(
|
|
1921
|
-
|
|
1967
|
+
def update(
|
|
1968
|
+
self, do_full_update: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
|
|
1969
|
+
) -> None:
|
|
1970
|
+
input_data = self._generate_input_data(exclude_unmodified=not do_full_update, request_context=request_context)
|
|
1922
1971
|
mutation_query = self._generate_mutation_query()
|
|
1923
1972
|
mutation_name = f"{self._schema.kind}Update"
|
|
1924
1973
|
|
infrahub_sdk/protocols_base.py
CHANGED
|
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
import ipaddress
|
|
7
7
|
|
|
8
|
+
from .context import RequestContext
|
|
8
9
|
from .schema import MainSchemaTypes
|
|
9
10
|
|
|
10
11
|
|
|
@@ -169,13 +170,23 @@ class CoreNodeBase(Protocol):
|
|
|
169
170
|
|
|
170
171
|
@runtime_checkable
|
|
171
172
|
class CoreNode(CoreNodeBase, Protocol):
|
|
172
|
-
async def save(
|
|
173
|
+
async def save(
|
|
174
|
+
self,
|
|
175
|
+
allow_upsert: bool = False,
|
|
176
|
+
update_group_context: bool | None = None,
|
|
177
|
+
timeout: int | None = None,
|
|
178
|
+
request_context: RequestContext | None = None,
|
|
179
|
+
) -> None: ...
|
|
173
180
|
|
|
174
|
-
async def delete(self) -> None: ...
|
|
181
|
+
async def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None: ...
|
|
175
182
|
|
|
176
|
-
async def update(
|
|
183
|
+
async def update(
|
|
184
|
+
self, do_full_update: bool, timeout: int | None = None, request_context: RequestContext | None = None
|
|
185
|
+
) -> None: ...
|
|
177
186
|
|
|
178
|
-
async def create(
|
|
187
|
+
async def create(
|
|
188
|
+
self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
|
|
189
|
+
) -> None: ...
|
|
179
190
|
|
|
180
191
|
async def add_relationships(self, relation_to_update: str, related_nodes: list[str]) -> None: ...
|
|
181
192
|
|
|
@@ -184,13 +195,23 @@ class CoreNode(CoreNodeBase, Protocol):
|
|
|
184
195
|
|
|
185
196
|
@runtime_checkable
|
|
186
197
|
class CoreNodeSync(CoreNodeBase, Protocol):
|
|
187
|
-
def save(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
def save(
|
|
199
|
+
self,
|
|
200
|
+
allow_upsert: bool = False,
|
|
201
|
+
update_group_context: bool | None = None,
|
|
202
|
+
timeout: int | None = None,
|
|
203
|
+
request_context: RequestContext | None = None,
|
|
204
|
+
) -> None: ...
|
|
205
|
+
|
|
206
|
+
def delete(self, timeout: int | None = None, request_context: RequestContext | None = None) -> None: ...
|
|
207
|
+
|
|
208
|
+
def update(
|
|
209
|
+
self, do_full_update: bool, timeout: int | None = None, request_context: RequestContext | None = None
|
|
210
|
+
) -> None: ...
|
|
211
|
+
|
|
212
|
+
def create(
|
|
213
|
+
self, allow_upsert: bool = False, timeout: int | None = None, request_context: RequestContext | None = None
|
|
214
|
+
) -> None: ...
|
|
194
215
|
|
|
195
216
|
def add_relationships(self, relation_to_update: str, related_nodes: list[str]) -> None: ...
|
|
196
217
|
|