Skip to content

Commit af4b5d8

Browse files
committed
feat: gracefully handle ephemeral errors
1 parent c80d627 commit af4b5d8

File tree

8 files changed

+77
-8
lines changed

8 files changed

+77
-8
lines changed

api/v1/clustertoken_types.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,18 @@ type ClusterTokenSpec struct {
4242

4343
// +optional
4444
// +kubebuilder:validation:Format:=duration
45-
// +kubebuilder:default:="10m"
45+
// +kubebuilder:default:="30m"
4646
// +kubebuilder:example:="45m"
4747
// Specify how often to refresh the token (maximum: 1h)
4848
RefreshInterval metav1.Duration `json:"refreshInterval"`
4949

50+
// +optional
51+
// +kubebuilder:validation:Format:=duration
52+
// +kubebuilder:default:="5m"
53+
// +kubebuilder:example:="1m"
54+
// Specify how long to wait before retrying on transient token retrieval error
55+
RetryInterval metav1.Duration `json:"retryInterval"`
56+
5057
// +optional
5158
// +kubebuilder:example:={"metadata": "read", "contents": "read"}
5259
// Specify the permissions for the token as a subset of those of the GitHub App
@@ -128,6 +135,10 @@ func (t *ClusterToken) GetRefreshInterval() time.Duration {
128135
return t.Spec.RefreshInterval.Duration
129136
}
130137

138+
func (t *ClusterToken) GetRetryInterval() time.Duration {
139+
return t.Spec.RetryInterval.Duration
140+
}
141+
131142
func (t *ClusterToken) GetSecretNamespace() string {
132143
return t.Spec.Secret.Namespace
133144
}

api/v1/token_types.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,18 @@ type TokenSpec struct {
4343

4444
// +optional
4545
// +kubebuilder:validation:Format:=duration
46-
// +kubebuilder:default:="10m"
46+
// +kubebuilder:default:="30m"
4747
// +kubebuilder:example:="45m"
4848
// Specify how often to refresh the token (maximum: 1h)
4949
RefreshInterval metav1.Duration `json:"refreshInterval"`
5050

51+
// +optional
52+
// +kubebuilder:validation:Format:=duration
53+
// +kubebuilder:default:="5m"
54+
// +kubebuilder:example:="1m"
55+
// Specify how long to wait before retrying on transient token retrieval error
56+
RetryInterval metav1.Duration `json:"retryInterval"`
57+
5158
// +optional
5259
// +kubebuilder:example:={"metadata": "read", "contents": "read"}
5360
// Specify the permissions for the token as a subset of those of the GitHub App
@@ -121,6 +128,10 @@ func (t *Token) GetRefreshInterval() time.Duration {
121128
return t.Spec.RefreshInterval.Duration
122129
}
123130

131+
func (t *Token) GetRetryInterval() time.Duration {
132+
return t.Spec.RetryInterval.Duration
133+
}
134+
124135
func (t *Token) GetSecretNamespace() string {
125136
return t.Namespace
126137
}

api/v1/zz_generated.deepcopy.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/github.as-code.io_clustertokens.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ spec:
236236
type: string
237237
type: object
238238
refreshInterval:
239-
default: 10m
239+
default: 30m
240240
description: "Specify how often to refresh the token (maximum: 1h)"
241241
example: 45m
242242
format: duration
@@ -258,6 +258,14 @@ spec:
258258
type: integer
259259
maxItems: 500
260260
type: array
261+
retryInterval:
262+
default: 5m
263+
description:
264+
Specify how long to wait before retrying on transient
265+
token retrieval error
266+
example: 1m
267+
format: duration
268+
type: string
261269
secret:
262270
properties:
263271
annotations:

config/crd/bases/github.as-code.io_tokens.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ spec:
236236
type: string
237237
type: object
238238
refreshInterval:
239-
default: 10m
239+
default: 30m
240240
description: "Specify how often to refresh the token (maximum: 1h)"
241241
example: 45m
242242
format: duration
@@ -258,6 +258,14 @@ spec:
258258
type: integer
259259
maxItems: 500
260260
type: array
261+
retryInterval:
262+
default: 5m
263+
description:
264+
Specify how long to wait before retrying on transient
265+
token retrieval error
266+
example: 1m
267+
format: duration
268+
type: string
261269
secret:
262270
description: Override the default token secret name and type
263271
properties:

deploy/charts/github-token-manager/templates/crds.yaml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ spec:
244244
type: string
245245
type: object
246246
refreshInterval:
247-
default: 10m
247+
default: 30m
248248
description: "Specify how often to refresh the token (maximum: 1h)"
249249
example: 45m
250250
format: duration
@@ -266,6 +266,14 @@ spec:
266266
type: integer
267267
maxItems: 500
268268
type: array
269+
retryInterval:
270+
default: 5m
271+
description:
272+
Specify how long to wait before retrying on transient
273+
token retrieval error
274+
example: 1m
275+
format: duration
276+
type: string
269277
secret:
270278
properties:
271279
annotations:
@@ -633,7 +641,7 @@ spec:
633641
type: string
634642
type: object
635643
refreshInterval:
636-
default: 10m
644+
default: 30m
637645
description: "Specify how often to refresh the token (maximum: 1h)"
638646
example: 45m
639647
format: duration
@@ -655,6 +663,14 @@ spec:
655663
type: integer
656664
maxItems: 500
657665
type: array
666+
retryInterval:
667+
default: 5m
668+
description:
669+
Specify how long to wait before retrying on transient
670+
token retrieval error
671+
example: 1m
672+
format: duration
673+
type: string
658674
secret:
659675
description: Override the default token secret name and type
660676
properties:

internal/tokenmanager/token_manager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type tokenManager interface {
2323
GetSecretBasicAuth() bool
2424
GetInstallationID() int64
2525
GetRefreshInterval() time.Duration
26+
GetRetryInterval() time.Duration
2627
GetSecretNamespace() string
2728
GetSecretName() string
2829
GetSecretLabels() map[string]string

internal/tokenmanager/token_secret.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,15 @@ func (s *tokenSecret) Reconcile() (result reconcile.Result, err error) {
137137
if apierrors.IsNotFound(err) {
138138
// Secret not found, so create it
139139
if err := s.CreateSecret(); err != nil {
140-
log.Error(err, "failed to create secret")
140+
if errors.Is(err, ghait.TransientError{}) {
141+
log.Error(err, "transient error creating secret")
142+
return reconcile.Result{RequeueAfter: s.owner.GetRetryInterval()}, nil
143+
}
144+
145+
log.Error(err, "fatal error creating secret")
141146
return result, err
142147
}
148+
143149
return reconcile.Result{RequeueAfter: s.owner.GetRefreshInterval()}, nil
144150
}
145151

@@ -163,9 +169,15 @@ func (s *tokenSecret) Reconcile() (result reconcile.Result, err error) {
163169
s.Secret = secret
164170

165171
if err := s.UpdateSecret(); err != nil {
166-
log.Error(err, "failed to update secret")
172+
if errors.Is(err, ghait.TransientError{}) {
173+
log.Error(err, "transient error updating secret")
174+
return reconcile.Result{RequeueAfter: s.owner.GetRetryInterval()}, nil
175+
}
176+
177+
log.Error(err, "fatal error updating secret")
167178
return result, err
168179
}
180+
169181
return reconcile.Result{RequeueAfter: s.owner.GetRefreshInterval()}, nil
170182
}
171183

0 commit comments

Comments
 (0)