1
1
package codefresh
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
6
"regexp"
6
7
"strings"
7
8
8
9
cfClient "github.com/codefresh-io/terraform-provider-codefresh/client"
10
+ "github.com/hashicorp/go-cty/cty"
11
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
12
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
9
13
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
14
+ "github.com/robfig/cron"
10
15
)
11
16
12
17
func resourcePipelineCronTrigger () * schema.Resource {
@@ -20,7 +25,7 @@ func resourcePipelineCronTrigger() *schema.Resource {
20
25
idParts := strings .Split (d .Id (), "," )
21
26
22
27
if len (idParts ) != 2 || idParts [0 ] == "" || idParts [1 ] == "" {
23
- return nil , fmt .Errorf ("Unexpected format of ID (%q), expected EVENT,PIPELINE_ID" , d .Id ())
28
+ return nil , fmt .Errorf ("unexpected format of ID (%q), expected EVENT,PIPELINE_ID" , d .Id ())
24
29
}
25
30
26
31
event := idParts [0 ]
@@ -39,12 +44,55 @@ func resourcePipelineCronTrigger() *schema.Resource {
39
44
"expression" : {
40
45
Type : schema .TypeString ,
41
46
Required : true ,
47
+ ValidateDiagFunc : func (v interface {}, path cty.Path ) (diags diag.Diagnostics ) {
48
+ expression := v .(string )
49
+
50
+ // Cron expression requirements: 6 fields, with ability to use descriptors (e.g. @yearly)
51
+ parser := cron .NewParser (cron .Second | cron .Minute | cron .Hour | cron .Dom | cron .Month | cron .Dow | cron .Descriptor )
52
+ if _ , err := parser .Parse (expression ); err != nil {
53
+ diags = append (diags , diag.Diagnostic {
54
+ Severity : diag .Error ,
55
+ Summary : "Invalid cron expression." ,
56
+ Detail : fmt .Sprintf ("The cron expression %q is invalid: %s" , expression , err ),
57
+ })
58
+ }
59
+
60
+ return
61
+ },
42
62
},
43
63
"message" : {
44
64
Type : schema .TypeString ,
45
65
Required : true ,
66
+ ValidateDiagFunc : func (v interface {}, path cty.Path ) (diags diag.Diagnostics ) {
67
+ message := v .(string )
68
+
69
+ // https://github.com/codefresh-io/hermes/blob/6d75b347cb8ff471ce970a766b2285788e5e19fe/pkg/backend/dev_compose_types.json#L226
70
+ re := regexp .MustCompile (`^[a-zA-Z0-9_+\s-#?.:]{2,128}$` )
71
+
72
+ if ! re .MatchString (message ) {
73
+ diags = append (diags , diag.Diagnostic {
74
+ Severity : diag .Error ,
75
+ Summary : "Invalid message." ,
76
+ Detail : fmt .Sprintf ("The message %q is invalid (must match %q)." , message , re .String ()),
77
+ })
78
+ }
79
+
80
+ return
81
+ },
46
82
},
47
83
},
84
+ // Force new resource if any field changes. This is because the Codefresh API does not support updating cron triggers.
85
+ CustomizeDiff : customdiff .All (
86
+ customdiff .ForceNewIfChange ("pipeline_id" , func (ctx context.Context , old , new , meta interface {}) bool {
87
+ return true
88
+ }),
89
+ customdiff .ForceNewIfChange ("expression" , func (ctx context.Context , old , new , meta interface {}) bool {
90
+ return true
91
+ }),
92
+ customdiff .ForceNewIfChange ("message" , func (ctx context.Context , old , new , meta interface {}) bool {
93
+ return true
94
+ }),
95
+ ),
48
96
}
49
97
}
50
98
@@ -97,7 +145,8 @@ func resourcePipelineCronTriggerRead(d *schema.ResourceData, meta interface{}) e
97
145
}
98
146
99
147
func resourcePipelineCronTriggerUpdate (d * schema.ResourceData , meta interface {}) error {
100
- return resourcePipelineCronTriggerCreate (d , meta )
148
+ // see notes in resourcePipelineCronTrigger()
149
+ return fmt .Errorf ("cron triggers cannot be updated" )
101
150
}
102
151
103
152
func resourcePipelineCronTriggerDelete (d * schema.ResourceData , meta interface {}) error {
@@ -107,7 +156,7 @@ func resourcePipelineCronTriggerDelete(d *schema.ResourceData, meta interface{})
107
156
108
157
err := client .DeleteHermesTriggerByEventAndPipeline (hermesTrigger .Event , hermesTrigger .PipelineID )
109
158
if err != nil {
110
- return fmt .Errorf ("Failed to delete cron trigger: %s " , err )
159
+ return fmt .Errorf ("failed to delete cron trigger: %v " , err )
111
160
}
112
161
113
162
return nil
@@ -122,7 +171,7 @@ func mapPipelineCronTriggerToResource(hermesTrigger *cfClient.HermesTrigger, d *
122
171
r := regexp .MustCompile ("[^:]+:[^:]+:[^:]+:[^:]+" )
123
172
eventStringAttributes := strings .Split (hermesTrigger .Event , ":" )
124
173
if ! r .MatchString (hermesTrigger .Event ) {
125
- return fmt .Errorf ("Event string must be in format 'cron:codefresh:[expression]:[message]:[uid]': %s" , hermesTrigger .Event )
174
+ return fmt .Errorf ("event string must be in format 'cron:codefresh:[expression]:[message]:[uid]': %s" , hermesTrigger .Event )
126
175
}
127
176
d .Set ("expression" , eventStringAttributes [2 ])
128
177
d .Set ("message" , eventStringAttributes [3 ])
0 commit comments