infrahub-server 1.2.9rc0__py3-none-any.whl → 1.3.0a0__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/actions/constants.py +86 -0
- infrahub/actions/gather.py +114 -0
- infrahub/actions/models.py +241 -0
- infrahub/actions/parsers.py +104 -0
- infrahub/actions/schema.py +382 -0
- infrahub/actions/tasks.py +126 -0
- infrahub/actions/triggers.py +21 -0
- infrahub/cli/db.py +1 -2
- infrahub/computed_attribute/models.py +13 -0
- infrahub/computed_attribute/tasks.py +48 -26
- infrahub/config.py +9 -0
- infrahub/core/account.py +24 -47
- infrahub/core/attribute.py +53 -14
- infrahub/core/branch/models.py +8 -9
- infrahub/core/branch/tasks.py +0 -2
- infrahub/core/constants/infrahubkind.py +8 -0
- infrahub/core/constraint/node/runner.py +1 -1
- infrahub/core/convert_object_type/__init__.py +0 -0
- infrahub/core/convert_object_type/conversion.py +122 -0
- infrahub/core/convert_object_type/schema_mapping.py +56 -0
- infrahub/core/diff/calculator.py +65 -11
- infrahub/core/diff/combiner.py +38 -31
- infrahub/core/diff/coordinator.py +44 -28
- infrahub/core/diff/data_check_synchronizer.py +3 -2
- infrahub/core/diff/enricher/hierarchy.py +36 -27
- infrahub/core/diff/ipam_diff_parser.py +5 -4
- infrahub/core/diff/merger/merger.py +46 -16
- infrahub/core/diff/merger/serializer.py +1 -0
- infrahub/core/diff/model/field_specifiers_map.py +64 -0
- infrahub/core/diff/model/path.py +58 -58
- infrahub/core/diff/parent_node_adder.py +14 -16
- infrahub/core/diff/query/all_conflicts.py +1 -5
- infrahub/core/diff/query/artifact.py +10 -20
- infrahub/core/diff/query/diff_get.py +3 -6
- infrahub/core/diff/query/drop_nodes.py +42 -0
- infrahub/core/diff/query/field_specifiers.py +8 -7
- infrahub/core/diff/query/field_summary.py +2 -4
- infrahub/core/diff/query/filters.py +15 -1
- infrahub/core/diff/query/merge.py +284 -101
- infrahub/core/diff/query/save.py +26 -34
- infrahub/core/diff/query/summary_counts_enricher.py +34 -54
- infrahub/core/diff/query_parser.py +55 -65
- infrahub/core/diff/repository/deserializer.py +38 -24
- infrahub/core/diff/repository/repository.py +31 -12
- infrahub/core/diff/tasks.py +3 -3
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/manager.py +14 -11
- infrahub/core/migrations/graph/__init__.py +2 -0
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +1 -2
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +2 -4
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +11 -22
- infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -6
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +1 -2
- infrahub/core/migrations/graph/m024_missing_hierarchy_backfill.py +1 -2
- infrahub/core/migrations/graph/m027_delete_isolated_nodes.py +50 -0
- infrahub/core/migrations/graph/m028_delete_diffs.py +38 -0
- infrahub/core/migrations/query/attribute_add.py +1 -2
- infrahub/core/migrations/query/attribute_rename.py +3 -6
- infrahub/core/migrations/query/delete_element_in_schema.py +3 -6
- infrahub/core/migrations/query/node_duplicate.py +3 -6
- infrahub/core/migrations/query/relationship_duplicate.py +3 -6
- infrahub/core/migrations/schema/node_attribute_remove.py +3 -6
- infrahub/core/migrations/schema/node_remove.py +3 -6
- infrahub/core/models.py +29 -2
- infrahub/core/node/__init__.py +18 -4
- infrahub/core/node/create.py +211 -0
- infrahub/core/protocols.py +51 -0
- infrahub/core/protocols_base.py +3 -0
- infrahub/core/query/__init__.py +2 -2
- infrahub/core/query/branch.py +27 -17
- infrahub/core/query/diff.py +186 -81
- infrahub/core/query/ipam.py +10 -20
- infrahub/core/query/node.py +65 -49
- infrahub/core/query/relationship.py +156 -58
- infrahub/core/query/resource_manager.py +1 -2
- infrahub/core/query/subquery.py +4 -6
- infrahub/core/relationship/model.py +4 -1
- infrahub/core/schema/__init__.py +2 -1
- infrahub/core/schema/attribute_parameters.py +36 -0
- infrahub/core/schema/attribute_schema.py +83 -8
- infrahub/core/schema/basenode_schema.py +25 -1
- infrahub/core/schema/definitions/core/__init__.py +21 -0
- infrahub/core/schema/definitions/internal.py +13 -3
- infrahub/core/schema/generated/attribute_schema.py +9 -3
- infrahub/core/schema/schema_branch.py +15 -7
- infrahub/core/validators/__init__.py +5 -1
- infrahub/core/validators/attribute/choices.py +1 -2
- infrahub/core/validators/attribute/enum.py +1 -2
- infrahub/core/validators/attribute/kind.py +1 -2
- infrahub/core/validators/attribute/length.py +13 -6
- infrahub/core/validators/attribute/optional.py +1 -2
- infrahub/core/validators/attribute/regex.py +5 -5
- infrahub/core/validators/attribute/unique.py +1 -3
- infrahub/core/validators/determiner.py +18 -2
- infrahub/core/validators/enum.py +7 -0
- infrahub/core/validators/node/hierarchy.py +3 -6
- infrahub/core/validators/query.py +1 -3
- infrahub/core/validators/relationship/count.py +6 -12
- infrahub/core/validators/relationship/optional.py +2 -4
- infrahub/core/validators/relationship/peer.py +3 -8
- infrahub/core/validators/tasks.py +1 -1
- infrahub/core/validators/uniqueness/query.py +12 -9
- infrahub/database/__init__.py +1 -3
- infrahub/events/group_action.py +1 -0
- infrahub/graphql/analyzer.py +139 -18
- infrahub/graphql/app.py +1 -1
- infrahub/graphql/loaders/node.py +1 -1
- infrahub/graphql/loaders/peers.py +1 -1
- infrahub/graphql/manager.py +4 -0
- infrahub/graphql/mutations/action.py +164 -0
- infrahub/graphql/mutations/convert_object_type.py +62 -0
- infrahub/graphql/mutations/main.py +24 -175
- infrahub/graphql/mutations/proposed_change.py +21 -18
- infrahub/graphql/queries/convert_object_type_mapping.py +36 -0
- infrahub/graphql/queries/diff/tree.py +2 -1
- infrahub/graphql/queries/relationship.py +1 -1
- infrahub/graphql/resolvers/many_relationship.py +4 -4
- infrahub/graphql/resolvers/resolver.py +4 -4
- infrahub/graphql/resolvers/single_relationship.py +2 -2
- infrahub/graphql/schema.py +6 -0
- infrahub/graphql/subscription/graphql_query.py +2 -2
- infrahub/graphql/types/branch.py +1 -1
- infrahub/menu/menu.py +31 -0
- infrahub/message_bus/messages/__init__.py +0 -10
- infrahub/message_bus/operations/__init__.py +0 -8
- infrahub/message_bus/operations/refresh/registry.py +1 -1
- infrahub/patch/queries/consolidate_duplicated_nodes.py +3 -6
- infrahub/patch/queries/delete_duplicated_edges.py +5 -10
- infrahub/prefect_server/models.py +1 -19
- infrahub/proposed_change/models.py +68 -3
- infrahub/proposed_change/tasks.py +907 -30
- infrahub/task_manager/models.py +10 -6
- infrahub/telemetry/database.py +1 -1
- infrahub/telemetry/tasks.py +1 -1
- infrahub/trigger/catalogue.py +2 -0
- infrahub/trigger/models.py +29 -3
- infrahub/trigger/setup.py +51 -15
- infrahub/trigger/tasks.py +4 -5
- infrahub/types.py +1 -1
- infrahub/webhook/models.py +2 -1
- infrahub/workflows/catalogue.py +85 -0
- infrahub/workflows/initialization.py +1 -3
- infrahub_sdk/timestamp.py +2 -2
- {infrahub_server-1.2.9rc0.dist-info → infrahub_server-1.3.0a0.dist-info}/METADATA +4 -4
- {infrahub_server-1.2.9rc0.dist-info → infrahub_server-1.3.0a0.dist-info}/RECORD +153 -146
- infrahub_testcontainers/container.py +0 -1
- infrahub_testcontainers/docker-compose.test.yml +4 -4
- infrahub_testcontainers/helpers.py +8 -2
- infrahub_testcontainers/performance_test.py +6 -3
- infrahub/message_bus/messages/check_generator_run.py +0 -26
- infrahub/message_bus/messages/finalize_validator_execution.py +0 -15
- infrahub/message_bus/messages/proposed_change/base_with_diff.py +0 -16
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +0 -11
- infrahub/message_bus/messages/request_generatordefinition_check.py +0 -20
- infrahub/message_bus/messages/request_proposedchange_pipeline.py +0 -23
- infrahub/message_bus/operations/check/__init__.py +0 -3
- infrahub/message_bus/operations/check/generator.py +0 -156
- infrahub/message_bus/operations/finalize/__init__.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +0 -133
- infrahub/message_bus/operations/requests/__init__.py +0 -9
- infrahub/message_bus/operations/requests/generator_definition.py +0 -140
- infrahub/message_bus/operations/requests/proposed_change.py +0 -629
- /infrahub/{message_bus/messages/proposed_change → actions}/__init__.py +0 -0
- {infrahub_server-1.2.9rc0.dist-info → infrahub_server-1.3.0a0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.9rc0.dist-info → infrahub_server-1.3.0a0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.2.9rc0.dist-info → infrahub_server-1.3.0a0.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
|
|
@@ -118,6 +118,10 @@ class PythonTransformTarget:
|
|
|
118
118
|
class ComputedAttrJinja2TriggerDefinition(TriggerBranchDefinition):
|
|
119
119
|
type: TriggerType = TriggerType.COMPUTED_ATTR_JINJA2
|
|
120
120
|
computed_attribute: ComputedAttributeTarget
|
|
121
|
+
template_hash: str
|
|
122
|
+
|
|
123
|
+
def get_description(self) -> str:
|
|
124
|
+
return f"{super().get_description()} | hash:{self.template_hash}"
|
|
121
125
|
|
|
122
126
|
@classmethod
|
|
123
127
|
def from_computed_attribute(
|
|
@@ -139,6 +143,14 @@ class ComputedAttrJinja2TriggerDefinition(TriggerBranchDefinition):
|
|
|
139
143
|
# node creation events if the attribute is optional.
|
|
140
144
|
event_trigger.events.add(NodeCreatedEvent.event_name)
|
|
141
145
|
|
|
146
|
+
if (
|
|
147
|
+
computed_attribute.attribute.computed_attribute
|
|
148
|
+
and computed_attribute.attribute.computed_attribute.jinja2_template is None
|
|
149
|
+
) or not computed_attribute.attribute.computed_attribute:
|
|
150
|
+
raise ValueError("Jinja2 template is required for computed attribute")
|
|
151
|
+
|
|
152
|
+
template_hash = computed_attribute.attribute.computed_attribute.get_hash()
|
|
153
|
+
|
|
142
154
|
event_trigger.match = {"infrahub.node.kind": trigger_node.kind}
|
|
143
155
|
if branches_out_of_scope:
|
|
144
156
|
event_trigger.match["infrahub.branch.name"] = [f"!{branch}" for branch in branches_out_of_scope]
|
|
@@ -177,6 +189,7 @@ class ComputedAttrJinja2TriggerDefinition(TriggerBranchDefinition):
|
|
|
177
189
|
|
|
178
190
|
definition = cls(
|
|
179
191
|
name=f"{computed_attribute.key_name}{NAME_SEPARATOR}kind{NAME_SEPARATOR}{trigger_node.kind}",
|
|
192
|
+
template_hash=template_hash,
|
|
180
193
|
branch=branch,
|
|
181
194
|
computed_attribute=computed_attribute,
|
|
182
195
|
trigger=event_trigger,
|