5
5
from prefect .cache_policies import NONE
6
6
from prefect .client .orchestration import PrefectClient
7
7
from prefect .client .schemas .filters import DeploymentFilter , DeploymentFilterName
8
+ from prefect .events .schemas .automations import Automation
8
9
9
10
from infrahub .trigger .models import TriggerDefinition
10
11
11
- from .models import TriggerType
12
+ from .models import TriggerSetupReport , TriggerType
12
13
13
14
if TYPE_CHECKING :
14
15
from uuid import UUID
15
16
16
17
18
+ def compare_automations (target : AutomationCore , existing : Automation ) -> bool :
19
+ """Compare an AutomationCore with an existing Automation object to identify if they are identical or not
20
+
21
+ Return True if the target is identical to the existing automatino
22
+ """
23
+
24
+ target_dump = target .model_dump (exclude_defaults = True , exclude_none = True )
25
+ existing_dump = existing .model_dump (exclude_defaults = True , exclude_none = True , exclude = {"id" })
26
+
27
+ return target_dump == existing_dump
28
+
29
+
17
30
@task (name = "trigger-setup" , task_run_name = "Setup triggers" , cache_policy = NONE ) # type: ignore[arg-type]
18
31
async def setup_triggers (
19
32
client : PrefectClient ,
20
33
triggers : list [TriggerDefinition ],
21
34
trigger_type : TriggerType | None = None ,
22
- ) -> None :
35
+ force_update : bool = False ,
36
+ ) -> TriggerSetupReport :
23
37
log = get_run_logger ()
24
38
39
+ report = TriggerSetupReport ()
40
+
25
41
if trigger_type :
26
42
log .info (f"Setting up triggers of type { trigger_type .value } " )
27
43
else :
@@ -38,23 +54,24 @@ async def setup_triggers(
38
54
)
39
55
}
40
56
deployments_mapping : dict [str , UUID ] = {name : item .id for name , item in deployments .items ()}
41
- existing_automations = {item .name : item for item in await client .read_automations ()}
42
57
43
58
# If a trigger type is provided, narrow down the list of existing triggers to know which one to delete
59
+ existing_automations : dict [str , Automation ] = {}
44
60
if trigger_type :
45
- trigger_automations = [
46
- item .name for item in await client .read_automations () if item .name .startswith (trigger_type .value )
47
- ]
61
+ existing_automations = {
62
+ item .name : item for item in await client .read_automations () if item .name .startswith (trigger_type .value )
63
+ }
48
64
else :
49
- trigger_automations = [ item .name for item in await client .read_automations ()]
65
+ existing_automations = { item .name : item for item in await client .read_automations ()}
50
66
51
67
trigger_names = [trigger .generate_name () for trigger in triggers ]
68
+ automation_names = list (existing_automations .keys ())
52
69
53
- log .debug (f"{ len (trigger_automations )} existing triggers ({ trigger_automations } )" )
54
- log .debug (f"{ len (trigger_names )} triggers to configure ({ trigger_names } )" )
70
+ log .debug (f"{ len (automation_names )} existing triggers ({ automation_names } )" )
71
+ log .debug (f"{ len (trigger_names )} triggers to configure ({ trigger_names } )" )
55
72
56
- to_delete = set (trigger_automations ) - set (trigger_names )
57
- log .debug (f"{ len (trigger_names )} triggers to delete ({ to_delete } )" )
73
+ to_delete = set (automation_names ) - set (trigger_names )
74
+ log .debug (f"{ len (to_delete )} triggers to delete ({ to_delete } )" )
58
75
59
76
# -------------------------------------------------------------
60
77
# Create or Update all triggers
@@ -71,11 +88,16 @@ async def setup_triggers(
71
88
existing_automation = existing_automations .get (trigger .generate_name (), None )
72
89
73
90
if existing_automation :
74
- await client .update_automation (automation_id = existing_automation .id , automation = automation )
75
- log .info (f"{ trigger .generate_name ()} Updated" )
91
+ if force_update or not compare_automations (target = automation , existing = existing_automation ):
92
+ await client .update_automation (automation_id = existing_automation .id , automation = automation )
93
+ log .info (f"{ trigger .generate_name ()} Updated" )
94
+ report .updated .append (trigger )
95
+ else :
96
+ report .unchanged .append (trigger )
76
97
else :
77
98
await client .create_automation (automation = automation )
78
99
log .info (f"{ trigger .generate_name ()} Created" )
100
+ report .created .append (trigger )
79
101
80
102
# -------------------------------------------------------------
81
103
# Delete Triggers that shouldn't be there
@@ -86,5 +108,8 @@ async def setup_triggers(
86
108
if not existing_automation :
87
109
continue
88
110
111
+ report .deleted .append (existing_automation )
89
112
await client .delete_automation (automation_id = existing_automation .id )
90
113
log .info (f"{ item_to_delete } Deleted" )
114
+
115
+ return report
0 commit comments