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