Skip to content

Commit 71ac078

Browse files
authored
Merge pull request #6425 from opsmill/pog-event-trigger-action-rules-IFC-1507
Add event triggered actions
2 parents 4967fe3 + b872173 commit 71ac078

File tree

23 files changed

+1725
-5
lines changed

23 files changed

+1725
-5
lines changed

backend/infrahub/actions/__init__.py

Whitespace-only changes.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from __future__ import annotations
2+
3+
from enum import Enum
4+
5+
from infrahub.core.constants import InfrahubKind
6+
from infrahub.core.schema.dropdown import DropdownChoice
7+
from infrahub.utils import InfrahubStringEnum
8+
9+
10+
class NodeAction(InfrahubStringEnum):
11+
CREATED = "created"
12+
DELETED = "deleted"
13+
UPDATED = "updated"
14+
15+
16+
class BranchScope(Enum):
17+
ALL_BRANCHES = DropdownChoice(
18+
name="all_branches",
19+
label="All Branches",
20+
description="All branches",
21+
color="#fef08a",
22+
)
23+
DEFAULT_BRANCH = DropdownChoice(
24+
name="default_branch",
25+
label="Default Branch",
26+
description="Only the default branch",
27+
color="#86efac",
28+
)
29+
OTHER_BRANCHES = DropdownChoice(
30+
name="other_branches",
31+
label="Other Branches",
32+
description="All branches except the default branch",
33+
color="#e5e7eb",
34+
)
35+
36+
@classmethod
37+
def available_types(cls) -> list[DropdownChoice]:
38+
return [cls.__members__[member].value for member in list(cls.__members__)]
39+
40+
@classmethod
41+
def from_value(cls, value: str) -> BranchScope:
42+
for member in cls.__members__:
43+
if value == cls.__members__[member].value.name:
44+
return cls.__members__[member]
45+
46+
raise NotImplementedError(f"The defined value {value} doesn't match a branch scope")
47+
48+
49+
class ValueMatch(Enum):
50+
VALUE = DropdownChoice(
51+
name="value",
52+
label="Value",
53+
description="Match against the current value",
54+
color="#fef08a",
55+
)
56+
VALUE_PREVIOUS = DropdownChoice(
57+
name="value_previous",
58+
label="Value Previous",
59+
description="Match against the previous value",
60+
color="#86efac",
61+
)
62+
VALUE_FULL = DropdownChoice(
63+
name="value_full",
64+
label="Full value match",
65+
description="Match against both the current and previous values",
66+
color="#e5e7eb",
67+
)
68+
69+
@classmethod
70+
def available_types(cls) -> list[DropdownChoice]:
71+
return [cls.__members__[member].value for member in list(cls.__members__)]
72+
73+
@classmethod
74+
def from_value(cls, value: str) -> ValueMatch:
75+
for member in cls.__members__:
76+
if value == cls.__members__[member].value.name:
77+
return cls.__members__[member]
78+
79+
raise NotImplementedError(f"The defined value {value} doesn't match a ValueMatch")
80+
81+
82+
NODES_THAT_TRIGGER_ACTION_RULES_SETUP = [
83+
InfrahubKind.GROUPACTION,
84+
InfrahubKind.GROUPTRIGGERRULE,
85+
InfrahubKind.NODETRIGGERRULE,
86+
]

backend/infrahub/actions/gather.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from __future__ import annotations
2+
3+
from graphql import graphql
4+
from infrahub_sdk.graphql import Query
5+
from prefect import task
6+
from prefect.cache_policies import NONE
7+
8+
from infrahub.core.constants import InfrahubKind
9+
from infrahub.core.registry import registry
10+
from infrahub.database import InfrahubDatabase # noqa: TC001 needed for prefect flow
11+
from infrahub.graphql.initialization import prepare_graphql_params
12+
13+
from .models import ActionTriggerRuleTriggerDefinition
14+
from .parsers import parse_trigger_rule_response
15+
16+
17+
@task(
18+
name="gather-trigger-action-rules",
19+
cache_policy=NONE,
20+
)
21+
async def gather_trigger_action_rules(db: InfrahubDatabase) -> list[ActionTriggerRuleTriggerDefinition]:
22+
trigger_query = Query(
23+
name=InfrahubKind.TRIGGERRULE,
24+
query={
25+
InfrahubKind.TRIGGERRULE: {
26+
"edges": {
27+
"node": {
28+
"__typename": None,
29+
"id": None,
30+
"name": {"value": None},
31+
"branch_scope": {"value": None},
32+
"active": {"value": None},
33+
"... on CoreNodeTriggerRule": {
34+
"node_kind": {"value": None},
35+
"mutation_action": {"value": None},
36+
"matches": {
37+
"edges": {
38+
"node": {
39+
"__typename": None,
40+
"id": None,
41+
"... on CoreNodeTriggerAttributeMatch": {
42+
"attribute_name": {"value": None},
43+
"value": {"value": None},
44+
"value_previous": {"value": None},
45+
"value_match": {"value": None},
46+
},
47+
"... on CoreNodeTriggerRelationshipMatch": {
48+
"relationship_name": {"value": None},
49+
"added": {"value": None},
50+
"peer": {"value": None},
51+
},
52+
}
53+
}
54+
},
55+
},
56+
"... on CoreGroupTriggerRule": {
57+
"members_added": {"value": None},
58+
"group": {
59+
"node": {
60+
"id": None,
61+
"__typename": None,
62+
}
63+
},
64+
},
65+
"action": {
66+
"node": {
67+
"__typename": None,
68+
"id": None,
69+
"name": {"value": None},
70+
"... on CoreGroupAction": {
71+
"add_members": {"value": None},
72+
"group": {
73+
"node": {
74+
"id": None,
75+
"__typename": None,
76+
}
77+
},
78+
},
79+
"... on CoreGeneratorAction": {
80+
"generator": {
81+
"node": {
82+
"__typename": None,
83+
"id": None,
84+
}
85+
},
86+
},
87+
}
88+
},
89+
}
90+
},
91+
}
92+
},
93+
)
94+
gql_params = await prepare_graphql_params(
95+
db=db,
96+
branch=registry.default_branch,
97+
)
98+
response = await graphql(
99+
schema=gql_params.schema,
100+
source=trigger_query.render(),
101+
context_value=gql_params.context,
102+
root_value=None,
103+
variable_values={},
104+
)
105+
106+
data = response.data or {}
107+
trigger_rules = parse_trigger_rule_response(data)
108+
trigger_candidates = [
109+
ActionTriggerRuleTriggerDefinition.from_trigger_rule(trigger_rule=trigger_rule)
110+
for trigger_rule in trigger_rules
111+
if trigger_rule.active
112+
]
113+
114+
return [trigger_rule for trigger_rule in trigger_candidates if trigger_rule]

0 commit comments

Comments
 (0)