Skip to content

Commit 3c8ab5c

Browse files
authored
argocd_application: added retry configuration block to sync policy (#46)
1 parent 56bc0a7 commit 3c8ab5c

File tree

5 files changed

+121
-5
lines changed

5 files changed

+121
-5
lines changed

argocd/resource_argocd_application_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,26 @@ ingress:
133133
"spec.0.sync_policy.0.automated.self_heal",
134134
"true",
135135
),
136+
resource.TestCheckResourceAttr(
137+
"argocd_application.sync_policy",
138+
"spec.0.sync_policy.0.retry.0.backoff.duration",
139+
"30s",
140+
),
141+
resource.TestCheckResourceAttr(
142+
"argocd_application.sync_policy",
143+
"spec.0.sync_policy.0.retry.0.backoff.max_duration",
144+
"2m",
145+
),
146+
resource.TestCheckResourceAttr(
147+
"argocd_application.sync_policy",
148+
"spec.0.sync_policy.0.retry.0.backoff.factor",
149+
"2",
150+
),
151+
resource.TestCheckResourceAttr(
152+
"argocd_application.sync_policy",
153+
"spec.0.sync_policy.0.retry.0.limit",
154+
"5",
155+
),
136156
),
137157
},
138158
{
@@ -354,6 +374,14 @@ resource "argocd_application" "sync_policy" {
354374
prune = true
355375
self_heal = true
356376
}
377+
retry {
378+
limit = "5"
379+
backoff = {
380+
duration = "30s"
381+
max_duration = "2m"
382+
factor = "2"
383+
}
384+
}
357385
}
358386
}
359387
}

argocd/schema_application.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,26 @@ func applicationSpecSchema() *schema.Schema {
300300
// TODO: add a validator
301301
},
302302
},
303+
"retry": {
304+
Type: schema.TypeList,
305+
MinItems: 1,
306+
MaxItems: 1,
307+
Optional: true,
308+
Elem: &schema.Resource{
309+
Schema: map[string]*schema.Schema{
310+
"limit": {
311+
Type: schema.TypeString,
312+
Description: "Max number of allowed sync retries, as a string",
313+
Optional: true,
314+
},
315+
"backoff": {
316+
Type: schema.TypeMap,
317+
Optional: true,
318+
Elem: &schema.Schema{Type: schema.TypeString},
319+
},
320+
},
321+
},
322+
},
303323
},
304324
},
305325
},

argocd/structure_application.go

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ func expandApplicationSpec(d *schema.ResourceData) (
4040
spec.IgnoreDifferences = expandApplicationIgnoreDifferences(v.([]interface{}))
4141
}
4242
if v, ok := s["sync_policy"]; ok {
43-
spec.SyncPolicy = expandApplicationSyncPolicy(v.([]interface{}))
43+
spec.SyncPolicy, err = expandApplicationSyncPolicy(v.([]interface{}))
4444
}
4545
if v, ok := s["destination"]; ok {
4646
spec.Destination = expandApplicationDestination(v.(*schema.Set).List()[0])
4747
}
4848
if v, ok := s["source"]; ok {
4949
spec.Source = expandApplicationSource(v.([]interface{})[0])
5050
}
51-
return spec, nil
51+
return spec, err
5252
}
5353

5454
func expandApplicationSource(_as interface{}) (
@@ -244,13 +244,15 @@ func expandApplicationSourceHelm(in []interface{}) *application.ApplicationSourc
244244
return result
245245
}
246246

247-
func expandApplicationSyncPolicy(_sp []interface{}) *application.SyncPolicy {
247+
func expandApplicationSyncPolicy(_sp []interface{}) (*application.SyncPolicy, error) {
248248
if len(_sp) == 0 {
249-
return nil
249+
return nil, nil
250250
}
251251
sp := _sp[0]
252252
var automated = &application.SyncPolicyAutomated{}
253253
var syncOptions application.SyncOptions
254+
var retry = &application.RetryStrategy{}
255+
var err error
254256

255257
if a, ok := sp.(map[string]interface{})["automated"]; ok {
256258
for k, v := range a.(map[string]interface{}) {
@@ -268,10 +270,43 @@ func expandApplicationSyncPolicy(_sp []interface{}) *application.SyncPolicy {
268270
syncOptions = append(syncOptions, sOpt.(string))
269271
}
270272
}
273+
if _retry, ok := sp.(map[string]interface{})["retry"].([]interface{}); ok {
274+
if len(_retry) > 0 {
275+
r := _retry[0]
276+
for k, v := range r.(map[string]interface{}) {
277+
if k == "limit" {
278+
retry.Limit, err = convertStringToInt64(v.(string))
279+
if err != nil {
280+
return nil, err
281+
}
282+
}
283+
if k == "backoff" {
284+
retry.Backoff = &application.Backoff{}
285+
for kb, vb := range v.(map[string]interface{}) {
286+
if kb == "duration" {
287+
retry.Backoff.Duration = vb.(string)
288+
}
289+
if kb == "max_duration" {
290+
retry.Backoff.MaxDuration = vb.(string)
291+
}
292+
if kb == "factor" {
293+
var pFactor int64
294+
pFactor, err = convertStringToInt64(vb.(string))
295+
if err != nil {
296+
return nil, fmt.Errorf("%s: not a valid int64: %s", kb, vb.(string))
297+
}
298+
retry.Backoff.Factor = &pFactor
299+
}
300+
}
301+
}
302+
}
303+
}
304+
}
271305
return &application.SyncPolicy{
272306
Automated: automated,
273307
SyncOptions: syncOptions,
274-
}
308+
Retry: retry,
309+
}, nil
275310
}
276311

277312
func expandApplicationIgnoreDifferences(ids []interface{}) (
@@ -370,13 +405,32 @@ func flattenApplicationSyncPolicy(sp *application.SyncPolicy) []map[string]inter
370405
return nil
371406
}
372407
result := make(map[string]interface{}, 0)
408+
backoff := make(map[string]string, 0)
373409
if sp.Automated != nil {
374410
result["automated"] = map[string]bool{
375411
"prune": sp.Automated.Prune,
376412
"self_heal": sp.Automated.SelfHeal,
377413
}
378414
}
379415
result["sync_options"] = []string(sp.SyncOptions)
416+
if sp.Retry != nil {
417+
limit := convertInt64ToString(sp.Retry.Limit)
418+
if sp.Retry.Backoff != nil {
419+
backoff = map[string]string{
420+
"duration": sp.Retry.Backoff.Duration,
421+
"max_duration": sp.Retry.Backoff.MaxDuration,
422+
}
423+
if sp.Retry.Backoff.Factor != nil {
424+
backoff["factor"] = convertInt64PointerToString(sp.Retry.Backoff.Factor)
425+
}
426+
}
427+
result["retry"] = []map[string]interface{}{
428+
{
429+
"limit": limit,
430+
"backoff": backoff,
431+
},
432+
}
433+
}
380434
return []map[string]interface{}{result}
381435
}
382436

argocd/utils.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ func convertInt64ToString(i int64) string {
2121
return strconv.FormatInt(i, 10)
2222
}
2323

24+
func convertInt64PointerToString(i *int64) string {
25+
return strconv.FormatInt(*i, 10)
26+
}
27+
2428
func isKeyInMap(key string, d map[string]interface{}) bool {
2529
if d == nil {
2630
return false

docs/resources/application.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,21 @@ The `destination` block has the following attributes:
139139
The `sync_policy` block has the following attributes:
140140
* `automated` - (Optional) map(string) of strings, will keep an application synced to the target revision. Structure is documented below
141141
* `sync_options` - (Optional) list of sync options, allow you to specify whole app sync-options (only available from ArgoCD 1.5.0 onwards).
142+
* `retry` - (Optional) controls failed sync retry behavior, structure is documented below
142143

143144
The `sync_policy/automated` map has the following attributes:
144145
* `prune` - (Optional), boolean, will prune resources automatically as part of automated sync. Defaults to `false`.
145146
* `self_heal` - (Optional), boolean, enables auto-syncing if the live resources differ from the targeted revision manifests. Defaults to `false`.
146147

148+
The `sync_policy/retry` block has the following attributes:
149+
* `limit` - (Optional), max number of allowed sync retries, as a string.
150+
* `backoff` - (Optional), retry backoff strategy, structure is documented below
151+
152+
The `sync_policy/retry/backoff` map has the following attributes:
153+
* `duration` - (Optional), Duration is the amount to back off. Default unit is seconds, but could also be a duration (e.g. "2m", "1h"), as a string.
154+
* `factor` - (Optional), Factor is a factor to multiply the base duration after each failed retry, as a string.
155+
* `max_duration` - (Optional), is the maximum amount of time allowed for the backoff strategy. Default unit is seconds, but could also be a duration (e.g. "2m", "1h"), as a string.
156+
147157
Each `ignore_difference` block can have the following attributes:
148158
* `group` - (Optional) The targeted Kubernetes resource kind.
149159
* `kind` - (Optional) The targeted Kubernetes resource kind.

0 commit comments

Comments
 (0)