infrahub-server 1.2.11__py3-none-any.whl → 1.3.0b1__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.
Files changed (147) hide show
  1. infrahub/actions/constants.py +86 -0
  2. infrahub/actions/gather.py +114 -0
  3. infrahub/actions/models.py +241 -0
  4. infrahub/actions/parsers.py +104 -0
  5. infrahub/actions/schema.py +382 -0
  6. infrahub/actions/tasks.py +126 -0
  7. infrahub/actions/triggers.py +21 -0
  8. infrahub/cli/db.py +1 -2
  9. infrahub/core/account.py +24 -47
  10. infrahub/core/attribute.py +13 -15
  11. infrahub/core/constants/__init__.py +5 -0
  12. infrahub/core/constants/infrahubkind.py +9 -0
  13. infrahub/core/convert_object_type/__init__.py +0 -0
  14. infrahub/core/convert_object_type/conversion.py +122 -0
  15. infrahub/core/convert_object_type/schema_mapping.py +56 -0
  16. infrahub/core/diff/query/all_conflicts.py +1 -5
  17. infrahub/core/diff/query/artifact.py +10 -20
  18. infrahub/core/diff/query/diff_get.py +3 -6
  19. infrahub/core/diff/query/field_summary.py +2 -4
  20. infrahub/core/diff/query/merge.py +70 -123
  21. infrahub/core/diff/query/save.py +20 -32
  22. infrahub/core/diff/query/summary_counts_enricher.py +34 -54
  23. infrahub/core/manager.py +14 -11
  24. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +1 -2
  25. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +2 -4
  26. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +11 -22
  27. infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -6
  28. infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +1 -2
  29. infrahub/core/migrations/graph/m024_missing_hierarchy_backfill.py +1 -2
  30. infrahub/core/migrations/query/attribute_add.py +1 -2
  31. infrahub/core/migrations/query/attribute_rename.py +5 -10
  32. infrahub/core/migrations/query/delete_element_in_schema.py +19 -17
  33. infrahub/core/migrations/query/node_duplicate.py +19 -21
  34. infrahub/core/migrations/query/relationship_duplicate.py +19 -17
  35. infrahub/core/migrations/schema/node_attribute_remove.py +4 -8
  36. infrahub/core/migrations/schema/node_remove.py +19 -19
  37. infrahub/core/models.py +29 -2
  38. infrahub/core/node/__init__.py +90 -18
  39. infrahub/core/node/create.py +211 -0
  40. infrahub/core/node/resource_manager/number_pool.py +31 -5
  41. infrahub/core/node/standard.py +6 -1
  42. infrahub/core/protocols.py +56 -0
  43. infrahub/core/protocols_base.py +3 -0
  44. infrahub/core/query/__init__.py +2 -2
  45. infrahub/core/query/diff.py +19 -32
  46. infrahub/core/query/ipam.py +10 -20
  47. infrahub/core/query/node.py +28 -46
  48. infrahub/core/query/relationship.py +53 -32
  49. infrahub/core/query/resource_manager.py +1 -2
  50. infrahub/core/query/subquery.py +2 -4
  51. infrahub/core/relationship/model.py +3 -0
  52. infrahub/core/schema/__init__.py +2 -1
  53. infrahub/core/schema/attribute_parameters.py +160 -0
  54. infrahub/core/schema/attribute_schema.py +111 -8
  55. infrahub/core/schema/basenode_schema.py +25 -1
  56. infrahub/core/schema/definitions/core/__init__.py +29 -1
  57. infrahub/core/schema/definitions/core/group.py +45 -0
  58. infrahub/core/schema/definitions/internal.py +27 -4
  59. infrahub/core/schema/generated/attribute_schema.py +16 -3
  60. infrahub/core/schema/manager.py +3 -0
  61. infrahub/core/schema/schema_branch.py +67 -7
  62. infrahub/core/validators/__init__.py +13 -1
  63. infrahub/core/validators/attribute/choices.py +1 -3
  64. infrahub/core/validators/attribute/enum.py +1 -3
  65. infrahub/core/validators/attribute/kind.py +1 -3
  66. infrahub/core/validators/attribute/length.py +13 -7
  67. infrahub/core/validators/attribute/min_max.py +118 -0
  68. infrahub/core/validators/attribute/number_pool.py +106 -0
  69. infrahub/core/validators/attribute/optional.py +1 -4
  70. infrahub/core/validators/attribute/regex.py +5 -6
  71. infrahub/core/validators/attribute/unique.py +1 -3
  72. infrahub/core/validators/determiner.py +18 -2
  73. infrahub/core/validators/enum.py +12 -0
  74. infrahub/core/validators/node/hierarchy.py +3 -6
  75. infrahub/core/validators/query.py +1 -3
  76. infrahub/core/validators/relationship/count.py +6 -12
  77. infrahub/core/validators/relationship/optional.py +2 -4
  78. infrahub/core/validators/relationship/peer.py +3 -8
  79. infrahub/core/validators/uniqueness/query.py +5 -9
  80. infrahub/database/__init__.py +11 -2
  81. infrahub/events/group_action.py +1 -0
  82. infrahub/git/base.py +5 -3
  83. infrahub/git/integrator.py +102 -3
  84. infrahub/graphql/analyzer.py +139 -18
  85. infrahub/graphql/manager.py +4 -0
  86. infrahub/graphql/mutations/action.py +164 -0
  87. infrahub/graphql/mutations/convert_object_type.py +62 -0
  88. infrahub/graphql/mutations/main.py +24 -175
  89. infrahub/graphql/mutations/proposed_change.py +20 -17
  90. infrahub/graphql/mutations/resource_manager.py +62 -6
  91. infrahub/graphql/queries/convert_object_type_mapping.py +36 -0
  92. infrahub/graphql/queries/resource_manager.py +7 -1
  93. infrahub/graphql/schema.py +6 -0
  94. infrahub/menu/menu.py +31 -0
  95. infrahub/message_bus/messages/__init__.py +0 -10
  96. infrahub/message_bus/operations/__init__.py +0 -8
  97. infrahub/patch/queries/consolidate_duplicated_nodes.py +3 -6
  98. infrahub/patch/queries/delete_duplicated_edges.py +5 -10
  99. infrahub/pools/number.py +5 -3
  100. infrahub/prefect_server/models.py +1 -19
  101. infrahub/proposed_change/models.py +68 -3
  102. infrahub/proposed_change/tasks.py +907 -30
  103. infrahub/task_manager/models.py +10 -6
  104. infrahub/trigger/catalogue.py +2 -0
  105. infrahub/trigger/models.py +18 -2
  106. infrahub/trigger/tasks.py +3 -1
  107. infrahub/types.py +6 -0
  108. infrahub/workflows/catalogue.py +76 -0
  109. infrahub_sdk/client.py +43 -10
  110. infrahub_sdk/node/__init__.py +39 -0
  111. infrahub_sdk/node/attribute.py +122 -0
  112. infrahub_sdk/node/constants.py +21 -0
  113. infrahub_sdk/{node.py → node/node.py} +50 -749
  114. infrahub_sdk/node/parsers.py +15 -0
  115. infrahub_sdk/node/property.py +24 -0
  116. infrahub_sdk/node/related_node.py +266 -0
  117. infrahub_sdk/node/relationship.py +302 -0
  118. infrahub_sdk/protocols.py +112 -0
  119. infrahub_sdk/protocols_base.py +34 -2
  120. infrahub_sdk/query_groups.py +13 -2
  121. infrahub_sdk/schema/main.py +1 -0
  122. infrahub_sdk/schema/repository.py +16 -0
  123. infrahub_sdk/spec/object.py +1 -1
  124. infrahub_sdk/store.py +1 -1
  125. infrahub_sdk/testing/schemas/car_person.py +1 -0
  126. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0b1.dist-info}/METADATA +4 -4
  127. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0b1.dist-info}/RECORD +134 -122
  128. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0b1.dist-info}/WHEEL +1 -1
  129. infrahub_testcontainers/container.py +0 -1
  130. infrahub_testcontainers/docker-compose.test.yml +1 -1
  131. infrahub_testcontainers/helpers.py +8 -2
  132. infrahub/message_bus/messages/check_generator_run.py +0 -26
  133. infrahub/message_bus/messages/finalize_validator_execution.py +0 -15
  134. infrahub/message_bus/messages/proposed_change/base_with_diff.py +0 -16
  135. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +0 -11
  136. infrahub/message_bus/messages/request_generatordefinition_check.py +0 -20
  137. infrahub/message_bus/messages/request_proposedchange_pipeline.py +0 -23
  138. infrahub/message_bus/operations/check/__init__.py +0 -3
  139. infrahub/message_bus/operations/check/generator.py +0 -156
  140. infrahub/message_bus/operations/finalize/__init__.py +0 -3
  141. infrahub/message_bus/operations/finalize/validator.py +0 -133
  142. infrahub/message_bus/operations/requests/__init__.py +0 -9
  143. infrahub/message_bus/operations/requests/generator_definition.py +0 -140
  144. infrahub/message_bus/operations/requests/proposed_change.py +0 -629
  145. /infrahub/{message_bus/messages/proposed_change → actions}/__init__.py +0 -0
  146. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0b1.dist-info}/LICENSE.txt +0 -0
  147. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0b1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,382 @@
1
+ from infrahub.actions.constants import BranchScope, NodeAction, ValueMatch
2
+ from infrahub.core.constants import AllowOverrideType, BranchSupportType, InfrahubKind
3
+ from infrahub.core.constants import RelationshipCardinality as Cardinality
4
+ from infrahub.core.constants import RelationshipKind as RelKind
5
+ from infrahub.core.schema.attribute_schema import AttributeSchema as Attr
6
+ from infrahub.core.schema.generic_schema import GenericSchema
7
+ from infrahub.core.schema.node_schema import NodeSchema
8
+ from infrahub.core.schema.relationship_schema import (
9
+ RelationshipSchema as Rel,
10
+ )
11
+
12
+ core_trigger_rule = GenericSchema(
13
+ name="TriggerRule",
14
+ namespace="Core",
15
+ description="A rule that allows you to define a trigger and map it to an action that runs once the trigger condition is met.",
16
+ include_in_menu=False,
17
+ icon="mdi:filter-cog-outline",
18
+ label="Trigger Rule",
19
+ human_friendly_id=["name__value"],
20
+ order_by=["name__value"],
21
+ display_labels=["name__value"],
22
+ branch=BranchSupportType.AGNOSTIC,
23
+ uniqueness_constraints=[["name__value"]],
24
+ generate_profile=False,
25
+ attributes=[
26
+ Attr(
27
+ name="name",
28
+ kind="Text",
29
+ description="The name of the trigger rule",
30
+ unique=True,
31
+ order_weight=1000,
32
+ ),
33
+ Attr(
34
+ name="description",
35
+ kind="Text",
36
+ description="A longer description to define the purpose of this trigger",
37
+ optional=True,
38
+ order_weight=2000,
39
+ ),
40
+ Attr(
41
+ name="active",
42
+ kind="Boolean",
43
+ description="Indicates if this trigger is enabled or if it's just prepared, could be useful as you are setting up a trigger",
44
+ optional=False,
45
+ default_value=True,
46
+ order_weight=2000,
47
+ ),
48
+ Attr(
49
+ name="branch_scope",
50
+ kind="Dropdown",
51
+ description="Limits the scope with regards to what kind of branches to match against",
52
+ choices=BranchScope.available_types(),
53
+ default_value=BranchScope.DEFAULT_BRANCH.value.name,
54
+ optional=False,
55
+ order_weight=2000,
56
+ allow_override=AllowOverrideType.NONE,
57
+ ),
58
+ ],
59
+ relationships=[
60
+ Rel(
61
+ name="action",
62
+ peer=InfrahubKind.ACTION,
63
+ description="The action to execute once the trigger conditions has been met",
64
+ identifier="core_action__core_triggerrule",
65
+ kind=RelKind.ATTRIBUTE,
66
+ cardinality=Cardinality.ONE,
67
+ optional=False,
68
+ order_weight=10000,
69
+ ),
70
+ ],
71
+ )
72
+
73
+ core_action = GenericSchema(
74
+ name="Action",
75
+ namespace="Core",
76
+ description="An action that can be executed by a trigger",
77
+ include_in_menu=False,
78
+ icon="mdi:cards-diamond-outline",
79
+ label="Core Action",
80
+ human_friendly_id=["name__value"],
81
+ order_by=["name__value"],
82
+ display_labels=["name__value"],
83
+ branch=BranchSupportType.AGNOSTIC,
84
+ uniqueness_constraints=[["name__value"]],
85
+ generate_profile=False,
86
+ attributes=[
87
+ Attr(
88
+ name="name",
89
+ description="Short descriptive name",
90
+ kind="Text",
91
+ unique=True,
92
+ order_weight=1000,
93
+ ),
94
+ Attr(
95
+ name="description",
96
+ description="A detailed description of the action",
97
+ kind="Text",
98
+ optional=True,
99
+ order_weight=2000,
100
+ ),
101
+ ],
102
+ relationships=[
103
+ Rel(
104
+ name="triggers",
105
+ description="The triggers that would execute this action once the triggering condition is met",
106
+ peer=InfrahubKind.TRIGGERRULE,
107
+ kind=RelKind.ATTRIBUTE,
108
+ cardinality=Cardinality.MANY,
109
+ identifier="core_action__core_triggerrule",
110
+ optional=True,
111
+ order_weight=10000,
112
+ ),
113
+ ],
114
+ )
115
+
116
+ core_node_trigger_match = GenericSchema(
117
+ name="NodeTriggerMatch",
118
+ namespace="Core",
119
+ description="A trigger match condition related to changes to nodes within the Infrahub database",
120
+ include_in_menu=False,
121
+ icon="mdi:match",
122
+ label="Node Trigger Match",
123
+ branch=BranchSupportType.AGNOSTIC,
124
+ generate_profile=False,
125
+ attributes=[],
126
+ relationships=[
127
+ Rel(
128
+ name="trigger",
129
+ peer="CoreNodeTriggerRule",
130
+ description="The node trigger that this match is connected to",
131
+ kind=RelKind.PARENT,
132
+ cardinality=Cardinality.ONE,
133
+ optional=False,
134
+ identifier="core_node_trigger_match__core_trigger_rule",
135
+ order_weight=10000,
136
+ ),
137
+ ],
138
+ )
139
+
140
+
141
+ core_generator_action = NodeSchema(
142
+ name="GeneratorAction",
143
+ namespace="Core",
144
+ description="An action that runs a generator definition once triggered",
145
+ include_in_menu=False,
146
+ icon="mdi:cards-diamond-outline",
147
+ label="Generator Action",
148
+ human_friendly_id=["name__value"],
149
+ order_by=["name__value"],
150
+ display_labels=["name__value"],
151
+ branch=BranchSupportType.AGNOSTIC,
152
+ uniqueness_constraints=[["name__value"]],
153
+ generate_profile=False,
154
+ inherit_from=[InfrahubKind.ACTION],
155
+ relationships=[
156
+ Rel(
157
+ name="generator",
158
+ description="The generator definition to execute once this action gets triggered",
159
+ peer=InfrahubKind.GENERATORDEFINITION,
160
+ kind=RelKind.ATTRIBUTE,
161
+ cardinality=Cardinality.ONE,
162
+ identifier="core_generator_action__generator_definition",
163
+ optional=False,
164
+ order_weight=4000,
165
+ ),
166
+ ],
167
+ )
168
+
169
+ core_group_action = NodeSchema(
170
+ name="GroupAction",
171
+ namespace="Core",
172
+ description="A group action that adds or removes members from a group once triggered",
173
+ include_in_menu=False,
174
+ icon="mdi:cards-diamond-outline",
175
+ label="Group Action",
176
+ human_friendly_id=["name__value"],
177
+ order_by=["name__value"],
178
+ display_labels=["name__value"],
179
+ branch=BranchSupportType.AGNOSTIC,
180
+ uniqueness_constraints=[["name__value"]],
181
+ generate_profile=False,
182
+ inherit_from=[InfrahubKind.ACTION],
183
+ attributes=[
184
+ Attr(
185
+ name="add_members",
186
+ kind="Boolean",
187
+ description="Defines if the action should add or remove members from a group when triggered",
188
+ unique=False,
189
+ optional=False,
190
+ default_value=True,
191
+ order_weight=3000,
192
+ ),
193
+ ],
194
+ relationships=[
195
+ Rel(
196
+ name="group",
197
+ peer=InfrahubKind.GENERICGROUP,
198
+ description="The target group of this action",
199
+ kind=RelKind.ATTRIBUTE,
200
+ cardinality=Cardinality.ONE,
201
+ identifier="core_action__group",
202
+ optional=False,
203
+ order_weight=4000,
204
+ ),
205
+ ],
206
+ )
207
+
208
+
209
+ core_node_trigger_rule = NodeSchema(
210
+ name="NodeTriggerRule",
211
+ namespace="Core",
212
+ description="A trigger rule that evaluates modifications to nodes within the Infrahub database",
213
+ include_in_menu=False,
214
+ icon="mdi:filter-cog-outline",
215
+ label="Node Trigger Rule",
216
+ human_friendly_id=["name__value"],
217
+ order_by=["name__value"],
218
+ display_labels=["name__value"],
219
+ branch=BranchSupportType.AGNOSTIC,
220
+ uniqueness_constraints=[["name__value"]],
221
+ generate_profile=False,
222
+ inherit_from=[InfrahubKind.TRIGGERRULE],
223
+ attributes=[
224
+ Attr(
225
+ name="node_kind",
226
+ kind="Text",
227
+ description="The kind of node to match against",
228
+ unique=False,
229
+ optional=False,
230
+ order_weight=3000,
231
+ ),
232
+ Attr(
233
+ name="mutation_action",
234
+ kind="Text",
235
+ description="The type of modification to match against",
236
+ enum=NodeAction.available_types(),
237
+ unique=False,
238
+ optional=False,
239
+ order_weight=4000,
240
+ ),
241
+ ],
242
+ relationships=[
243
+ Rel(
244
+ name="matches",
245
+ peer="CoreNodeTriggerMatch",
246
+ description="Use matches to configure the match condition for the selected node kind",
247
+ kind=RelKind.COMPONENT,
248
+ cardinality=Cardinality.MANY,
249
+ optional=True,
250
+ identifier="core_node_trigger_match__core_trigger_rule",
251
+ order_weight=8000,
252
+ ),
253
+ ],
254
+ )
255
+
256
+ core_node_trigger_attribute_match = NodeSchema(
257
+ name="NodeTriggerAttributeMatch",
258
+ namespace="Core",
259
+ description="A trigger match that matches against attribute changes on a node",
260
+ include_in_menu=False,
261
+ icon="mdi:match",
262
+ label="Node Trigger Attribute Match",
263
+ branch=BranchSupportType.AGNOSTIC,
264
+ generate_profile=False,
265
+ inherit_from=["CoreNodeTriggerMatch"],
266
+ attributes=[
267
+ Attr(
268
+ name="attribute_name",
269
+ kind="Text",
270
+ description="The attribue to match against",
271
+ unique=False,
272
+ optional=False,
273
+ order_weight=1000,
274
+ ),
275
+ Attr(
276
+ name="value",
277
+ kind="Text",
278
+ description="The value the attribute is updated to",
279
+ unique=False,
280
+ optional=True,
281
+ order_weight=2000,
282
+ ),
283
+ Attr(
284
+ name="value_previous",
285
+ kind="Text",
286
+ description="The previous value of the targeted attribute",
287
+ unique=False,
288
+ optional=True,
289
+ order_weight=3000,
290
+ ),
291
+ Attr(
292
+ name="value_match",
293
+ kind="Dropdown",
294
+ description="The value_match defines how the update will be evaluated, if it has to match the new value, the previous value or both",
295
+ choices=ValueMatch.available_types(),
296
+ default_value=ValueMatch.VALUE.value.name,
297
+ optional=False,
298
+ order_weight=5000,
299
+ ),
300
+ ],
301
+ relationships=[],
302
+ )
303
+
304
+ core_node_trigger_relationship_match = NodeSchema(
305
+ name="NodeTriggerRelationshipMatch",
306
+ namespace="Core",
307
+ description="A trigger match that matches against relationship changes on a node",
308
+ include_in_menu=False,
309
+ icon="mdi:match",
310
+ label="Node Trigger Relationship Match",
311
+ branch=BranchSupportType.AGNOSTIC,
312
+ generate_profile=False,
313
+ inherit_from=["CoreNodeTriggerMatch"],
314
+ attributes=[
315
+ Attr(
316
+ name="relationship_name",
317
+ kind="Text",
318
+ description="The name of the relationship to match against",
319
+ unique=False,
320
+ optional=False,
321
+ order_weight=1000,
322
+ ),
323
+ Attr(
324
+ name="added",
325
+ kind="Boolean",
326
+ description="Indicates if the relationship was added or removed",
327
+ unique=False,
328
+ optional=False,
329
+ default_value=True,
330
+ order_weight=2000,
331
+ ),
332
+ Attr(
333
+ name="peer",
334
+ kind="Text",
335
+ description="The node_id of the relationship peer to match against",
336
+ unique=False,
337
+ optional=True,
338
+ order_weight=3000,
339
+ ),
340
+ ],
341
+ relationships=[],
342
+ )
343
+
344
+
345
+ core_group_trigger_rule = NodeSchema(
346
+ name="GroupTriggerRule",
347
+ namespace="Core",
348
+ description="A trigger rule that matches against updates to memberships within groups",
349
+ include_in_menu=False,
350
+ icon="mdi:filter-cog-outline",
351
+ label="Group Trigger Rule",
352
+ human_friendly_id=["name__value"],
353
+ order_by=["name__value"],
354
+ display_labels=["name__value"],
355
+ branch=BranchSupportType.AGNOSTIC,
356
+ uniqueness_constraints=[["name__value"]],
357
+ generate_profile=False,
358
+ inherit_from=[InfrahubKind.TRIGGERRULE],
359
+ attributes=[
360
+ Attr(
361
+ name="members_added",
362
+ kind="Boolean",
363
+ description="Indicate if the match should be for when members are added or removed",
364
+ unique=False,
365
+ optional=False,
366
+ default_value=True,
367
+ order_weight=3000,
368
+ ),
369
+ ],
370
+ relationships=[
371
+ Rel(
372
+ name="group",
373
+ peer=InfrahubKind.GENERICGROUP,
374
+ description="The group to match against",
375
+ kind=RelKind.ATTRIBUTE,
376
+ cardinality=Cardinality.ONE,
377
+ identifier="core_group_trigger__group",
378
+ optional=False,
379
+ order_weight=4000,
380
+ ),
381
+ ],
382
+ )
@@ -0,0 +1,126 @@
1
+ from __future__ import annotations
2
+
3
+ from infrahub_sdk.graphql import Mutation
4
+ from prefect import flow
5
+ from prefect.client.orchestration import get_client
6
+
7
+ from infrahub import lock
8
+ from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
9
+ from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
10
+ from infrahub.trigger.models import TriggerType
11
+ from infrahub.trigger.setup import setup_triggers
12
+ from infrahub.workflows.utils import add_tags
13
+
14
+ from .gather import gather_trigger_action_rules
15
+ from .models import EventGroupMember # noqa: TC001 needed for prefect flow
16
+
17
+
18
+ @flow(
19
+ name="action-add-node-to-group",
20
+ flow_run_name="Adding node={node_id} to group={group_id}",
21
+ )
22
+ async def add_node_to_group(
23
+ branch_name: str,
24
+ node_id: str,
25
+ group_id: str,
26
+ context: InfrahubContext, # noqa: ARG001
27
+ service: InfrahubServices,
28
+ ) -> None:
29
+ await add_tags(branches=[branch_name], nodes=[node_id, group_id])
30
+
31
+ mutation = Mutation(
32
+ mutation="RelationshipAdd",
33
+ input_data={"data": {"id": group_id, "name": "members", "nodes": [{"id": node_id}]}},
34
+ query={"ok": None},
35
+ )
36
+
37
+ await service.client.execute_graphql(query=mutation.render(), branch_name=branch_name)
38
+
39
+
40
+ @flow(
41
+ name="action-remove-node-from-group",
42
+ flow_run_name="Removing node={node_id} from group={group_id}",
43
+ )
44
+ async def remove_node_from_group(
45
+ branch_name: str,
46
+ node_id: str,
47
+ group_id: str,
48
+ context: InfrahubContext, # noqa: ARG001
49
+ service: InfrahubServices,
50
+ ) -> None:
51
+ await add_tags(branches=[branch_name], nodes=[node_id, group_id])
52
+
53
+ mutation = Mutation(
54
+ mutation="RelationshipRemove",
55
+ input_data={"data": {"id": group_id, "name": "members", "nodes": [{"id": node_id}]}},
56
+ query={"ok": None},
57
+ )
58
+
59
+ await service.client.execute_graphql(query=mutation.render(), branch_name=branch_name)
60
+
61
+
62
+ @flow(
63
+ name="action-run-generator",
64
+ flow_run_name="Running generator generator_definition_id={generator_definition_id} for nodes={node_ids}",
65
+ )
66
+ async def run_generator(
67
+ branch_name: str,
68
+ node_ids: list[str],
69
+ generator_definition_id: str,
70
+ context: InfrahubContext, # noqa: ARG001
71
+ service: InfrahubServices,
72
+ ) -> None:
73
+ await add_tags(branches=[branch_name], nodes=node_ids + [generator_definition_id])
74
+ await _run_generator(
75
+ branch_name=branch_name, generator_definition_id=generator_definition_id, node_ids=node_ids, service=service
76
+ )
77
+
78
+
79
+ @flow(
80
+ name="action-run-generator-group-event",
81
+ flow_run_name="Running generator",
82
+ )
83
+ async def run_generator_group_event(
84
+ branch_name: str,
85
+ members: list[EventGroupMember],
86
+ generator_definition_id: str,
87
+ context: InfrahubContext, # noqa: ARG001
88
+ service: InfrahubServices,
89
+ ) -> None:
90
+ node_ids = [node.id for node in members]
91
+ await add_tags(branches=[branch_name], nodes=node_ids + [generator_definition_id])
92
+ await _run_generator(
93
+ branch_name=branch_name, generator_definition_id=generator_definition_id, node_ids=node_ids, service=service
94
+ )
95
+
96
+
97
+ @flow(
98
+ name="configure-action-rules",
99
+ flow_run_name="Configure updated action rules and triggers",
100
+ )
101
+ async def configure_action_rules(
102
+ service: InfrahubServices,
103
+ ) -> None:
104
+ async with lock.registry.get(name="configure-action-rules", namespace="trigger-rules", local=False):
105
+ triggers = await gather_trigger_action_rules(db=service.database)
106
+ async with get_client(sync_client=False) as prefect_client:
107
+ await setup_triggers(
108
+ client=prefect_client,
109
+ triggers=triggers,
110
+ trigger_type=TriggerType.ACTION_TRIGGER_RULE,
111
+ ) # type: ignore[misc]
112
+
113
+
114
+ async def _run_generator(
115
+ branch_name: str,
116
+ node_ids: list[str],
117
+ generator_definition_id: str,
118
+ service: InfrahubServices,
119
+ ) -> None:
120
+ mutation = Mutation(
121
+ mutation="CoreGeneratorDefinitionRun",
122
+ input_data={"data": {"id": generator_definition_id, "nodes": node_ids}},
123
+ query={"ok": None},
124
+ )
125
+
126
+ await service.client.execute_graphql(query=mutation.render(), branch_name=branch_name)
@@ -0,0 +1,21 @@
1
+ from infrahub.events.node_action import NodeCreatedEvent, NodeDeletedEvent, NodeUpdatedEvent
2
+ from infrahub.trigger.models import BuiltinTriggerDefinition, EventTrigger, ExecuteWorkflow
3
+ from infrahub.workflows.catalogue import CONFIGURE_ACTION_RULES
4
+
5
+ from .constants import NODES_THAT_TRIGGER_ACTION_RULES_SETUP
6
+
7
+ TRIGGER_ACTION_RULE_UPDATE = BuiltinTriggerDefinition(
8
+ name="action-trigger-setup-all",
9
+ trigger=EventTrigger(
10
+ events={NodeCreatedEvent.event_name, NodeDeletedEvent.event_name, NodeUpdatedEvent.event_name},
11
+ match={
12
+ "infrahub.node.kind": NODES_THAT_TRIGGER_ACTION_RULES_SETUP,
13
+ },
14
+ ),
15
+ actions=[
16
+ ExecuteWorkflow(
17
+ workflow=CONFIGURE_ACTION_RULES,
18
+ parameters={},
19
+ ),
20
+ ],
21
+ )
infrahub/cli/db.py CHANGED
@@ -489,11 +489,10 @@ WITH n
489
489
  ORDER BY %(id_func)s(n)
490
490
  SKIP toInteger($offset)
491
491
  LIMIT toInteger($limit)
492
- CALL {
492
+ CALL (n) {
493
493
  // --------------
494
494
  // get all the nodes and edges linked to this node up to 2 steps away, excluding IS_PART_OF
495
495
  // --------------
496
- WITH n
497
496
  MATCH (n)-[r1]-(v1)-[r2]-(v2)
498
497
  WHERE type(r1) <> "IS_PART_OF"
499
498
  WITH collect([v1, v2]) AS vertex_pairs, collect([r1, r2]) AS edge_pairs