infrahub-server 1.3.7__py3-none-any.whl → 1.4.0__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/internal.py +5 -0
- infrahub/artifacts/tasks.py +17 -22
- infrahub/branch/merge_mutation_checker.py +38 -0
- infrahub/cli/__init__.py +2 -2
- infrahub/cli/context.py +7 -3
- infrahub/cli/db.py +5 -16
- infrahub/cli/upgrade.py +10 -29
- infrahub/computed_attribute/tasks.py +36 -46
- infrahub/config.py +57 -6
- infrahub/constants/environment.py +1 -0
- infrahub/core/attribute.py +15 -7
- infrahub/core/branch/tasks.py +43 -41
- infrahub/core/constants/__init__.py +21 -6
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/diff/coordinator.py +3 -1
- infrahub/core/diff/model/path.py +0 -39
- infrahub/core/diff/repository/repository.py +0 -8
- infrahub/core/diff/tasks.py +11 -8
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/index.py +1 -2
- infrahub/core/graph/schema.py +50 -29
- infrahub/core/initialization.py +81 -47
- infrahub/core/ipam/tasks.py +4 -3
- infrahub/core/merge.py +8 -10
- infrahub/core/migrations/__init__.py +2 -0
- infrahub/core/migrations/graph/__init__.py +4 -0
- infrahub/core/migrations/graph/m036_drop_attr_value_index.py +45 -0
- infrahub/core/migrations/graph/m037_index_attr_vals.py +577 -0
- infrahub/core/migrations/query/attribute_add.py +27 -2
- infrahub/core/migrations/schema/attribute_kind_update.py +156 -0
- infrahub/core/migrations/schema/tasks.py +6 -5
- infrahub/core/models.py +5 -1
- infrahub/core/node/proposed_change.py +43 -0
- infrahub/core/protocols.py +12 -0
- infrahub/core/query/attribute.py +32 -14
- infrahub/core/query/diff.py +11 -0
- infrahub/core/query/ipam.py +13 -7
- infrahub/core/query/node.py +51 -10
- infrahub/core/query/resource_manager.py +3 -3
- infrahub/core/schema/basenode_schema.py +8 -0
- infrahub/core/schema/definitions/core/__init__.py +10 -1
- infrahub/core/schema/definitions/core/ipam.py +28 -2
- infrahub/core/schema/definitions/core/propose_change.py +15 -0
- infrahub/core/schema/definitions/core/webhook.py +3 -0
- infrahub/core/schema/definitions/internal.py +1 -1
- infrahub/core/schema/generated/attribute_schema.py +1 -1
- infrahub/core/schema/generic_schema.py +10 -0
- infrahub/core/schema/manager.py +10 -1
- infrahub/core/schema/node_schema.py +22 -22
- infrahub/core/schema/profile_schema.py +8 -0
- infrahub/core/schema/schema_branch.py +11 -7
- infrahub/core/schema/template_schema.py +8 -0
- infrahub/core/validators/attribute/kind.py +5 -1
- infrahub/core/validators/checks_runner.py +5 -5
- infrahub/core/validators/determiner.py +22 -2
- infrahub/core/validators/tasks.py +6 -7
- infrahub/core/validators/uniqueness/checker.py +4 -2
- infrahub/core/validators/uniqueness/model.py +1 -0
- infrahub/core/validators/uniqueness/query.py +57 -7
- infrahub/database/__init__.py +2 -1
- infrahub/events/__init__.py +20 -0
- infrahub/events/constants.py +7 -0
- infrahub/events/generator.py +29 -2
- infrahub/events/proposed_change_action.py +203 -0
- infrahub/generators/tasks.py +24 -20
- infrahub/git/base.py +4 -7
- infrahub/git/integrator.py +21 -12
- infrahub/git/repository.py +15 -30
- infrahub/git/tasks.py +121 -106
- infrahub/graphql/app.py +2 -1
- infrahub/graphql/field_extractor.py +69 -0
- infrahub/graphql/manager.py +15 -11
- infrahub/graphql/mutations/account.py +2 -2
- infrahub/graphql/mutations/action.py +8 -2
- infrahub/graphql/mutations/artifact_definition.py +4 -1
- infrahub/graphql/mutations/branch.py +10 -5
- infrahub/graphql/mutations/graphql_query.py +2 -1
- infrahub/graphql/mutations/main.py +14 -8
- infrahub/graphql/mutations/menu.py +2 -1
- infrahub/graphql/mutations/proposed_change.py +230 -8
- infrahub/graphql/mutations/relationship.py +5 -0
- infrahub/graphql/mutations/repository.py +2 -1
- infrahub/graphql/mutations/tasks.py +7 -9
- infrahub/graphql/mutations/webhook.py +4 -1
- infrahub/graphql/parser.py +15 -6
- infrahub/graphql/queries/__init__.py +10 -1
- infrahub/graphql/queries/account.py +3 -3
- infrahub/graphql/queries/branch.py +2 -2
- infrahub/graphql/queries/diff/tree.py +56 -5
- infrahub/graphql/queries/event.py +13 -3
- infrahub/graphql/queries/ipam.py +23 -1
- infrahub/graphql/queries/proposed_change.py +84 -0
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/resource_manager.py +3 -3
- infrahub/graphql/queries/search.py +3 -2
- infrahub/graphql/queries/status.py +3 -2
- infrahub/graphql/queries/task.py +2 -2
- infrahub/graphql/resolvers/ipam.py +440 -0
- infrahub/graphql/resolvers/many_relationship.py +4 -3
- infrahub/graphql/resolvers/resolver.py +5 -5
- infrahub/graphql/resolvers/single_relationship.py +3 -2
- infrahub/graphql/schema.py +25 -5
- infrahub/graphql/types/__init__.py +2 -2
- infrahub/graphql/types/attribute.py +3 -3
- infrahub/graphql/types/event.py +68 -0
- infrahub/groups/tasks.py +6 -6
- infrahub/lock.py +3 -2
- infrahub/menu/generator.py +8 -0
- infrahub/message_bus/operations/__init__.py +9 -12
- infrahub/message_bus/operations/git/file.py +6 -5
- infrahub/message_bus/operations/git/repository.py +12 -20
- infrahub/message_bus/operations/refresh/registry.py +15 -9
- infrahub/message_bus/operations/send/echo.py +7 -4
- infrahub/message_bus/types.py +1 -0
- infrahub/permissions/__init__.py +2 -1
- infrahub/permissions/constants.py +13 -0
- infrahub/permissions/globals.py +31 -2
- infrahub/permissions/manager.py +8 -5
- infrahub/pools/prefix.py +7 -5
- infrahub/prefect_server/app.py +31 -0
- infrahub/prefect_server/bootstrap.py +18 -0
- infrahub/proposed_change/action_checker.py +206 -0
- infrahub/proposed_change/approval_revoker.py +40 -0
- infrahub/proposed_change/branch_diff.py +3 -1
- infrahub/proposed_change/checker.py +45 -0
- infrahub/proposed_change/constants.py +32 -2
- infrahub/proposed_change/tasks.py +182 -150
- infrahub/py.typed +0 -0
- infrahub/server.py +29 -17
- infrahub/services/__init__.py +13 -28
- infrahub/services/adapters/cache/__init__.py +4 -0
- infrahub/services/adapters/cache/nats.py +2 -0
- infrahub/services/adapters/cache/redis.py +3 -0
- infrahub/services/adapters/message_bus/__init__.py +0 -2
- infrahub/services/adapters/message_bus/local.py +1 -2
- infrahub/services/adapters/message_bus/nats.py +6 -8
- infrahub/services/adapters/message_bus/rabbitmq.py +7 -9
- infrahub/services/adapters/workflow/__init__.py +1 -0
- infrahub/services/adapters/workflow/local.py +1 -8
- infrahub/services/component.py +2 -1
- infrahub/task_manager/event.py +56 -0
- infrahub/task_manager/models.py +9 -0
- infrahub/tasks/artifact.py +6 -7
- infrahub/tasks/check.py +4 -7
- infrahub/telemetry/tasks.py +15 -18
- infrahub/transformations/tasks.py +10 -6
- infrahub/trigger/tasks.py +4 -3
- infrahub/types.py +4 -0
- infrahub/validators/events.py +7 -7
- infrahub/validators/tasks.py +6 -7
- infrahub/webhook/models.py +45 -45
- infrahub/webhook/tasks.py +25 -24
- infrahub/workers/dependencies.py +143 -0
- infrahub/workers/infrahub_async.py +19 -43
- infrahub/workflows/catalogue.py +16 -2
- infrahub/workflows/initialization.py +5 -4
- infrahub/workflows/models.py +2 -0
- infrahub_sdk/client.py +2 -2
- infrahub_sdk/ctl/repository.py +51 -0
- infrahub_sdk/ctl/schema.py +9 -9
- infrahub_sdk/node/node.py +2 -2
- infrahub_sdk/pytest_plugin/items/graphql_query.py +1 -1
- infrahub_sdk/schema/repository.py +1 -1
- infrahub_sdk/testing/docker.py +1 -1
- infrahub_sdk/utils.py +2 -2
- {infrahub_server-1.3.7.dist-info → infrahub_server-1.4.0.dist-info}/METADATA +7 -5
- {infrahub_server-1.3.7.dist-info → infrahub_server-1.4.0.dist-info}/RECORD +174 -158
- infrahub_testcontainers/container.py +17 -0
- infrahub_testcontainers/docker-compose-cluster.test.yml +56 -1
- infrahub_testcontainers/docker-compose.test.yml +56 -1
- infrahub_testcontainers/helpers.py +4 -1
- {infrahub_server-1.3.7.dist-info → infrahub_server-1.4.0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.3.7.dist-info → infrahub_server-1.4.0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.3.7.dist-info → infrahub_server-1.4.0.dist-info}/entry_points.txt +0 -0
|
@@ -3,7 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
5
|
from infrahub.core.constants.relationship_label import RELATIONSHIP_TO_VALUE_LABEL
|
|
6
|
+
from infrahub.core.graph.schema import GraphAttributeValueIndexedNode, GraphAttributeValueNode
|
|
6
7
|
from infrahub.core.query import Query, QueryType
|
|
8
|
+
from infrahub.types import is_large_attribute_type
|
|
7
9
|
|
|
8
10
|
from .model import QueryAttributePathValued, QueryRelationshipPathValued
|
|
9
11
|
|
|
@@ -40,6 +42,7 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
40
42
|
items="relationships(active_path)", item_names=["branch", "branch_level"]
|
|
41
43
|
)
|
|
42
44
|
|
|
45
|
+
attrs_include_large_type = False
|
|
43
46
|
attribute_names = set()
|
|
44
47
|
attr_paths, attr_paths_with_value, attr_values = [], [], []
|
|
45
48
|
for attr_path in self.query_request.unique_attribute_paths:
|
|
@@ -49,12 +52,19 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
49
52
|
raise ValueError(
|
|
50
53
|
f"{attr_path.property_name} is not a valid property for a uniqueness constraint"
|
|
51
54
|
) from exc
|
|
55
|
+
if is_large_attribute_type(attr_path.attribute_kind):
|
|
56
|
+
attrs_include_large_type = True
|
|
52
57
|
attribute_names.add(attr_path.attribute_name)
|
|
53
58
|
if attr_path.value:
|
|
54
59
|
attr_paths_with_value.append((attr_path.attribute_name, property_rel_name, attr_path.value))
|
|
55
60
|
attr_values.append(attr_path.value)
|
|
56
61
|
else:
|
|
57
62
|
attr_paths.append((attr_path.attribute_name, property_rel_name))
|
|
63
|
+
attr_value_label = (
|
|
64
|
+
GraphAttributeValueNode.get_default_label()
|
|
65
|
+
if attrs_include_large_type
|
|
66
|
+
else GraphAttributeValueIndexedNode.get_default_label()
|
|
67
|
+
)
|
|
58
68
|
|
|
59
69
|
relationship_names = set()
|
|
60
70
|
relationship_attr_paths = []
|
|
@@ -112,11 +122,11 @@ class NodeUniqueAttributeConstraintQuery(Query):
|
|
|
112
122
|
""" % {"node_kind": self.query_request.kind}
|
|
113
123
|
|
|
114
124
|
attr_paths_with_value_subquery = """
|
|
115
|
-
MATCH attr_path = (start_node:%(node_kind)s)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[r:HAS_VALUE]->(attr_value
|
|
125
|
+
MATCH attr_path = (start_node:%(node_kind)s)-[:HAS_ATTRIBUTE]->(attr:Attribute)-[r:HAS_VALUE]->(attr_value:%(attr_value_label)s)
|
|
116
126
|
WHERE attr.name in $attribute_names AND attr_value.value in $attr_values
|
|
117
127
|
AND [attr.name, type(r), attr_value.value] in $attr_paths_with_value
|
|
118
128
|
RETURN start_node, attr_path as potential_path, NULL as rel_identifier, attr.name as potential_attr, attr_value.value as potential_attr_value
|
|
119
|
-
""" % {"node_kind": self.query_request.kind}
|
|
129
|
+
""" % {"node_kind": self.query_request.kind, "attr_value_label": attr_value_label}
|
|
120
130
|
|
|
121
131
|
relationship_attr_paths_subquery = """
|
|
122
132
|
MATCH rel_path = (start_node:%(node_kind)s)-[:IS_RELATED]-(relationship_node:Relationship)-[:IS_RELATED]-(related_n:Node)-[:HAS_ATTRIBUTE]->(rel_attr:Attribute)-[:HAS_VALUE]->(rel_attr_value:AttributeValue)
|
|
@@ -262,8 +272,20 @@ class UniquenessValidationQuery(Query):
|
|
|
262
272
|
self.node_ids_to_exclude = node_ids_to_exclude
|
|
263
273
|
super().__init__(**kwargs)
|
|
264
274
|
|
|
275
|
+
def _is_attribute_large_type(self, db: InfrahubDatabase, node_kind: str, attribute_name: str) -> bool:
|
|
276
|
+
"""Determine if an attribute is a large type that should use AttributeValue instead of AttributeValueIndexed."""
|
|
277
|
+
node_schema = db.schema.get(node_kind, branch=self.branch, duplicate=False)
|
|
278
|
+
attr_schema = node_schema.get_attribute(attribute_name)
|
|
279
|
+
return is_large_attribute_type(attr_schema.kind)
|
|
280
|
+
|
|
265
281
|
def _build_attr_subquery(
|
|
266
|
-
self,
|
|
282
|
+
self,
|
|
283
|
+
node_kind: str,
|
|
284
|
+
attr_path: QueryAttributePathValued,
|
|
285
|
+
index: int,
|
|
286
|
+
branch_filter: str,
|
|
287
|
+
is_first_query: bool,
|
|
288
|
+
is_large_type: bool,
|
|
267
289
|
) -> tuple[str, dict[str, str | int | float | bool]]:
|
|
268
290
|
attr_name_var = f"attr_name_{index}"
|
|
269
291
|
attr_value_var = f"attr_value_{index}"
|
|
@@ -271,8 +293,16 @@ class UniquenessValidationQuery(Query):
|
|
|
271
293
|
first_query_filter = "WHERE $node_ids_to_exclude IS NULL OR NOT node.uuid IN $node_ids_to_exclude"
|
|
272
294
|
else:
|
|
273
295
|
first_query_filter = ""
|
|
296
|
+
|
|
297
|
+
# Determine the appropriate label based on attribute type
|
|
298
|
+
attr_value_label = (
|
|
299
|
+
GraphAttributeValueNode.get_default_label()
|
|
300
|
+
if is_large_type
|
|
301
|
+
else GraphAttributeValueIndexedNode.get_default_label()
|
|
302
|
+
)
|
|
303
|
+
|
|
274
304
|
attribute_query = """
|
|
275
|
-
MATCH (node:%(node_kind)s)-[:HAS_ATTRIBUTE]->(attr:Attribute {name: $%(attr_name_var)s})-[:HAS_VALUE]->(
|
|
305
|
+
MATCH (node:%(node_kind)s)-[:HAS_ATTRIBUTE]->(attr:Attribute {name: $%(attr_name_var)s})-[:HAS_VALUE]->(:%(attr_value_label)s {value: $%(attr_value_var)s})
|
|
276
306
|
%(first_query_filter)s
|
|
277
307
|
WITH DISTINCT node
|
|
278
308
|
CALL (node) {
|
|
@@ -300,6 +330,7 @@ CALL (node) {
|
|
|
300
330
|
"attr_value_var": attr_value_var,
|
|
301
331
|
"branch_filter": branch_filter,
|
|
302
332
|
"index": index,
|
|
333
|
+
"attr_value_label": attr_value_label,
|
|
303
334
|
}
|
|
304
335
|
params: dict[str, str | int | float | bool] = {
|
|
305
336
|
attr_name_var: attr_path.attribute_name,
|
|
@@ -314,6 +345,7 @@ CALL (node) {
|
|
|
314
345
|
index: int,
|
|
315
346
|
branch_filter: str,
|
|
316
347
|
is_first_query: bool,
|
|
348
|
+
is_large_type: bool = False,
|
|
317
349
|
) -> tuple[str, dict[str, str | int | float | bool]]:
|
|
318
350
|
params: dict[str, str | int | float | bool] = {}
|
|
319
351
|
rel_attr_query = ""
|
|
@@ -321,6 +353,14 @@ CALL (node) {
|
|
|
321
353
|
if rel_path.attribute_name and rel_path.attribute_value:
|
|
322
354
|
attr_name_var = f"attr_name_{index}"
|
|
323
355
|
attr_value_var = f"attr_value_{index}"
|
|
356
|
+
|
|
357
|
+
# Determine the appropriate label based on relationship attribute type
|
|
358
|
+
rel_attr_value_label = (
|
|
359
|
+
GraphAttributeValueNode.get_default_label()
|
|
360
|
+
if is_large_type
|
|
361
|
+
else GraphAttributeValueIndexedNode.get_default_label()
|
|
362
|
+
)
|
|
363
|
+
|
|
324
364
|
rel_attr_query = """
|
|
325
365
|
MATCH (peer)-[r:HAS_ATTRIBUTE]->(attr:Attribute {name: $%(attr_name_var)s})
|
|
326
366
|
WHERE %(branch_filter)s
|
|
@@ -330,19 +370,25 @@ CALL (node) {
|
|
|
330
370
|
LIMIT 1
|
|
331
371
|
WITH attr, is_active
|
|
332
372
|
WHERE is_active = TRUE
|
|
333
|
-
MATCH (attr)-[r:HAS_VALUE]->(
|
|
373
|
+
MATCH (attr)-[r:HAS_VALUE]->(:%(rel_attr_value_label)s {value: $%(attr_value_var)s})
|
|
334
374
|
WHERE %(branch_filter)s
|
|
335
375
|
WITH r
|
|
336
376
|
ORDER BY r.branch_level DESC, r.from DESC, r.status ASC
|
|
337
377
|
LIMIT 1
|
|
338
378
|
WITH r
|
|
339
379
|
WHERE r.status = "active"
|
|
340
|
-
""" % {
|
|
380
|
+
""" % {
|
|
381
|
+
"attr_name_var": attr_name_var,
|
|
382
|
+
"attr_value_var": attr_value_var,
|
|
383
|
+
"branch_filter": branch_filter,
|
|
384
|
+
"rel_attr_value_label": rel_attr_value_label,
|
|
385
|
+
}
|
|
341
386
|
rel_attr_match = (
|
|
342
|
-
"-[r:HAS_ATTRIBUTE]->(attr:Attribute {name: $%(attr_name_var)s})-[:HAS_VALUE]->(
|
|
387
|
+
"-[r:HAS_ATTRIBUTE]->(attr:Attribute {name: $%(attr_name_var)s})-[:HAS_VALUE]->(:%(rel_attr_value_label)s {value: $%(attr_value_var)s})"
|
|
343
388
|
% {
|
|
344
389
|
"attr_name_var": attr_name_var,
|
|
345
390
|
"attr_value_var": attr_value_var,
|
|
391
|
+
"rel_attr_value_label": rel_attr_value_label,
|
|
346
392
|
}
|
|
347
393
|
)
|
|
348
394
|
params[attr_name_var] = rel_path.attribute_name
|
|
@@ -426,12 +472,16 @@ CALL (node) {
|
|
|
426
472
|
for index, schema_path in enumerate(self.query_request.unique_valued_paths):
|
|
427
473
|
is_first_query = index == 0
|
|
428
474
|
if isinstance(schema_path, QueryAttributePathValued):
|
|
475
|
+
is_large_type = self._is_attribute_large_type(
|
|
476
|
+
db=db, node_kind=self.query_request.kind, attribute_name=schema_path.attribute_name
|
|
477
|
+
)
|
|
429
478
|
subquery, params = self._build_attr_subquery(
|
|
430
479
|
node_kind=self.query_request.kind,
|
|
431
480
|
attr_path=schema_path,
|
|
432
481
|
index=index,
|
|
433
482
|
branch_filter=branch_filter,
|
|
434
483
|
is_first_query=is_first_query,
|
|
484
|
+
is_large_type=is_large_type,
|
|
435
485
|
)
|
|
436
486
|
else:
|
|
437
487
|
subquery, params = self._build_rel_subquery(
|
infrahub/database/__init__.py
CHANGED
|
@@ -295,7 +295,8 @@ class InfrahubDatabase:
|
|
|
295
295
|
traceback: TracebackType | None,
|
|
296
296
|
) -> None:
|
|
297
297
|
if self._mode == InfrahubDatabaseMode.SESSION:
|
|
298
|
-
|
|
298
|
+
await self._session.close()
|
|
299
|
+
return
|
|
299
300
|
|
|
300
301
|
if self._mode == InfrahubDatabaseMode.TRANSACTION:
|
|
301
302
|
if exc_type is not None:
|
infrahub/events/__init__.py
CHANGED
|
@@ -3,6 +3,17 @@ from .branch_action import BranchCreatedEvent, BranchDeletedEvent, BranchMergedE
|
|
|
3
3
|
from .group_action import GroupMemberAddedEvent, GroupMemberRemovedEvent
|
|
4
4
|
from .models import EventMeta, InfrahubEvent
|
|
5
5
|
from .node_action import NodeCreatedEvent, NodeDeletedEvent, NodeUpdatedEvent
|
|
6
|
+
from .proposed_change_action import (
|
|
7
|
+
ProposedChangeApprovalRevokedEvent,
|
|
8
|
+
ProposedChangeApprovalsRevokedEvent,
|
|
9
|
+
ProposedChangeApprovedEvent,
|
|
10
|
+
ProposedChangeMergedEvent,
|
|
11
|
+
ProposedChangeRejectedEvent,
|
|
12
|
+
ProposedChangeRejectionRevokedEvent,
|
|
13
|
+
ProposedChangeReviewRequestedEvent,
|
|
14
|
+
ProposedChangeThreadCreatedEvent,
|
|
15
|
+
ProposedChangeThreadUpdatedEvent,
|
|
16
|
+
)
|
|
6
17
|
from .repository_action import CommitUpdatedEvent
|
|
7
18
|
from .validator_action import ValidatorFailedEvent, ValidatorPassedEvent, ValidatorStartedEvent
|
|
8
19
|
|
|
@@ -21,6 +32,15 @@ __all__ = [
|
|
|
21
32
|
"NodeCreatedEvent",
|
|
22
33
|
"NodeDeletedEvent",
|
|
23
34
|
"NodeUpdatedEvent",
|
|
35
|
+
"ProposedChangeApprovalRevokedEvent",
|
|
36
|
+
"ProposedChangeApprovalsRevokedEvent",
|
|
37
|
+
"ProposedChangeApprovedEvent",
|
|
38
|
+
"ProposedChangeMergedEvent",
|
|
39
|
+
"ProposedChangeRejectedEvent",
|
|
40
|
+
"ProposedChangeRejectionRevokedEvent",
|
|
41
|
+
"ProposedChangeReviewRequestedEvent",
|
|
42
|
+
"ProposedChangeThreadCreatedEvent",
|
|
43
|
+
"ProposedChangeThreadUpdatedEvent",
|
|
24
44
|
"ValidatorFailedEvent",
|
|
25
45
|
"ValidatorPassedEvent",
|
|
26
46
|
"ValidatorStartedEvent",
|
infrahub/events/constants.py
CHANGED
infrahub/events/generator.py
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
from infrahub.context import InfrahubContext
|
|
2
2
|
from infrahub.core.branch import Branch
|
|
3
3
|
from infrahub.core.changelog.models import RelationshipChangelogGetter
|
|
4
|
-
from infrahub.core.constants import MutationAction
|
|
4
|
+
from infrahub.core.constants import InfrahubKind, MutationAction
|
|
5
5
|
from infrahub.core.node import Node
|
|
6
|
+
from infrahub.core.protocols import CoreProposedChange
|
|
6
7
|
from infrahub.database import InfrahubDatabase
|
|
7
8
|
from infrahub.events.node_action import NodeDeletedEvent, NodeMutatedEvent, NodeUpdatedEvent, get_node_event
|
|
8
9
|
from infrahub.groups.parsers import GroupNodeMutationParser
|
|
9
10
|
from infrahub.worker import WORKER_IDENTITY
|
|
10
11
|
|
|
11
12
|
from .models import EventMeta, InfrahubEvent
|
|
13
|
+
from .proposed_change_action import ProposedChangeThreadCreatedEvent, ProposedChangeThreadUpdatedEvent
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
async def generate_node_mutation_events(
|
|
@@ -68,4 +70,29 @@ async def generate_node_mutation_events(
|
|
|
68
70
|
|
|
69
71
|
group_parser = GroupNodeMutationParser(db=db, branch=branch)
|
|
70
72
|
group_events = await group_parser.group_events_from_node_actions(events=events)
|
|
71
|
-
|
|
73
|
+
|
|
74
|
+
specific_events: list[InfrahubEvent] = []
|
|
75
|
+
if (kind := node.get_kind()) in [
|
|
76
|
+
InfrahubKind.CHANGETHREAD,
|
|
77
|
+
InfrahubKind.OBJECTTHREAD,
|
|
78
|
+
InfrahubKind.ARTIFACTTHREAD,
|
|
79
|
+
InfrahubKind.FILETHREAD,
|
|
80
|
+
]:
|
|
81
|
+
proposed_change: CoreProposedChange = await node.change.get_peer(db=db, peer_type=CoreProposedChange) # type: ignore[attr-defined]
|
|
82
|
+
action_to_event_map = {
|
|
83
|
+
MutationAction.CREATED: ProposedChangeThreadCreatedEvent,
|
|
84
|
+
MutationAction.UPDATED: ProposedChangeThreadUpdatedEvent,
|
|
85
|
+
}
|
|
86
|
+
if action in action_to_event_map:
|
|
87
|
+
specific_events.append(
|
|
88
|
+
action_to_event_map[action](
|
|
89
|
+
proposed_change_id=proposed_change.id,
|
|
90
|
+
proposed_change_name=proposed_change.name.value,
|
|
91
|
+
proposed_change_state=proposed_change.state.value,
|
|
92
|
+
thread_id=node.id,
|
|
93
|
+
thread_kind=kind,
|
|
94
|
+
meta=EventMeta.from_context(context=context),
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return events + group_events + specific_events
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from typing import ClassVar
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from infrahub.core.constants import InfrahubKind, MutationAction
|
|
6
|
+
|
|
7
|
+
from .constants import EVENT_NAMESPACE
|
|
8
|
+
from .models import InfrahubEvent
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProposedChangeEvent(InfrahubEvent):
|
|
12
|
+
proposed_change_id: str = Field(..., description="The ID of the proposed change")
|
|
13
|
+
proposed_change_name: str = Field(..., description="The name of the proposed change")
|
|
14
|
+
proposed_change_state: str = Field(..., description="The state of the proposed change")
|
|
15
|
+
|
|
16
|
+
def get_resource(self) -> dict[str, str]:
|
|
17
|
+
return {
|
|
18
|
+
"prefect.resource.id": f"infrahub.proposed_change.{self.proposed_change_id}",
|
|
19
|
+
"infrahub.node.kind": InfrahubKind.PROPOSEDCHANGE,
|
|
20
|
+
"infrahub.node.id": self.proposed_change_id,
|
|
21
|
+
"infrahub.proposed_change.name": self.proposed_change_name,
|
|
22
|
+
"infrahub.proposed_change.state": self.proposed_change_state,
|
|
23
|
+
"infrahub.branch.name": self.meta.context.branch.name,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ProposedChangeReviewEvent(ProposedChangeEvent):
|
|
28
|
+
reviewer_account_id: str = Field(..., description="The ID of the user who reviewed the proposed change")
|
|
29
|
+
reviewer_account_name: str = Field(..., description="The name of the user who reviewed the proposed change")
|
|
30
|
+
reviewer_decision: str = Field(..., description="The decision made by the reviewer")
|
|
31
|
+
|
|
32
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
33
|
+
related = super().get_related()
|
|
34
|
+
related.append(
|
|
35
|
+
{
|
|
36
|
+
"prefect.resource.id": self.reviewer_account_id,
|
|
37
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
38
|
+
"infrahub.node.kind": InfrahubKind.GENERICACCOUNT,
|
|
39
|
+
"infrahub.node.id": self.reviewer_account_id,
|
|
40
|
+
"infrahub.reviewer.account.name": self.reviewer_account_name,
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
return related
|
|
44
|
+
|
|
45
|
+
def get_resource(self) -> dict[str, str]:
|
|
46
|
+
return {**super().get_resource(), "infrahub.proposed_change.reviewer_decision": self.reviewer_decision}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ProposedChangeReviewRevokedEvent(ProposedChangeEvent):
|
|
50
|
+
reviewer_account_id: str = Field(..., description="The ID of the user who reviewed the proposed change")
|
|
51
|
+
reviewer_account_name: str = Field(..., description="The name of the user who reviewed the proposed change")
|
|
52
|
+
reviewer_former_decision: str = Field(..., description="The former decision made by the reviewer")
|
|
53
|
+
|
|
54
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
55
|
+
related = super().get_related()
|
|
56
|
+
related.append(
|
|
57
|
+
{
|
|
58
|
+
"prefect.resource.id": self.reviewer_account_id,
|
|
59
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
60
|
+
"infrahub.node.kind": InfrahubKind.GENERICACCOUNT,
|
|
61
|
+
"infrahub.node.id": self.reviewer_account_id,
|
|
62
|
+
"infrahub.reviewer.account.name": self.reviewer_account_name,
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
return related
|
|
66
|
+
|
|
67
|
+
def get_resource(self) -> dict[str, str]:
|
|
68
|
+
return {
|
|
69
|
+
**super().get_resource(),
|
|
70
|
+
"infrahub.proposed_change.reviewer_former_decision": self.reviewer_former_decision,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ProposedChangeMergedEvent(ProposedChangeEvent):
|
|
75
|
+
"""Event generated when a proposed change has been merged"""
|
|
76
|
+
|
|
77
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.merged"
|
|
78
|
+
|
|
79
|
+
merged_by_account_id: str = Field(..., description="The ID of the user who merged the proposed change")
|
|
80
|
+
merged_by_account_name: str = Field(..., description="The name of the user who merged the proposed change")
|
|
81
|
+
|
|
82
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
83
|
+
related = super().get_related()
|
|
84
|
+
related.append(
|
|
85
|
+
{
|
|
86
|
+
"prefect.resource.id": self.merged_by_account_id,
|
|
87
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
88
|
+
"infrahub.node.kind": InfrahubKind.GENERICACCOUNT,
|
|
89
|
+
"infrahub.node.id": self.merged_by_account_id,
|
|
90
|
+
"infrahub.merged_by.account.name": self.merged_by_account_name,
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
return related
|
|
94
|
+
|
|
95
|
+
def get_resource(self) -> dict[str, str]:
|
|
96
|
+
return {
|
|
97
|
+
**super().get_resource(),
|
|
98
|
+
"infrahub.proposed_change.merged_by_account_id": self.merged_by_account_id,
|
|
99
|
+
"infrahub.proposed_change.merged_by_account_name": self.merged_by_account_name,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ProposedChangeReviewRequestedEvent(ProposedChangeEvent):
|
|
104
|
+
"""Event generated when a proposed change has been flagged for review"""
|
|
105
|
+
|
|
106
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.review_requested"
|
|
107
|
+
|
|
108
|
+
requested_by_account_id: str = Field(
|
|
109
|
+
..., description="The ID of the user who requested the proposed change to be reviewed"
|
|
110
|
+
)
|
|
111
|
+
requested_by_account_name: str = Field(
|
|
112
|
+
..., description="The name of the user who requested the proposed change to be reviewed"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
116
|
+
related = super().get_related()
|
|
117
|
+
related.append(
|
|
118
|
+
{
|
|
119
|
+
"prefect.resource.id": self.requested_by_account_id,
|
|
120
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
121
|
+
"infrahub.node.kind": InfrahubKind.GENERICACCOUNT,
|
|
122
|
+
"infrahub.node.id": self.requested_by_account_id,
|
|
123
|
+
"infrahub.requested_by.account.name": self.requested_by_account_name,
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
return related
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class ProposedChangeApprovedEvent(ProposedChangeReviewEvent):
|
|
130
|
+
"""Event generated when a proposed change has been approved"""
|
|
131
|
+
|
|
132
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.approved"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class ProposedChangeRejectedEvent(ProposedChangeReviewEvent):
|
|
136
|
+
"""Event generated when a proposed change has been rejected"""
|
|
137
|
+
|
|
138
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.rejected"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class ProposedChangeApprovalRevokedEvent(ProposedChangeReviewRevokedEvent):
|
|
142
|
+
"""Event generated when a proposed change approval has been revoked"""
|
|
143
|
+
|
|
144
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.approval_revoked"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ProposedChangeRejectionRevokedEvent(ProposedChangeReviewRevokedEvent):
|
|
148
|
+
"""Event generated when a proposed change rejection has been revoked"""
|
|
149
|
+
|
|
150
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.rejection_revoked"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class ProposedChangeApprovalsRevokedEvent(ProposedChangeEvent):
|
|
154
|
+
reviewer_accounts: dict[str, str] = Field(
|
|
155
|
+
default_factory=dict, description="ID to name map of accounts whose approval was revoked"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change.approvals_revoked"
|
|
159
|
+
|
|
160
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
161
|
+
related = super().get_related()
|
|
162
|
+
for account_id, account_name in self.reviewer_accounts.items():
|
|
163
|
+
related.append(
|
|
164
|
+
{
|
|
165
|
+
"prefect.resource.id": account_id,
|
|
166
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
167
|
+
"infrahub.node.kind": InfrahubKind.GENERICACCOUNT,
|
|
168
|
+
"infrahub.node.id": account_id,
|
|
169
|
+
"infrahub.reviewer.account.name": account_name,
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
return related
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class ProposedChangeThreadEvent(ProposedChangeEvent):
|
|
176
|
+
thread_id: str = Field(..., description="The ID of the thread that was created or updated")
|
|
177
|
+
thread_kind: str = Field(..., description="The name of the thread that was created or updated")
|
|
178
|
+
|
|
179
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
180
|
+
related = super().get_related()
|
|
181
|
+
related.append(
|
|
182
|
+
{
|
|
183
|
+
"prefect.resource.id": self.thread_id,
|
|
184
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
185
|
+
"infrahub.node.kind": self.thread_kind,
|
|
186
|
+
"infrahub.node.id": self.thread_id,
|
|
187
|
+
}
|
|
188
|
+
)
|
|
189
|
+
return related
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class ProposedChangeThreadCreatedEvent(ProposedChangeThreadEvent):
|
|
193
|
+
"""Event generated when a thread has been created in a proposed change"""
|
|
194
|
+
|
|
195
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change_thread.created"
|
|
196
|
+
action: MutationAction = MutationAction.CREATED
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class ProposedChangeThreadUpdatedEvent(ProposedChangeThreadEvent):
|
|
200
|
+
"""Event generated when a thread has been updated in a proposed change"""
|
|
201
|
+
|
|
202
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.proposed_change_thread.updated"
|
|
203
|
+
action: MutationAction = MutationAction.UPDATED
|
infrahub/generators/tasks.py
CHANGED
|
@@ -21,25 +21,29 @@ from infrahub.generators.models import (
|
|
|
21
21
|
)
|
|
22
22
|
from infrahub.git.base import extract_repo_file_information
|
|
23
23
|
from infrahub.git.repository import get_initialized_repo
|
|
24
|
-
from infrahub.
|
|
24
|
+
from infrahub.workers.dependencies import get_client, get_workflow
|
|
25
25
|
from infrahub.workflows.catalogue import REQUEST_GENERATOR_DEFINITION_RUN, REQUEST_GENERATOR_RUN
|
|
26
26
|
from infrahub.workflows.utils import add_tags
|
|
27
27
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
from collections.abc import Coroutine
|
|
30
30
|
|
|
31
|
+
from infrahub_sdk.client import InfrahubClient
|
|
32
|
+
|
|
31
33
|
|
|
32
34
|
@flow(
|
|
33
35
|
name="generator-run",
|
|
34
36
|
flow_run_name="Run generator {model.generator_definition.definition_name}",
|
|
35
37
|
)
|
|
36
|
-
async def run_generator(model: RequestGeneratorRun
|
|
38
|
+
async def run_generator(model: RequestGeneratorRun) -> None:
|
|
37
39
|
await add_tags(branches=[model.branch_name], nodes=[model.target_id])
|
|
38
40
|
|
|
41
|
+
client = get_client()
|
|
42
|
+
|
|
39
43
|
repository = await get_initialized_repo(
|
|
44
|
+
client=client,
|
|
40
45
|
repository_id=model.repository_id,
|
|
41
46
|
name=model.repository_name,
|
|
42
|
-
service=service,
|
|
43
47
|
repository_kind=model.repository_kind,
|
|
44
48
|
commit=model.commit,
|
|
45
49
|
)
|
|
@@ -60,7 +64,7 @@ async def run_generator(model: RequestGeneratorRun, service: InfrahubServices) -
|
|
|
60
64
|
repo_directory=repository.directory_root,
|
|
61
65
|
worktree_directory=commit_worktree.directory,
|
|
62
66
|
)
|
|
63
|
-
generator_instance = await _define_instance(model=model,
|
|
67
|
+
generator_instance = await _define_instance(model=model, client=client)
|
|
64
68
|
|
|
65
69
|
try:
|
|
66
70
|
generator_class = generator_definition.load_class(
|
|
@@ -69,7 +73,7 @@ async def run_generator(model: RequestGeneratorRun, service: InfrahubServices) -
|
|
|
69
73
|
|
|
70
74
|
generator = generator_class(
|
|
71
75
|
query=generator_definition.query,
|
|
72
|
-
client=
|
|
76
|
+
client=client,
|
|
73
77
|
branch=model.branch_name,
|
|
74
78
|
params=model.variables,
|
|
75
79
|
generator_instance=generator_instance.id,
|
|
@@ -87,11 +91,9 @@ async def run_generator(model: RequestGeneratorRun, service: InfrahubServices) -
|
|
|
87
91
|
|
|
88
92
|
|
|
89
93
|
@task(name="generator-define-instance", task_run_name="Define Instance", cache_policy=NONE) # type: ignore[arg-type]
|
|
90
|
-
async def _define_instance(model: RequestGeneratorRun,
|
|
94
|
+
async def _define_instance(model: RequestGeneratorRun, client: InfrahubClient) -> CoreGeneratorInstance:
|
|
91
95
|
if model.generator_instance:
|
|
92
|
-
instance = await
|
|
93
|
-
kind=CoreGeneratorInstance, id=model.generator_instance, branch=model.branch_name
|
|
94
|
-
)
|
|
96
|
+
instance = await client.get(kind=CoreGeneratorInstance, id=model.generator_instance, branch=model.branch_name)
|
|
95
97
|
instance.status.value = GeneratorInstanceStatus.PENDING.value
|
|
96
98
|
await instance.update(do_full_update=True)
|
|
97
99
|
|
|
@@ -99,7 +101,7 @@ async def _define_instance(model: RequestGeneratorRun, service: InfrahubServices
|
|
|
99
101
|
async with lock.registry.get(
|
|
100
102
|
f"{model.target_id}-{model.generator_definition.definition_id}", namespace="generator"
|
|
101
103
|
):
|
|
102
|
-
instances = await
|
|
104
|
+
instances = await client.filters(
|
|
103
105
|
kind=CoreGeneratorInstance,
|
|
104
106
|
definition__ids=[model.generator_definition.definition_id],
|
|
105
107
|
object__ids=[model.target_id],
|
|
@@ -110,7 +112,7 @@ async def _define_instance(model: RequestGeneratorRun, service: InfrahubServices
|
|
|
110
112
|
instance.status.value = GeneratorInstanceStatus.PENDING.value
|
|
111
113
|
await instance.update(do_full_update=True)
|
|
112
114
|
else:
|
|
113
|
-
instance = await
|
|
115
|
+
instance = await client.create(
|
|
114
116
|
kind=CoreGeneratorInstance,
|
|
115
117
|
branch=model.branch_name,
|
|
116
118
|
data={
|
|
@@ -125,10 +127,10 @@ async def _define_instance(model: RequestGeneratorRun, service: InfrahubServices
|
|
|
125
127
|
|
|
126
128
|
|
|
127
129
|
@flow(name="generator-definition-run", flow_run_name="Run all generators")
|
|
128
|
-
async def run_generator_definition(branch: str, context: InfrahubContext
|
|
130
|
+
async def run_generator_definition(branch: str, context: InfrahubContext) -> None:
|
|
129
131
|
await add_tags(branches=[branch])
|
|
130
132
|
|
|
131
|
-
generators = await
|
|
133
|
+
generators = await get_client().filters(
|
|
132
134
|
kind=InfrahubKind.GENERATORDEFINITION, prefetch_relationships=True, populate_store=True, branch=branch
|
|
133
135
|
)
|
|
134
136
|
|
|
@@ -150,7 +152,7 @@ async def run_generator_definition(branch: str, context: InfrahubContext, servic
|
|
|
150
152
|
|
|
151
153
|
for generator_definition in generator_definitions:
|
|
152
154
|
model = RequestGeneratorDefinitionRun(branch=branch, generator_definition=generator_definition)
|
|
153
|
-
await
|
|
155
|
+
await get_workflow().submit_workflow(
|
|
154
156
|
workflow=REQUEST_GENERATOR_DEFINITION_RUN, context=context, parameters={"model": model}
|
|
155
157
|
)
|
|
156
158
|
|
|
@@ -160,11 +162,13 @@ async def run_generator_definition(branch: str, context: InfrahubContext, servic
|
|
|
160
162
|
flow_run_name="Execute generator {model.generator_definition.definition_name}",
|
|
161
163
|
)
|
|
162
164
|
async def request_generator_definition_run(
|
|
163
|
-
model: RequestGeneratorDefinitionRun, context: InfrahubContext
|
|
165
|
+
model: RequestGeneratorDefinitionRun, context: InfrahubContext
|
|
164
166
|
) -> State[Any]:
|
|
165
167
|
await add_tags(branches=[model.branch], nodes=[model.generator_definition.definition_id])
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
client = get_client()
|
|
170
|
+
|
|
171
|
+
group = await client.get(
|
|
168
172
|
kind=InfrahubKind.GENERICGROUP,
|
|
169
173
|
prefetch_relationships=True,
|
|
170
174
|
populate_store=True,
|
|
@@ -173,7 +177,7 @@ async def request_generator_definition_run(
|
|
|
173
177
|
)
|
|
174
178
|
await group.members.fetch()
|
|
175
179
|
|
|
176
|
-
existing_instances = await
|
|
180
|
+
existing_instances = await client.filters(
|
|
177
181
|
kind=InfrahubKind.GENERATORINSTANCE,
|
|
178
182
|
definition__ids=[model.generator_definition.definition_id],
|
|
179
183
|
include=["object"],
|
|
@@ -183,14 +187,14 @@ async def request_generator_definition_run(
|
|
|
183
187
|
for instance in existing_instances:
|
|
184
188
|
instance_by_member[instance.object.peer.id] = instance.id
|
|
185
189
|
|
|
186
|
-
repository = await
|
|
190
|
+
repository = await client.get(
|
|
187
191
|
kind=InfrahubKind.REPOSITORY,
|
|
188
192
|
branch=model.branch,
|
|
189
193
|
id=model.generator_definition.repository_id,
|
|
190
194
|
raise_when_missing=False,
|
|
191
195
|
)
|
|
192
196
|
if not repository:
|
|
193
|
-
repository = await
|
|
197
|
+
repository = await client.get(
|
|
194
198
|
kind=InfrahubKind.READONLYREPOSITORY,
|
|
195
199
|
branch=model.branch,
|
|
196
200
|
id=model.generator_definition.repository_id,
|
|
@@ -219,7 +223,7 @@ async def request_generator_definition_run(
|
|
|
219
223
|
target_name=member.display_label,
|
|
220
224
|
)
|
|
221
225
|
tasks.append(
|
|
222
|
-
|
|
226
|
+
get_workflow().execute_workflow(
|
|
223
227
|
workflow=REQUEST_GENERATOR_RUN, context=context, parameters={"model": request_generator_run_model}
|
|
224
228
|
)
|
|
225
229
|
)
|
infrahub/git/base.py
CHANGED
|
@@ -33,7 +33,7 @@ from infrahub.git.constants import BRANCHES_DIRECTORY_NAME, COMMITS_DIRECTORY_NA
|
|
|
33
33
|
from infrahub.git.directory import get_repositories_directory, initialize_repositories_directory
|
|
34
34
|
from infrahub.git.worktree import Worktree
|
|
35
35
|
from infrahub.log import get_logger
|
|
36
|
-
from infrahub.
|
|
36
|
+
from infrahub.workers.dependencies import get_client
|
|
37
37
|
|
|
38
38
|
if TYPE_CHECKING:
|
|
39
39
|
from infrahub_sdk.branch import BranchData
|
|
@@ -153,9 +153,6 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
153
153
|
)
|
|
154
154
|
|
|
155
155
|
cache_repo: Repo | None = Field(None, description="Internal cache of the GitPython Repo object")
|
|
156
|
-
service: InfrahubServices = Field(
|
|
157
|
-
..., description="Service object with access to the message queue, the database etc.."
|
|
158
|
-
)
|
|
159
156
|
is_read_only: bool = Field(False, description="If true, changes will not be synced to remote")
|
|
160
157
|
|
|
161
158
|
internal_status: str = Field("active", description="Internal status: Active, Inactive, Staging")
|
|
@@ -169,10 +166,10 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
169
166
|
|
|
170
167
|
@property
|
|
171
168
|
def sdk(self) -> InfrahubClient:
|
|
172
|
-
if self.client:
|
|
173
|
-
|
|
169
|
+
if not self.client:
|
|
170
|
+
self.client = get_client()
|
|
174
171
|
|
|
175
|
-
return self.
|
|
172
|
+
return self.client
|
|
176
173
|
|
|
177
174
|
@property
|
|
178
175
|
def default_branch(self) -> str:
|