Skip to content

Commit 05c13fe

Browse files
committed
check readiness using kstatus
This change replaces all the many functions and ways of calculating readiness of objects into one unified way that uses kstatus.Compute() to check if the object is in progress or current. Only the objects that are current are considered to be ready. This takes advantage of the kstatus compatibility of Flux's APIs and also makes sure that they remain kstatus compatible. The new isObjectReady() function is also aware of static/statusless objects and knows how to check their readiness using kstatus. This prepares the CLI for the upcoming static API objects. All the is*Ready() functions for specific objects have been removed. This change doesn't affect any of the existing tests results. Introduce suspend and resume subcommands for alert-provider. Signed-off-by: Sunny <darkowlzz@protonmail.com>
1 parent 8e3a809 commit 05c13fe

23 files changed

+464
-420
lines changed

cmd/flux/create.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e
132132

133133
logger.Waitingf("waiting for %s reconciliation", names.kind)
134134
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
135-
isReady(kubeClient, namespacedName, object)); err != nil {
135+
isObjectReadyConditionFunc(kubeClient, namespacedName, object.asClientObject())); err != nil {
136136
return err
137137
}
138138
logger.Successf("%s reconciliation completed", names.kind)

cmd/flux/create_alert.go

+1-21
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/spf13/cobra"
2424
"k8s.io/apimachinery/pkg/api/errors"
25-
apimeta "k8s.io/apimachinery/pkg/api/meta"
2625
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
"k8s.io/apimachinery/pkg/types"
2827
"k8s.io/apimachinery/pkg/util/wait"
@@ -133,7 +132,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
133132

134133
logger.Waitingf("waiting for Alert reconciliation")
135134
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
136-
isAlertReady(kubeClient, namespacedName, &alert)); err != nil {
135+
isObjectReadyConditionFunc(kubeClient, namespacedName, &alert)); err != nil {
137136
return err
138137
}
139138
logger.Successf("Alert %s is ready", name)
@@ -170,22 +169,3 @@ func upsertAlert(ctx context.Context, kubeClient client.Client,
170169
logger.Successf("Alert updated")
171170
return namespacedName, nil
172171
}
173-
174-
func isAlertReady(kubeClient client.Client, namespacedName types.NamespacedName, alert *notificationv1b2.Alert) wait.ConditionWithContextFunc {
175-
return func(ctx context.Context) (bool, error) {
176-
err := kubeClient.Get(ctx, namespacedName, alert)
177-
if err != nil {
178-
return false, err
179-
}
180-
181-
if c := apimeta.FindStatusCondition(alert.Status.Conditions, meta.ReadyCondition); c != nil {
182-
switch c.Status {
183-
case metav1.ConditionTrue:
184-
return true, nil
185-
case metav1.ConditionFalse:
186-
return false, fmt.Errorf(c.Message)
187-
}
188-
}
189-
return false, nil
190-
}
191-
}

cmd/flux/create_alertprovider.go

+1-21
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/spf13/cobra"
2424
"k8s.io/apimachinery/pkg/api/errors"
25-
apimeta "k8s.io/apimachinery/pkg/api/meta"
2625
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
"k8s.io/apimachinery/pkg/types"
2827
"k8s.io/apimachinery/pkg/util/wait"
@@ -128,7 +127,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
128127

129128
logger.Waitingf("waiting for Provider reconciliation")
130129
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
131-
isAlertProviderReady(kubeClient, namespacedName, &provider)); err != nil {
130+
isObjectReadyConditionFunc(kubeClient, namespacedName, &provider)); err != nil {
132131
return err
133132
}
134133

@@ -167,22 +166,3 @@ func upsertAlertProvider(ctx context.Context, kubeClient client.Client,
167166
logger.Successf("Provider updated")
168167
return namespacedName, nil
169168
}
170-
171-
func isAlertProviderReady(kubeClient client.Client, namespacedName types.NamespacedName, provider *notificationv1.Provider) wait.ConditionWithContextFunc {
172-
return func(ctx context.Context) (bool, error) {
173-
err := kubeClient.Get(ctx, namespacedName, provider)
174-
if err != nil {
175-
return false, err
176-
}
177-
178-
if c := apimeta.FindStatusCondition(provider.Status.Conditions, meta.ReadyCondition); c != nil {
179-
switch c.Status {
180-
case metav1.ConditionTrue:
181-
return true, nil
182-
case metav1.ConditionFalse:
183-
return false, fmt.Errorf(c.Message)
184-
}
185-
}
186-
return false, nil
187-
}
188-
}

cmd/flux/create_helmrelease.go

+1-18
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"github.com/spf13/cobra"
3333
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3434
"k8s.io/apimachinery/pkg/api/errors"
35-
apimeta "k8s.io/apimachinery/pkg/api/meta"
3635
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3736
"k8s.io/apimachinery/pkg/types"
3837
"k8s.io/apimachinery/pkg/util/wait"
@@ -304,7 +303,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
304303

305304
logger.Waitingf("waiting for HelmRelease reconciliation")
306305
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
307-
isHelmReleaseReady(kubeClient, namespacedName, &helmRelease)); err != nil {
306+
isObjectReadyConditionFunc(kubeClient, namespacedName, &helmRelease)); err != nil {
308307
return err
309308
}
310309
logger.Successf("HelmRelease %s is ready", name)
@@ -344,22 +343,6 @@ func upsertHelmRelease(ctx context.Context, kubeClient client.Client,
344343
return namespacedName, nil
345344
}
346345

347-
func isHelmReleaseReady(kubeClient client.Client, namespacedName types.NamespacedName, helmRelease *helmv2.HelmRelease) wait.ConditionWithContextFunc {
348-
return func(ctx context.Context) (bool, error) {
349-
err := kubeClient.Get(ctx, namespacedName, helmRelease)
350-
if err != nil {
351-
return false, err
352-
}
353-
354-
// Confirm the state we are observing is for the current generation
355-
if helmRelease.Generation != helmRelease.Status.ObservedGeneration {
356-
return false, nil
357-
}
358-
359-
return apimeta.IsStatusConditionTrue(helmRelease.Status.Conditions, meta.ReadyCondition), nil
360-
}
361-
}
362-
363346
func validateStrategy(input string) bool {
364347
allowedStrategy := []string{"Revision", "ChartVersion"}
365348

cmd/flux/create_kustomization.go

+1-26
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424

2525
"github.com/spf13/cobra"
2626
"k8s.io/apimachinery/pkg/api/errors"
27-
apimeta "k8s.io/apimachinery/pkg/api/meta"
2827
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2928
"k8s.io/apimachinery/pkg/types"
3029
"k8s.io/apimachinery/pkg/util/wait"
@@ -264,7 +263,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
264263

265264
logger.Waitingf("waiting for Kustomization reconciliation")
266265
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
267-
isKustomizationReady(kubeClient, namespacedName, &kustomization)); err != nil {
266+
isObjectReadyConditionFunc(kubeClient, namespacedName, &kustomization)); err != nil {
268267
return err
269268
}
270269
logger.Successf("Kustomization %s is ready", name)
@@ -303,27 +302,3 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client,
303302
logger.Successf("Kustomization updated")
304303
return namespacedName, nil
305304
}
306-
307-
func isKustomizationReady(kubeClient client.Client, namespacedName types.NamespacedName, kustomization *kustomizev1.Kustomization) wait.ConditionWithContextFunc {
308-
return func(ctx context.Context) (bool, error) {
309-
err := kubeClient.Get(ctx, namespacedName, kustomization)
310-
if err != nil {
311-
return false, err
312-
}
313-
314-
// Confirm the state we are observing is for the current generation
315-
if kustomization.Generation != kustomization.Status.ObservedGeneration {
316-
return false, nil
317-
}
318-
319-
if c := apimeta.FindStatusCondition(kustomization.Status.Conditions, meta.ReadyCondition); c != nil {
320-
switch c.Status {
321-
case metav1.ConditionTrue:
322-
return true, nil
323-
case metav1.ConditionFalse:
324-
return false, fmt.Errorf(c.Message)
325-
}
326-
}
327-
return false, nil
328-
}
329-
}

cmd/flux/create_receiver.go

+1-21
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/spf13/cobra"
2424
"k8s.io/apimachinery/pkg/api/errors"
25-
apimeta "k8s.io/apimachinery/pkg/api/meta"
2625
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
"k8s.io/apimachinery/pkg/types"
2827
"k8s.io/apimachinery/pkg/util/wait"
@@ -140,7 +139,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error {
140139

141140
logger.Waitingf("waiting for Receiver reconciliation")
142141
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
143-
isReceiverReady(kubeClient, namespacedName, &receiver)); err != nil {
142+
isObjectReadyConditionFunc(kubeClient, namespacedName, &receiver)); err != nil {
144143
return err
145144
}
146145
logger.Successf("Receiver %s is ready", name)
@@ -179,22 +178,3 @@ func upsertReceiver(ctx context.Context, kubeClient client.Client,
179178
logger.Successf("Receiver updated")
180179
return namespacedName, nil
181180
}
182-
183-
func isReceiverReady(kubeClient client.Client, namespacedName types.NamespacedName, receiver *notificationv1.Receiver) wait.ConditionWithContextFunc {
184-
return func(ctx context.Context) (bool, error) {
185-
err := kubeClient.Get(ctx, namespacedName, receiver)
186-
if err != nil {
187-
return false, err
188-
}
189-
190-
if c := apimeta.FindStatusCondition(receiver.Status.Conditions, meta.ReadyCondition); c != nil {
191-
switch c.Status {
192-
case metav1.ConditionTrue:
193-
return true, nil
194-
case metav1.ConditionFalse:
195-
return false, fmt.Errorf(c.Message)
196-
}
197-
}
198-
return false, nil
199-
}
200-
}

cmd/flux/create_source_bucket.go

+1-28
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"sigs.k8s.io/controller-runtime/pkg/client"
3232

3333
"github.com/fluxcd/pkg/apis/meta"
34-
"github.com/fluxcd/pkg/runtime/conditions"
3534

3635
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
3736

@@ -205,7 +204,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
205204

206205
logger.Waitingf("waiting for Bucket source reconciliation")
207206
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
208-
isBucketReady(kubeClient, namespacedName, bucket)); err != nil {
207+
isObjectReadyConditionFunc(kubeClient, namespacedName, bucket)); err != nil {
209208
return err
210209
}
211210
logger.Successf("Bucket source reconciliation completed")
@@ -247,29 +246,3 @@ func upsertBucket(ctx context.Context, kubeClient client.Client,
247246
logger.Successf("Bucket source updated")
248247
return namespacedName, nil
249248
}
250-
251-
func isBucketReady(kubeClient client.Client, namespacedName types.NamespacedName, bucket *sourcev1.Bucket) wait.ConditionWithContextFunc {
252-
return func(ctx context.Context) (bool, error) {
253-
err := kubeClient.Get(ctx, namespacedName, bucket)
254-
if err != nil {
255-
return false, err
256-
}
257-
258-
if c := conditions.Get(bucket, meta.ReadyCondition); c != nil {
259-
// Confirm the Ready condition we are observing is for the
260-
// current generation
261-
if c.ObservedGeneration != bucket.GetGeneration() {
262-
return false, nil
263-
}
264-
265-
// Further check the Status
266-
switch c.Status {
267-
case metav1.ConditionTrue:
268-
return true, nil
269-
case metav1.ConditionFalse:
270-
return false, fmt.Errorf(c.Message)
271-
}
272-
}
273-
return false, nil
274-
}
275-
}

cmd/flux/create_source_git.go

+1-28
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"sigs.k8s.io/yaml"
3636

3737
"github.com/fluxcd/pkg/apis/meta"
38-
"github.com/fluxcd/pkg/runtime/conditions"
3938

4039
sourcev1 "github.com/fluxcd/source-controller/api/v1"
4140

@@ -326,7 +325,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
326325

327326
logger.Waitingf("waiting for GitRepository source reconciliation")
328327
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
329-
isGitRepositoryReady(kubeClient, namespacedName, &gitRepository)); err != nil {
328+
isObjectReadyConditionFunc(kubeClient, namespacedName, &gitRepository)); err != nil {
330329
return err
331330
}
332331
logger.Successf("GitRepository source reconciliation completed")
@@ -368,29 +367,3 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client,
368367
logger.Successf("GitRepository source updated")
369368
return namespacedName, nil
370369
}
371-
372-
func isGitRepositoryReady(kubeClient client.Client, namespacedName types.NamespacedName, gitRepository *sourcev1.GitRepository) wait.ConditionWithContextFunc {
373-
return func(ctx context.Context) (bool, error) {
374-
err := kubeClient.Get(ctx, namespacedName, gitRepository)
375-
if err != nil {
376-
return false, err
377-
}
378-
379-
if c := conditions.Get(gitRepository, meta.ReadyCondition); c != nil {
380-
// Confirm the Ready condition we are observing is for the
381-
// current generation
382-
if c.ObservedGeneration != gitRepository.GetGeneration() {
383-
return false, nil
384-
}
385-
386-
// Further check the Status
387-
switch c.Status {
388-
case metav1.ConditionTrue:
389-
return true, nil
390-
case metav1.ConditionFalse:
391-
return false, fmt.Errorf(c.Message)
392-
}
393-
}
394-
return false, nil
395-
}
396-
}

cmd/flux/create_source_git_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,21 @@ func TestCreateSourceGit(t *testing.T) {
181181
Time: time.Now(),
182182
},
183183
}
184+
repo.Status.ObservedGeneration = repo.GetGeneration()
184185
},
185186
}, {
186187
"Failed",
187188
command,
188189
assertError("failed message"),
189190
func(repo *sourcev1.GitRepository) {
191+
stalledCondition := metav1.Condition{
192+
Type: meta.StalledCondition,
193+
Status: metav1.ConditionTrue,
194+
Reason: sourcev1.URLInvalidReason,
195+
Message: "failed message",
196+
ObservedGeneration: repo.GetGeneration(),
197+
}
198+
apimeta.SetStatusCondition(&repo.Status.Conditions, stalledCondition)
190199
newCondition := metav1.Condition{
191200
Type: meta.ReadyCondition,
192201
Status: metav1.ConditionFalse,
@@ -195,6 +204,7 @@ func TestCreateSourceGit(t *testing.T) {
195204
ObservedGeneration: repo.GetGeneration(),
196205
}
197206
apimeta.SetStatusCondition(&repo.Status.Conditions, newCondition)
207+
repo.Status.ObservedGeneration = repo.GetGeneration()
198208
},
199209
}, {
200210
"NoArtifact",
@@ -210,6 +220,7 @@ func TestCreateSourceGit(t *testing.T) {
210220
ObservedGeneration: repo.GetGeneration(),
211221
}
212222
apimeta.SetStatusCondition(&repo.Status.Conditions, newCondition)
223+
repo.Status.ObservedGeneration = repo.GetGeneration()
213224
},
214225
},
215226
}

cmd/flux/create_source_helm.go

+1-28
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"os"
2424

2525
"github.com/fluxcd/pkg/apis/meta"
26-
"github.com/fluxcd/pkg/runtime/conditions"
2726
"github.com/spf13/cobra"
2827
corev1 "k8s.io/api/core/v1"
2928
"k8s.io/apimachinery/pkg/api/errors"
@@ -232,7 +231,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
232231

233232
logger.Waitingf("waiting for HelmRepository source reconciliation")
234233
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
235-
isHelmRepositoryReady(kubeClient, namespacedName, helmRepository)); err != nil {
234+
isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository)); err != nil {
236235
return err
237236
}
238237
logger.Successf("HelmRepository source reconciliation completed")
@@ -279,29 +278,3 @@ func upsertHelmRepository(ctx context.Context, kubeClient client.Client,
279278
logger.Successf("source updated")
280279
return namespacedName, nil
281280
}
282-
283-
func isHelmRepositoryReady(kubeClient client.Client, namespacedName types.NamespacedName, helmRepository *sourcev1.HelmRepository) wait.ConditionWithContextFunc {
284-
return func(ctx context.Context) (bool, error) {
285-
err := kubeClient.Get(ctx, namespacedName, helmRepository)
286-
if err != nil {
287-
return false, err
288-
}
289-
290-
if c := conditions.Get(helmRepository, meta.ReadyCondition); c != nil {
291-
// Confirm the Ready condition we are observing is for the
292-
// current generation
293-
if c.ObservedGeneration != helmRepository.GetGeneration() {
294-
return false, nil
295-
}
296-
297-
// Further check the Status
298-
switch c.Status {
299-
case metav1.ConditionTrue:
300-
return true, nil
301-
case metav1.ConditionFalse:
302-
return false, fmt.Errorf(c.Message)
303-
}
304-
}
305-
return false, nil
306-
}
307-
}

0 commit comments

Comments
 (0)