infrahub-server 1.3.0b1__py3-none-any.whl → 1.3.0b3__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 (81) hide show
  1. infrahub/actions/constants.py +87 -0
  2. infrahub/actions/gather.py +3 -3
  3. infrahub/actions/models.py +10 -8
  4. infrahub/actions/parsers.py +6 -6
  5. infrahub/actions/schema.py +46 -37
  6. infrahub/actions/tasks.py +4 -11
  7. infrahub/branch/__init__.py +0 -0
  8. infrahub/branch/tasks.py +29 -0
  9. infrahub/branch/triggers.py +22 -0
  10. infrahub/cli/db.py +2 -2
  11. infrahub/computed_attribute/gather.py +3 -1
  12. infrahub/computed_attribute/tasks.py +23 -29
  13. infrahub/core/constants/__init__.py +5 -0
  14. infrahub/core/constants/database.py +1 -0
  15. infrahub/core/convert_object_type/conversion.py +1 -1
  16. infrahub/core/diff/query/save.py +67 -40
  17. infrahub/core/diff/query/time_range_query.py +0 -1
  18. infrahub/core/graph/__init__.py +1 -1
  19. infrahub/core/migrations/graph/__init__.py +6 -0
  20. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +0 -2
  21. infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
  22. infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
  23. infrahub/core/migrations/query/attribute_add.py +13 -9
  24. infrahub/core/migrations/query/relationship_duplicate.py +0 -1
  25. infrahub/core/migrations/schema/node_remove.py +0 -1
  26. infrahub/core/node/__init__.py +2 -0
  27. infrahub/core/node/base.py +1 -1
  28. infrahub/core/path.py +1 -1
  29. infrahub/core/protocols.py +4 -3
  30. infrahub/core/query/node.py +1 -1
  31. infrahub/core/query/relationship.py +2 -2
  32. infrahub/core/query/standard_node.py +19 -5
  33. infrahub/core/relationship/constraints/peer_relatives.py +72 -0
  34. infrahub/core/relationship/model.py +1 -1
  35. infrahub/core/schema/attribute_schema.py +26 -6
  36. infrahub/core/schema/basenode_schema.py +2 -2
  37. infrahub/core/schema/definitions/core/resource_pool.py +9 -0
  38. infrahub/core/schema/definitions/internal.py +9 -1
  39. infrahub/core/schema/generated/attribute_schema.py +4 -4
  40. infrahub/core/schema/generated/relationship_schema.py +6 -1
  41. infrahub/core/schema/manager.py +4 -2
  42. infrahub/core/schema/schema_branch.py +14 -5
  43. infrahub/core/validators/tasks.py +1 -1
  44. infrahub/database/__init__.py +1 -1
  45. infrahub/database/validation.py +100 -0
  46. infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
  47. infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
  48. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  49. infrahub/dependencies/registry.py +2 -0
  50. infrahub/events/models.py +1 -1
  51. infrahub/graphql/mutations/main.py +1 -1
  52. infrahub/graphql/mutations/resource_manager.py +13 -13
  53. infrahub/graphql/resolvers/many_relationship.py +1 -1
  54. infrahub/graphql/resolvers/resolver.py +2 -2
  55. infrahub/graphql/resolvers/single_relationship.py +1 -1
  56. infrahub/menu/menu.py +5 -4
  57. infrahub/message_bus/operations/refresh/registry.py +3 -3
  58. infrahub/patch/queries/delete_duplicated_edges.py +40 -29
  59. infrahub/pools/registration.py +22 -0
  60. infrahub/pools/tasks.py +56 -0
  61. infrahub/proposed_change/tasks.py +8 -8
  62. infrahub/schema/__init__.py +0 -0
  63. infrahub/schema/tasks.py +27 -0
  64. infrahub/schema/triggers.py +23 -0
  65. infrahub/trigger/catalogue.py +4 -0
  66. infrahub/trigger/models.py +5 -4
  67. infrahub/trigger/setup.py +26 -2
  68. infrahub/trigger/tasks.py +1 -1
  69. infrahub/webhook/tasks.py +6 -9
  70. infrahub/workflows/catalogue.py +27 -1
  71. {infrahub_server-1.3.0b1.dist-info → infrahub_server-1.3.0b3.dist-info}/METADATA +1 -1
  72. {infrahub_server-1.3.0b1.dist-info → infrahub_server-1.3.0b3.dist-info}/RECORD +80 -67
  73. infrahub_testcontainers/container.py +239 -64
  74. infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
  75. infrahub_testcontainers/docker-compose.test.yml +1 -0
  76. infrahub_testcontainers/helpers.py +15 -1
  77. infrahub_testcontainers/plugin.py +9 -0
  78. infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -106
  79. {infrahub_server-1.3.0b1.dist-info → infrahub_server-1.3.0b3.dist-info}/LICENSE.txt +0 -0
  80. {infrahub_server-1.3.0b1.dist-info → infrahub_server-1.3.0b3.dist-info}/WHEEL +0 -0
  81. {infrahub_server-1.3.0b1.dist-info → infrahub_server-1.3.0b3.dist-info}/entry_points.txt +0 -0
@@ -46,6 +46,93 @@ class BranchScope(Enum):
46
46
  raise NotImplementedError(f"The defined value {value} doesn't match a branch scope")
47
47
 
48
48
 
49
+ class MemberAction(Enum):
50
+ ADD_MEMBER = DropdownChoice(
51
+ name="add_member",
52
+ label="Add member",
53
+ description="Add impacted member to the selected group",
54
+ color="#86efac",
55
+ )
56
+ REMOVE_MEMBER = DropdownChoice(
57
+ name="remove_member",
58
+ label="Remove member",
59
+ description="Remove impacted member from the selected group",
60
+ color="#fef08a",
61
+ )
62
+
63
+ @classmethod
64
+ def available_types(cls) -> list[DropdownChoice]:
65
+ return [cls.__members__[member].value for member in list(cls.__members__)]
66
+
67
+ @classmethod
68
+ def from_value(cls, value: str) -> MemberAction:
69
+ for member in cls.__members__:
70
+ if value == cls.__members__[member].value.name:
71
+ return cls.__members__[member]
72
+
73
+ raise NotImplementedError(f"The defined value {value} doesn't match a member action")
74
+
75
+
76
+ class MemberUpdate(Enum):
77
+ ADDED = DropdownChoice(
78
+ name="added",
79
+ label="Added",
80
+ description="Trigger when members are added to this group",
81
+ color="#86efac",
82
+ )
83
+ REMOVED = DropdownChoice(
84
+ name="removed",
85
+ label="Removed",
86
+ description="Trigger when members are removed from this group",
87
+ color="#fef08a",
88
+ )
89
+
90
+ @classmethod
91
+ def available_types(cls) -> list[DropdownChoice]:
92
+ return [cls.__members__[member].value for member in list(cls.__members__)]
93
+
94
+ @classmethod
95
+ def from_value(cls, value: str) -> MemberUpdate:
96
+ for member in cls.__members__:
97
+ if value == cls.__members__[member].value.name:
98
+ return cls.__members__[member]
99
+
100
+ raise NotImplementedError(f"The defined value {value} doesn't match a MemberUpdate")
101
+
102
+
103
+ class RelationshipMatch(Enum):
104
+ ADDED = DropdownChoice(
105
+ name="added",
106
+ label="Added",
107
+ description="Check if the selected relationship was added",
108
+ color="#86efac",
109
+ )
110
+ REMOVED = DropdownChoice(
111
+ name="removed",
112
+ label="Removed",
113
+ description="Check if the selected relationship was removed",
114
+ color="#fef08a",
115
+ )
116
+ UPDATED = DropdownChoice(
117
+ name="updated",
118
+ label="Updated",
119
+ description="Check if the selected relationship was updated, added or removed.",
120
+ color="#e5e7eb",
121
+ )
122
+
123
+ @classmethod
124
+ def available_types(cls) -> list[DropdownChoice]:
125
+ return [cls.__members__[member].value for member in list(cls.__members__)]
126
+
127
+ @classmethod
128
+ def from_value(cls, value: str) -> RelationshipMatch:
129
+ for member in cls.__members__:
130
+ if value == cls.__members__[member].value.name:
131
+ return cls.__members__[member]
132
+
133
+ raise NotImplementedError(f"The defined value {value} doesn't match a RelationshipMatch")
134
+
135
+
49
136
  class ValueMatch(Enum):
50
137
  VALUE = DropdownChoice(
51
138
  name="value",
@@ -46,7 +46,7 @@ async def gather_trigger_action_rules(db: InfrahubDatabase) -> list[ActionTrigge
46
46
  },
47
47
  "... on CoreNodeTriggerRelationshipMatch": {
48
48
  "relationship_name": {"value": None},
49
- "added": {"value": None},
49
+ "modification_type": {"value": None},
50
50
  "peer": {"value": None},
51
51
  },
52
52
  }
@@ -54,7 +54,7 @@ async def gather_trigger_action_rules(db: InfrahubDatabase) -> list[ActionTrigge
54
54
  },
55
55
  },
56
56
  "... on CoreGroupTriggerRule": {
57
- "members_added": {"value": None},
57
+ "member_update": {"value": None},
58
58
  "group": {
59
59
  "node": {
60
60
  "id": None,
@@ -68,7 +68,7 @@ async def gather_trigger_action_rules(db: InfrahubDatabase) -> list[ActionTrigge
68
68
  "id": None,
69
69
  "name": {"value": None},
70
70
  "... on CoreGroupAction": {
71
- "add_members": {"value": None},
71
+ "member_action": {"value": None},
72
72
  "group": {
73
73
  "node": {
74
74
  "id": None,
@@ -23,7 +23,7 @@ from infrahub.workflows.catalogue import (
23
23
  REMOVE_ADD_NODE_FROM_GROUP,
24
24
  )
25
25
 
26
- from .constants import BranchScope, ValueMatch
26
+ from .constants import BranchScope, MemberAction, MemberUpdate, RelationshipMatch, ValueMatch
27
27
 
28
28
 
29
29
  class EventGroupMember(BaseModel):
@@ -40,7 +40,7 @@ class CoreGeneratorAction(CoreAction):
40
40
 
41
41
 
42
42
  class CoreGroupAction(CoreAction):
43
- add_members: bool
43
+ member_action: MemberAction
44
44
  group_id: str
45
45
 
46
46
 
@@ -52,7 +52,7 @@ class CoreTriggerRule(BaseModel):
52
52
 
53
53
 
54
54
  class CoreGroupTriggerRule(CoreTriggerRule):
55
- members_added: bool
55
+ member_update: MemberUpdate
56
56
  group_id: str
57
57
  group_kind: str
58
58
 
@@ -70,7 +70,7 @@ class CoreNodeTriggerAttributeMatch(CoreNodeTriggerMatch):
70
70
 
71
71
  class CoreNodeTriggerRelationshipMatch(CoreNodeTriggerMatch):
72
72
  relationship_name: str
73
- added: bool
73
+ modification_type: RelationshipMatch
74
74
  peer: str | None
75
75
 
76
76
 
@@ -135,14 +135,16 @@ class ActionTriggerRuleTriggerDefinition(TriggerDefinition):
135
135
  match_related["infrahub.attribute.value_previous"] = match.value_previous or ""
136
136
 
137
137
  elif isinstance(match, CoreNodeTriggerRelationshipMatch):
138
- peer_status = "added" if match.added else "removed"
139
138
  match_related = {
140
139
  "prefect.resource.role": "infrahub.node.relationship_update",
141
140
  "infrahub.field.name": match.relationship_name,
142
- "infrahub.relationship.peer_status": peer_status,
143
141
  }
144
142
  if isinstance(match.peer, str):
145
143
  match_related["infrahub.relationship.peer_id"] = match.peer
144
+
145
+ if match.modification_type != RelationshipMatch.UPDATED:
146
+ match_related["infrahub.relationship.peer_status"] = match.modification_type.value.name
147
+
146
148
  related_matches.append(match_related)
147
149
 
148
150
  event_trigger.match_related = related_matches or {}
@@ -164,7 +166,7 @@ class ActionTriggerRuleTriggerDefinition(TriggerDefinition):
164
166
  },
165
167
  )
166
168
  elif isinstance(trigger_rule.action, CoreGroupAction):
167
- if trigger_rule.action.add_members:
169
+ if trigger_rule.action.member_action == MemberAction.ADD_MEMBER:
168
170
  flow = ACTION_ADD_NODE_TO_GROUP
169
171
  else:
170
172
  flow = REMOVE_ADD_NODE_FROM_GROUP
@@ -198,7 +200,7 @@ class ActionTriggerRuleTriggerDefinition(TriggerDefinition):
198
200
  ) -> Self:
199
201
  event_trigger = EventTrigger()
200
202
 
201
- if trigger_rule.members_added:
203
+ if trigger_rule.member_update == MemberUpdate.ADDED:
202
204
  event_trigger.events.add(GroupMemberAddedEvent.event_name)
203
205
  else:
204
206
  event_trigger.events.add(GroupMemberRemovedEvent.event_name)
@@ -2,7 +2,7 @@ from typing import Any
2
2
 
3
3
  from infrahub.core.constants import InfrahubKind
4
4
 
5
- from .constants import BranchScope, ValueMatch
5
+ from .constants import BranchScope, MemberAction, MemberUpdate, RelationshipMatch, ValueMatch
6
6
  from .models import (
7
7
  CoreAction,
8
8
  CoreGeneratorAction,
@@ -35,14 +35,14 @@ def _parse_graphql_node(data: dict[str, Any]) -> CoreTriggerRule | None:
35
35
  action = _parse_graphql_action_response(data=data["action"]["node"])
36
36
  match typename:
37
37
  case "CoreGroupTriggerRule":
38
- members_added = data["members_added"]["value"]
38
+ member_update = MemberUpdate.from_value(data["member_update"]["value"])
39
39
  group_id = data["group"]["node"]["id"]
40
40
  group_kind = data["group"]["node"]["__typename"]
41
41
  return CoreGroupTriggerRule(
42
42
  name=name,
43
43
  branch_scope=branch_scope,
44
44
  action=action,
45
- members_added=members_added,
45
+ member_update=member_update,
46
46
  group_id=group_id,
47
47
  group_kind=group_kind,
48
48
  active=active,
@@ -70,9 +70,9 @@ def _parse_graphql_action_response(data: dict[str, Any]) -> CoreAction:
70
70
  generator_id = data["generator"]["node"]["id"]
71
71
  return CoreGeneratorAction(generator_id=generator_id)
72
72
  case "CoreGroupAction":
73
- add_members = data["add_members"]["value"]
73
+ member_action = MemberAction.from_value(data["member_action"]["value"])
74
74
  group_id = data["group"]["node"]["id"]
75
- return CoreGroupAction(add_members=add_members, group_id=group_id)
75
+ return CoreGroupAction(member_action=member_action, group_id=group_id)
76
76
 
77
77
  raise NotImplementedError(f"{typename} is not a valid CoreAction")
78
78
 
@@ -96,7 +96,7 @@ def _parse_node_trigger_matches(data: list[dict[str, Any]]) -> list[CoreNodeTrig
96
96
  matches.append(
97
97
  CoreNodeTriggerRelationshipMatch(
98
98
  relationship_name=node["relationship_name"]["value"],
99
- added=node["added"]["value"],
99
+ modification_type=RelationshipMatch.from_value(node["modification_type"]["value"]),
100
100
  peer=node["peer"]["value"],
101
101
  )
102
102
  )
@@ -1,4 +1,11 @@
1
- from infrahub.actions.constants import BranchScope, NodeAction, ValueMatch
1
+ from infrahub.actions.constants import (
2
+ BranchScope,
3
+ MemberAction,
4
+ MemberUpdate,
5
+ NodeAction,
6
+ RelationshipMatch,
7
+ ValueMatch,
8
+ )
2
9
  from infrahub.core.constants import AllowOverrideType, BranchSupportType, InfrahubKind
3
10
  from infrahub.core.constants import RelationshipCardinality as Cardinality
4
11
  from infrahub.core.constants import RelationshipKind as RelKind
@@ -28,14 +35,14 @@ core_trigger_rule = GenericSchema(
28
35
  kind="Text",
29
36
  description="The name of the trigger rule",
30
37
  unique=True,
31
- order_weight=1000,
38
+ order_weight=100,
32
39
  ),
33
40
  Attr(
34
41
  name="description",
35
42
  kind="Text",
36
43
  description="A longer description to define the purpose of this trigger",
37
44
  optional=True,
38
- order_weight=2000,
45
+ order_weight=200,
39
46
  ),
40
47
  Attr(
41
48
  name="active",
@@ -43,7 +50,7 @@ core_trigger_rule = GenericSchema(
43
50
  description="Indicates if this trigger is enabled or if it's just prepared, could be useful as you are setting up a trigger",
44
51
  optional=False,
45
52
  default_value=True,
46
- order_weight=2000,
53
+ order_weight=200,
47
54
  ),
48
55
  Attr(
49
56
  name="branch_scope",
@@ -52,7 +59,7 @@ core_trigger_rule = GenericSchema(
52
59
  choices=BranchScope.available_types(),
53
60
  default_value=BranchScope.DEFAULT_BRANCH.value.name,
54
61
  optional=False,
55
- order_weight=2000,
62
+ order_weight=200,
56
63
  allow_override=AllowOverrideType.NONE,
57
64
  ),
58
65
  ],
@@ -65,7 +72,7 @@ core_trigger_rule = GenericSchema(
65
72
  kind=RelKind.ATTRIBUTE,
66
73
  cardinality=Cardinality.ONE,
67
74
  optional=False,
68
- order_weight=10000,
75
+ order_weight=1000,
69
76
  ),
70
77
  ],
71
78
  )
@@ -89,14 +96,14 @@ core_action = GenericSchema(
89
96
  description="Short descriptive name",
90
97
  kind="Text",
91
98
  unique=True,
92
- order_weight=1000,
99
+ order_weight=100,
93
100
  ),
94
101
  Attr(
95
102
  name="description",
96
103
  description="A detailed description of the action",
97
104
  kind="Text",
98
105
  optional=True,
99
- order_weight=2000,
106
+ order_weight=200,
100
107
  ),
101
108
  ],
102
109
  relationships=[
@@ -108,7 +115,7 @@ core_action = GenericSchema(
108
115
  cardinality=Cardinality.MANY,
109
116
  identifier="core_action__core_triggerrule",
110
117
  optional=True,
111
- order_weight=10000,
118
+ order_weight=1000,
112
119
  ),
113
120
  ],
114
121
  )
@@ -132,7 +139,7 @@ core_node_trigger_match = GenericSchema(
132
139
  cardinality=Cardinality.ONE,
133
140
  optional=False,
134
141
  identifier="core_node_trigger_match__core_trigger_rule",
135
- order_weight=10000,
142
+ order_weight=1000,
136
143
  ),
137
144
  ],
138
145
  )
@@ -161,7 +168,7 @@ core_generator_action = NodeSchema(
161
168
  cardinality=Cardinality.ONE,
162
169
  identifier="core_generator_action__generator_definition",
163
170
  optional=False,
164
- order_weight=4000,
171
+ order_weight=400,
165
172
  ),
166
173
  ],
167
174
  )
@@ -182,13 +189,14 @@ core_group_action = NodeSchema(
182
189
  inherit_from=[InfrahubKind.ACTION],
183
190
  attributes=[
184
191
  Attr(
185
- name="add_members",
186
- kind="Boolean",
192
+ name="member_action",
193
+ kind="Dropdown",
187
194
  description="Defines if the action should add or remove members from a group when triggered",
195
+ choices=MemberAction.available_types(),
196
+ default_value=MemberAction.ADD_MEMBER.value.name,
188
197
  unique=False,
189
198
  optional=False,
190
- default_value=True,
191
- order_weight=3000,
199
+ order_weight=300,
192
200
  ),
193
201
  ],
194
202
  relationships=[
@@ -200,7 +208,7 @@ core_group_action = NodeSchema(
200
208
  cardinality=Cardinality.ONE,
201
209
  identifier="core_action__group",
202
210
  optional=False,
203
- order_weight=4000,
211
+ order_weight=400,
204
212
  ),
205
213
  ],
206
214
  )
@@ -227,7 +235,7 @@ core_node_trigger_rule = NodeSchema(
227
235
  description="The kind of node to match against",
228
236
  unique=False,
229
237
  optional=False,
230
- order_weight=3000,
238
+ order_weight=300,
231
239
  ),
232
240
  Attr(
233
241
  name="mutation_action",
@@ -236,7 +244,7 @@ core_node_trigger_rule = NodeSchema(
236
244
  enum=NodeAction.available_types(),
237
245
  unique=False,
238
246
  optional=False,
239
- order_weight=4000,
247
+ order_weight=400,
240
248
  ),
241
249
  ],
242
250
  relationships=[
@@ -248,7 +256,7 @@ core_node_trigger_rule = NodeSchema(
248
256
  cardinality=Cardinality.MANY,
249
257
  optional=True,
250
258
  identifier="core_node_trigger_match__core_trigger_rule",
251
- order_weight=8000,
259
+ order_weight=800,
252
260
  ),
253
261
  ],
254
262
  )
@@ -270,7 +278,7 @@ core_node_trigger_attribute_match = NodeSchema(
270
278
  description="The attribue to match against",
271
279
  unique=False,
272
280
  optional=False,
273
- order_weight=1000,
281
+ order_weight=100,
274
282
  ),
275
283
  Attr(
276
284
  name="value",
@@ -278,7 +286,7 @@ core_node_trigger_attribute_match = NodeSchema(
278
286
  description="The value the attribute is updated to",
279
287
  unique=False,
280
288
  optional=True,
281
- order_weight=2000,
289
+ order_weight=200,
282
290
  ),
283
291
  Attr(
284
292
  name="value_previous",
@@ -286,7 +294,7 @@ core_node_trigger_attribute_match = NodeSchema(
286
294
  description="The previous value of the targeted attribute",
287
295
  unique=False,
288
296
  optional=True,
289
- order_weight=3000,
297
+ order_weight=300,
290
298
  ),
291
299
  Attr(
292
300
  name="value_match",
@@ -295,7 +303,7 @@ core_node_trigger_attribute_match = NodeSchema(
295
303
  choices=ValueMatch.available_types(),
296
304
  default_value=ValueMatch.VALUE.value.name,
297
305
  optional=False,
298
- order_weight=5000,
306
+ order_weight=500,
299
307
  ),
300
308
  ],
301
309
  relationships=[],
@@ -318,16 +326,17 @@ core_node_trigger_relationship_match = NodeSchema(
318
326
  description="The name of the relationship to match against",
319
327
  unique=False,
320
328
  optional=False,
321
- order_weight=1000,
329
+ order_weight=100,
322
330
  ),
323
331
  Attr(
324
- name="added",
325
- kind="Boolean",
326
- description="Indicates if the relationship was added or removed",
327
- unique=False,
332
+ name="modification_type",
333
+ kind="Dropdown",
334
+ description="Indicates if the relationship was added or removed or just updated in any way",
335
+ choices=RelationshipMatch.available_types(),
336
+ default_value=RelationshipMatch.ADDED.value.name,
328
337
  optional=False,
329
- default_value=True,
330
- order_weight=2000,
338
+ order_weight=200,
339
+ allow_override=AllowOverrideType.NONE,
331
340
  ),
332
341
  Attr(
333
342
  name="peer",
@@ -335,7 +344,7 @@ core_node_trigger_relationship_match = NodeSchema(
335
344
  description="The node_id of the relationship peer to match against",
336
345
  unique=False,
337
346
  optional=True,
338
- order_weight=3000,
347
+ order_weight=300,
339
348
  ),
340
349
  ],
341
350
  relationships=[],
@@ -358,13 +367,13 @@ core_group_trigger_rule = NodeSchema(
358
367
  inherit_from=[InfrahubKind.TRIGGERRULE],
359
368
  attributes=[
360
369
  Attr(
361
- name="members_added",
362
- kind="Boolean",
370
+ name="member_update",
371
+ kind="Dropdown",
363
372
  description="Indicate if the match should be for when members are added or removed",
364
- unique=False,
373
+ choices=MemberUpdate.available_types(),
374
+ default_value=MemberUpdate.ADDED.value.name,
365
375
  optional=False,
366
- default_value=True,
367
- order_weight=3000,
376
+ order_weight=300,
368
377
  ),
369
378
  ],
370
379
  relationships=[
@@ -376,7 +385,7 @@ core_group_trigger_rule = NodeSchema(
376
385
  cardinality=Cardinality.ONE,
377
386
  identifier="core_group_trigger__group",
378
387
  optional=False,
379
- order_weight=4000,
388
+ order_weight=400,
380
389
  ),
381
390
  ],
382
391
  )
infrahub/actions/tasks.py CHANGED
@@ -2,13 +2,11 @@ from __future__ import annotations
2
2
 
3
3
  from infrahub_sdk.graphql import Mutation
4
4
  from prefect import flow
5
- from prefect.client.orchestration import get_client
6
5
 
7
- from infrahub import lock
8
6
  from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
9
7
  from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
10
8
  from infrahub.trigger.models import TriggerType
11
- from infrahub.trigger.setup import setup_triggers
9
+ from infrahub.trigger.setup import setup_triggers_specific
12
10
  from infrahub.workflows.utils import add_tags
13
11
 
14
12
  from .gather import gather_trigger_action_rules
@@ -101,14 +99,9 @@ async def run_generator_group_event(
101
99
  async def configure_action_rules(
102
100
  service: InfrahubServices,
103
101
  ) -> 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]
102
+ await setup_triggers_specific(
103
+ gatherer=gather_trigger_action_rules, trigger_type=TriggerType.ACTION_TRIGGER_RULE, db=service.database
104
+ ) # type: ignore[misc]
112
105
 
113
106
 
114
107
  async def _run_generator(
File without changes
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from prefect import flow
4
+ from prefect.logging import get_run_logger
5
+
6
+ from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
7
+ from infrahub.core.registry import registry
8
+ from infrahub.pools.tasks import validate_schema_number_pools
9
+ from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
10
+ from infrahub.workflows.utils import wait_for_schema_to_converge
11
+
12
+
13
+ @flow(
14
+ name="branch-merged",
15
+ flow_run_name="Running actions after '{source_branch}' was merged",
16
+ )
17
+ async def branch_merged(
18
+ source_branch: str, # noqa: ARG001
19
+ context: InfrahubContext,
20
+ service: InfrahubServices,
21
+ target_branch: str | None = None,
22
+ ) -> None:
23
+ target_branch = target_branch or registry.default_branch
24
+ log = get_run_logger()
25
+ await wait_for_schema_to_converge(
26
+ branch_name=target_branch, component=service.component, db=service.database, log=log
27
+ )
28
+
29
+ await validate_schema_number_pools(branch_name=target_branch, context=context, service=service)
@@ -0,0 +1,22 @@
1
+ from infrahub.events.branch_action import BranchMergedEvent
2
+ from infrahub.trigger.models import BuiltinTriggerDefinition, EventTrigger, ExecuteWorkflow
3
+ from infrahub.workflows.catalogue import BRANCH_MERGED
4
+
5
+ TRIGGER_BRANCH_MERGED = BuiltinTriggerDefinition(
6
+ name="branch-merged-trigger",
7
+ trigger=EventTrigger(
8
+ events={BranchMergedEvent.event_name},
9
+ ),
10
+ actions=[
11
+ ExecuteWorkflow(
12
+ workflow=BRANCH_MERGED,
13
+ parameters={
14
+ "source_branch": "{{ event.payload['data']['branch_name'] }}",
15
+ "context": {
16
+ "__prefect_kind": "json",
17
+ "value": {"__prefect_kind": "jinja", "template": "{{ event.payload['context'] | tojson }}"},
18
+ },
19
+ },
20
+ ),
21
+ ],
22
+ )
infrahub/cli/db.py CHANGED
@@ -326,7 +326,7 @@ async def migrate_database(db: InfrahubDatabase, initialize: bool = False, check
326
326
  root_node.graph_version = migration.minimum_version + 1
327
327
  await root_node.save(db=db)
328
328
 
329
- if not execution_result.success or validation_result and not validation_result.success:
329
+ if not execution_result.success or (validation_result and not validation_result.success):
330
330
  rprint(f"Migration: {migration.name} {FAILED_BADGE}")
331
331
  for error in execution_result.errors:
332
332
  rprint(f" {error}")
@@ -449,7 +449,7 @@ async def selected_export_cmd(
449
449
  ctx: typer.Context,
450
450
  kinds: list[str] = typer.Option([], help="Node kinds to export"), # noqa: B008
451
451
  uuids: list[str] = typer.Option([], help="UUIDs of nodes to export"), # noqa: B008
452
- query_limit: int = typer.Option(1000, help="Maximum batch size of export query"), # noqa: B008
452
+ query_limit: int = typer.Option(1000, help="Maximum batch size of export query"),
453
453
  export_dir: Path = typer.Option(Path("infrahub-exports"), help="Path of directory to save exports"), # noqa: B008
454
454
  config_file: str = typer.Argument("infrahub.toml", envvar="INFRAHUB_CONFIG"),
455
455
  ) -> None:
@@ -100,7 +100,9 @@ async def gather_python_transform_attributes(
100
100
  name="gather-trigger-computed-attribute-jinja2",
101
101
  cache_policy=NONE,
102
102
  )
103
- async def gather_trigger_computed_attribute_jinja2() -> list[ComputedAttrJinja2TriggerDefinition]:
103
+ async def gather_trigger_computed_attribute_jinja2(
104
+ db: InfrahubDatabase | None = None, # noqa: ARG001 Needed to have a common function signature for gathering functions
105
+ ) -> list[ComputedAttrJinja2TriggerDefinition]:
104
106
  log = get_run_logger()
105
107
 
106
108
  # Build a list of all branches to process based on which branch is different from main