From 112a94fcf2993172658055dbca3ada03867fd8b7 Mon Sep 17 00:00:00 2001 From: Sunny Date: Fri, 13 Oct 2023 20:40:34 +0000 Subject: [PATCH] non-reconciliable & readiness of static objects Remove reconcile subcommand for static object APIs Alerts and Providers. Add a hasReconciler() method on all the object adapters to determine if their configuration supports reconciliation. The objects that don't support reconciliation are skilled from reconciliation and readiness checks like HelmRepository of type OCI. Add default ready message for `get` subcommand output for static objects, Alerts, Providers and HelmRepositories of type OCI, as ready message can't be derived for them from their status. Signed-off-by: Sunny --- cmd/flux/create_alert.go | 2 +- cmd/flux/create_alertprovider.go | 2 +- cmd/flux/create_source_helm.go | 8 +++-- cmd/flux/get_alert.go | 3 +- cmd/flux/get_alertprovider.go | 3 +- cmd/flux/get_source_helm.go | 8 ++++- cmd/flux/reconcile.go | 6 ++++ cmd/flux/reconcile_alert.go | 44 -------------------------- cmd/flux/reconcile_alertprovider.go | 44 -------------------------- cmd/flux/reconcile_helmrelease.go | 4 +++ cmd/flux/reconcile_image_repository.go | 4 +++ cmd/flux/reconcile_image_updateauto.go | 4 +++ cmd/flux/reconcile_kustomization.go | 4 +++ cmd/flux/reconcile_receiver.go | 4 +++ cmd/flux/reconcile_source_bucket.go | 4 +++ cmd/flux/reconcile_source_chart.go | 4 +++ cmd/flux/reconcile_source_git.go | 4 +++ cmd/flux/reconcile_source_helm.go | 4 +++ cmd/flux/reconcile_source_oci.go | 4 +++ cmd/flux/resume.go | 10 ++++-- cmd/flux/resume_alert.go | 4 +++ cmd/flux/resume_alertprovider.go | 4 +++ 22 files changed, 81 insertions(+), 97 deletions(-) delete mode 100644 cmd/flux/reconcile_alert.go delete mode 100644 cmd/flux/reconcile_alertprovider.go diff --git a/cmd/flux/create_alert.go b/cmd/flux/create_alert.go index 22a5d28975..e750d44fd2 100644 --- a/cmd/flux/create_alert.go +++ b/cmd/flux/create_alert.go @@ -132,7 +132,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error { logger.Waitingf("waiting for Alert reconciliation") if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, - isObjectReadyConditionFunc(kubeClient, namespacedName, &alert)); err != nil { + isStaticObjectReadyConditionFunc(kubeClient, namespacedName, &alert)); err != nil { return err } logger.Successf("Alert %s is ready", name) diff --git a/cmd/flux/create_alertprovider.go b/cmd/flux/create_alertprovider.go index 468ec5d88d..402ff0c4f1 100644 --- a/cmd/flux/create_alertprovider.go +++ b/cmd/flux/create_alertprovider.go @@ -127,7 +127,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error { logger.Waitingf("waiting for Provider reconciliation") if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, - isObjectReadyConditionFunc(kubeClient, namespacedName, &provider)); err != nil { + isStaticObjectReadyConditionFunc(kubeClient, namespacedName, &provider)); err != nil { return err } diff --git a/cmd/flux/create_source_helm.go b/cmd/flux/create_source_helm.go index 5b46f45ea1..522e980fe7 100644 --- a/cmd/flux/create_source_helm.go +++ b/cmd/flux/create_source_helm.go @@ -230,8 +230,12 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for HelmRepository source reconciliation") - if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, - isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository)); err != nil { + readyConditionFunc := isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository) + if helmRepository.Spec.Type == sourcev1.HelmRepositoryTypeOCI { + // HelmRepository type OCI is a static object. + readyConditionFunc = isStaticObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository) + } + if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc); err != nil { return err } logger.Successf("HelmRepository source reconciliation completed") diff --git a/cmd/flux/get_alert.go b/cmd/flux/get_alert.go index 9ea6c682f1..760423c3b7 100644 --- a/cmd/flux/get_alert.go +++ b/cmd/flux/get_alert.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "golang.org/x/text/cases" "golang.org/x/text/language" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2" @@ -77,7 +78,7 @@ func init() { func (s alertListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string { item := s.Items[i] - status, msg := statusAndMessage(item.Status.Conditions) + status, msg := string(metav1.ConditionTrue), "Alert is Ready" return append(nameColumns(&item, includeNamespace, includeKind), cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg) } diff --git a/cmd/flux/get_alertprovider.go b/cmd/flux/get_alertprovider.go index 983cbf3362..a4c3bca6c0 100644 --- a/cmd/flux/get_alertprovider.go +++ b/cmd/flux/get_alertprovider.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2" @@ -74,7 +75,7 @@ func init() { func (s alertProviderListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string { item := s.Items[i] - status, msg := statusAndMessage(item.Status.Conditions) + status, msg := string(metav1.ConditionTrue), "Provider is Ready" return append(nameColumns(&item, includeNamespace, includeKind), status, msg) } diff --git a/cmd/flux/get_source_helm.go b/cmd/flux/get_source_helm.go index 173a18803b..ec131714ab 100644 --- a/cmd/flux/get_source_helm.go +++ b/cmd/flux/get_source_helm.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "golang.org/x/text/cases" "golang.org/x/text/language" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" @@ -82,7 +83,12 @@ func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool, if item.GetArtifact() != nil { revision = item.GetArtifact().Revision } - status, msg := statusAndMessage(item.Status.Conditions) + var status, msg string + if item.Spec.Type == sourcev1.HelmRepositoryTypeOCI { + status, msg = string(metav1.ConditionTrue), "Helm repository is Ready" + } else { + status, msg = statusAndMessage(item.Status.Conditions) + } revision = utils.TruncateHex(revision) msg = utils.TruncateHex(msg) return append(nameColumns(&item, includeNamespace, includeKind), diff --git a/cmd/flux/reconcile.go b/cmd/flux/reconcile.go index 0b9407d6c3..b94e9ff7ce 100644 --- a/cmd/flux/reconcile.go +++ b/cmd/flux/reconcile.go @@ -60,6 +60,7 @@ type reconcilable interface { GetAnnotations() map[string]string SetAnnotations(map[string]string) + hasReconciler() bool // does the object's current configuration has a reconciler to reconcile it? lastHandledReconcileRequest() string // what was the last handled reconcile request? successMessage() string // what do you want to tell people when successfully reconciled? } @@ -100,6 +101,11 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error { return err } + if !reconcile.object.hasReconciler() { + logger.Successf("reconciliation not supported by the object") + return nil + } + if reconcile.object.isSuspended() { return fmt.Errorf("resource is suspended") } diff --git a/cmd/flux/reconcile_alert.go b/cmd/flux/reconcile_alert.go deleted file mode 100644 index 8dd8be6132..0000000000 --- a/cmd/flux/reconcile_alert.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright 2020 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "github.com/spf13/cobra" - - notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2" -) - -var reconcileAlertCmd = &cobra.Command{ - Use: "alert [name]", - Short: "Reconcile an Alert", - Long: `The reconcile alert command triggers a reconciliation of an Alert resource and waits for it to finish.`, - Example: ` # Trigger a reconciliation for an existing alert - flux reconcile alert main`, - ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), - RunE: reconcileCommand{ - apiType: alertType, - object: alertAdapter{¬ificationv1.Alert{}}, - }.run, -} - -func init() { - reconcileCmd.AddCommand(reconcileAlertCmd) -} - -func (obj alertAdapter) lastHandledReconcileRequest() string { - return obj.Status.GetLastHandledReconcileRequest() -} diff --git a/cmd/flux/reconcile_alertprovider.go b/cmd/flux/reconcile_alertprovider.go deleted file mode 100644 index 5c3001af1a..0000000000 --- a/cmd/flux/reconcile_alertprovider.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright 2020 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "github.com/spf13/cobra" - - notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2" -) - -var reconcileAlertProviderCmd = &cobra.Command{ - Use: "alert-provider [name]", - Short: "Reconcile a Provider", - Long: `The reconcile alert-provider command triggers a reconciliation of a Provider resource and waits for it to finish.`, - Example: ` # Trigger a reconciliation for an existing provider - flux reconcile alert-provider slack`, - ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)), - RunE: reconcileCommand{ - apiType: alertProviderType, - object: alertProviderAdapter{¬ificationv1.Provider{}}, - }.run, -} - -func init() { - reconcileCmd.AddCommand(reconcileAlertProviderCmd) -} - -func (obj alertProviderAdapter) lastHandledReconcileRequest() string { - return obj.Status.GetLastHandledReconcileRequest() -} diff --git a/cmd/flux/reconcile_helmrelease.go b/cmd/flux/reconcile_helmrelease.go index b015aa8b2d..038c8144bf 100644 --- a/cmd/flux/reconcile_helmrelease.go +++ b/cmd/flux/reconcile_helmrelease.go @@ -81,3 +81,7 @@ func (obj helmReleaseAdapter) getSource() (reconcileSource, types.NamespacedName Namespace: ns, } } + +func (obj helmReleaseAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_image_repository.go b/cmd/flux/reconcile_image_repository.go index c7304eb7b1..89320c0df7 100644 --- a/cmd/flux/reconcile_image_repository.go +++ b/cmd/flux/reconcile_image_repository.go @@ -48,3 +48,7 @@ func (obj imageRepositoryAdapter) lastHandledReconcileRequest() string { func (obj imageRepositoryAdapter) successMessage() string { return fmt.Sprintf("scan fetched %d tags", obj.Status.LastScanResult.TagCount) } + +func (obj imageRepositoryAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_image_updateauto.go b/cmd/flux/reconcile_image_updateauto.go index 2db4a1c020..1fca0270bd 100644 --- a/cmd/flux/reconcile_image_updateauto.go +++ b/cmd/flux/reconcile_image_updateauto.go @@ -56,3 +56,7 @@ func (obj imageUpdateAutomationAdapter) successMessage() string { } return "automation not yet run" } + +func (obj imageUpdateAutomationAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_kustomization.go b/cmd/flux/reconcile_kustomization.go index 99d1254512..d9eb01f9b4 100644 --- a/cmd/flux/reconcile_kustomization.go +++ b/cmd/flux/reconcile_kustomization.go @@ -88,3 +88,7 @@ func (obj kustomizationAdapter) getSource() (reconcileSource, types.NamespacedNa Namespace: obj.Spec.SourceRef.Namespace, } } + +func (obj kustomizationAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_receiver.go b/cmd/flux/reconcile_receiver.go index 42a2dd24ab..a0bb82e075 100644 --- a/cmd/flux/reconcile_receiver.go +++ b/cmd/flux/reconcile_receiver.go @@ -42,3 +42,7 @@ func init() { func (obj receiverAdapter) lastHandledReconcileRequest() string { return obj.Status.GetLastHandledReconcileRequest() } + +func (obj receiverAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_source_bucket.go b/cmd/flux/reconcile_source_bucket.go index 2a2bbdbc71..bda3e2e898 100644 --- a/cmd/flux/reconcile_source_bucket.go +++ b/cmd/flux/reconcile_source_bucket.go @@ -48,3 +48,7 @@ func (obj bucketAdapter) lastHandledReconcileRequest() string { func (obj bucketAdapter) successMessage() string { return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) } + +func (obj bucketAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_source_chart.go b/cmd/flux/reconcile_source_chart.go index 4154061780..8056e03011 100644 --- a/cmd/flux/reconcile_source_chart.go +++ b/cmd/flux/reconcile_source_chart.go @@ -84,3 +84,7 @@ func (obj helmChartAdapter) getSource() (reconcileSource, types.NamespacedName) Namespace: obj.Namespace, } } + +func (obj helmChartAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_source_git.go b/cmd/flux/reconcile_source_git.go index a42cd7b959..047fa6e869 100644 --- a/cmd/flux/reconcile_source_git.go +++ b/cmd/flux/reconcile_source_git.go @@ -48,3 +48,7 @@ func (obj gitRepositoryAdapter) lastHandledReconcileRequest() string { func (obj gitRepositoryAdapter) successMessage() string { return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) } + +func (obj gitRepositoryAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/reconcile_source_helm.go b/cmd/flux/reconcile_source_helm.go index f559a5e4c8..de640d24d7 100644 --- a/cmd/flux/reconcile_source_helm.go +++ b/cmd/flux/reconcile_source_helm.go @@ -60,3 +60,7 @@ func (obj helmRepositoryAdapter) successMessage() string { } return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) } + +func (obj helmRepositoryAdapter) hasReconciler() bool { + return obj.Spec.Type != sourcev1.HelmRepositoryTypeOCI +} diff --git a/cmd/flux/reconcile_source_oci.go b/cmd/flux/reconcile_source_oci.go index ffc649f9b3..abea7db222 100644 --- a/cmd/flux/reconcile_source_oci.go +++ b/cmd/flux/reconcile_source_oci.go @@ -48,3 +48,7 @@ func (obj ociRepositoryAdapter) lastHandledReconcileRequest() string { func (obj ociRepositoryAdapter) successMessage() string { return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) } + +func (obj ociRepositoryAdapter) hasReconciler() bool { + return true +} diff --git a/cmd/flux/resume.go b/cmd/flux/resume.go index 4cb700a27a..e2dd187413 100644 --- a/cmd/flux/resume.go +++ b/cmd/flux/resume.go @@ -56,6 +56,7 @@ type resumable interface { copyable statusable setUnsuspended() + hasReconciler() bool successMessage() string } @@ -212,8 +213,13 @@ func (resume resumeCommand) reconcile(ctx context.Context, res resumable) reconc logger.Waitingf("waiting for %s reconciliation", resume.kind) - if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, - isObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject())); err != nil { + readyConditionFunc := isObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject()) + if !res.hasReconciler() { + // Objects without reconciler are static objects. + readyConditionFunc = isStaticObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject()) + } + + if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc); err != nil { return reconcileResponse{ resumable: res, err: err, diff --git a/cmd/flux/resume_alert.go b/cmd/flux/resume_alert.go index 713aebb38a..cae056390b 100644 --- a/cmd/flux/resume_alert.go +++ b/cmd/flux/resume_alert.go @@ -55,6 +55,10 @@ func (obj alertAdapter) successMessage() string { return "Alert reconciliation completed" } +func (a alertAdapter) hasReconciler() bool { + return false +} + func (a alertListAdapter) resumeItem(i int) resumable { return &alertAdapter{&a.AlertList.Items[i]} } diff --git a/cmd/flux/resume_alertprovider.go b/cmd/flux/resume_alertprovider.go index e0ba49b93b..1b53fab8d2 100644 --- a/cmd/flux/resume_alertprovider.go +++ b/cmd/flux/resume_alertprovider.go @@ -55,6 +55,10 @@ func (obj alertProviderAdapter) successMessage() string { return "Provider reconciliation completed" } +func (a alertProviderAdapter) hasReconciler() bool { + return false +} + func (a alertProviderListAdapter) resumeItem(i int) resumable { return &alertProviderAdapter{&a.ProviderList.Items[i]} }