React to a change in the reconcileAt annotation

Despite the name, the contract of the reconcileAt mechanism is that
_changing it_ should trigger reconciliation outside the otherwise
specified schedule. To detect changes, this commit adds a field to the
status, and updates it when a scan has run.
This commit is contained in:
Michael Bridgen 2020-10-19 16:30:27 +01:00
parent 4e5c89ae18
commit 316b9758c4
5 changed files with 27 additions and 6 deletions

View File

@ -62,6 +62,12 @@ type ImageRepositoryStatus struct {
// LastScanResult contains the number of fetched tags.
// +optional
LastScanResult ScanResult `json:"lastScanResult,omitempty"`
// LastHandledReconcileAt records the value of the annotation used
// to prompt a scan, so that a change in value can be
// detected. The name is in common with other GitOps Toolkit
// controllers.
LastHandledReconcileAt string `json:"lastHandledReconcileAt,omitempty"`
}
// SetImageRepositoryReadiness sets the ready condition with the given status, reason and message.

View File

@ -95,6 +95,11 @@ spec:
- type
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt records the value of the annotation
used to prompt a scan, so that a change in value can be detected.
The name is in common with other GitOps Toolkit controllers.
type: string
lastScanResult:
description: LastScanResult contains the number of fetched tags.
properties:

View File

@ -154,6 +154,14 @@ func (r *ImageRepositoryReconciler) scan(ctx context.Context, imageRepo imagev1a
r.Database.SetTags(canonicalName, tags)
imageRepo.Status.LastScanResult.TagCount = len(tags)
// if the reconcile request annotation was set, consider it
// handled (NB it doesn't matter here if it was changed since last
// time)
if token, ok := imageRepo.GetAnnotations()[meta.ReconcileAtAnnotation]; ok {
imageRepo.Status.LastHandledReconcileAt = token
}
return imagev1alpha1.SetImageRepositoryReadiness(
imageRepo,
corev1.ConditionTrue,
@ -177,12 +185,12 @@ func (r *ImageRepositoryReconciler) shouldScan(repo imagev1alpha1.ImageRepositor
return true, scanInterval
}
// allow for the "reconcile at" annotation
// Is the controller seeing this because the reconcileAt
// annotation was tweaked? Despite the name of the annotation, all
// that matters is that it's different.
if syncAt, ok := repo.GetAnnotations()[meta.ReconcileAtAnnotation]; ok {
if t, err := time.Parse(time.RFC3339Nano, syncAt); err == nil && t.Before(now) {
if syncAt != repo.Status.LastHandledReconcileAt {
return true, scanInterval
} else if err == nil {
return false, t.Sub(now)
}
}

View File

@ -182,14 +182,17 @@ var _ = Describe("ImageRepository controller", func() {
lastScan := imagev1alpha1.GetLastTransitionTime(repoAfter)
Expect(lastScan).ToNot(BeNil())
requestToken := "this can be anything, so long as it's a change"
repoAfter.Annotations = map[string]string{
meta.ReconcileAtAnnotation: time.Now().Add(-time.Minute).Format(time.RFC3339Nano),
meta.ReconcileAtAnnotation: requestToken,
}
Expect(r.Update(ctx, &repoAfter)).To(Succeed())
Eventually(func() bool {
err := r.Get(context.Background(), objectName, &repoAfter)
return err == nil && imagev1alpha1.GetLastTransitionTime(repoAfter).After(lastScan.Time)
}, timeout, interval).Should(BeTrue())
Expect(repoAfter.Status.LastHandledReconcileAt).To(Equal(requestToken))
})
})
})

1
go.sum
View File

@ -200,7 +200,6 @@ github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQo
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fluxcd/pkg v0.0.4 h1:fMA6GG3FTSBFDrlB026gQJhxj4xVuvcvwP3rhX/Yqrw=
github.com/fluxcd/pkg/apis/meta v0.0.2 h1:kyA4Y0IzNjf1joBOnFqpWG7aNDHvtLExZcaHQM7qhRI=
github.com/fluxcd/pkg/apis/meta v0.0.2/go.mod h1:nCNps5JJOcEQr3MNDmZqI4o0chjePSUYL6Q2ktDtotU=
github.com/fluxcd/pkg/recorder v0.0.5 h1:D8qfupahIvh6ncCMn2yTHsrzG91S05sp4zdpsbKWeaU=