1
0
mirror of synced 2026-02-06 19:05:55 +00:00

non-reconciliable & readiness of static objects

Remove reconcile subcommand for static object APIs Alerts and Providers.

Add a isStatic() method on all the object adapters to determine if
they are static and don't have reconciler. The objects that don't
have reconcilers are skipped 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 <darkowlzz@protonmail.com>
This commit is contained in:
Sunny
2023-10-13 20:40:34 +00:00
parent 6135c326d8
commit b28b5dd9b9
22 changed files with 80 additions and 97 deletions

View File

@@ -132,7 +132,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Alert reconciliation") logger.Waitingf("waiting for Alert reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, &alert)); err != nil { isStaticObjectReadyConditionFunc(kubeClient, namespacedName, &alert)); err != nil {
return err return err
} }
logger.Successf("Alert %s is ready", name) logger.Successf("Alert %s is ready", name)

View File

@@ -127,7 +127,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
logger.Waitingf("waiting for Provider reconciliation") logger.Waitingf("waiting for Provider reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true,
isObjectReadyConditionFunc(kubeClient, namespacedName, &provider)); err != nil { isStaticObjectReadyConditionFunc(kubeClient, namespacedName, &provider)); err != nil {
return err return err
} }

View File

@@ -230,8 +230,12 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
} }
logger.Waitingf("waiting for HelmRepository source reconciliation") logger.Waitingf("waiting for HelmRepository source reconciliation")
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc := isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository)
isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository)); err != nil { 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 return err
} }
logger.Successf("HelmRepository source reconciliation completed") logger.Successf("HelmRepository source reconciliation completed")

View File

@@ -23,6 +23,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2" 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 { func (s alertListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i] item := s.Items[i]
status, msg := statusAndMessage(item.Status.Conditions) status, msg := string(metav1.ConditionTrue), "Alert is Ready"
return append(nameColumns(&item, includeNamespace, includeKind), return append(nameColumns(&item, includeNamespace, includeKind),
cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg) cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg)
} }

View File

@@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
notificationv1 "github.com/fluxcd/notification-controller/api/v1beta2" 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 { func (s alertProviderListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i] 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) return append(nameColumns(&item, includeNamespace, includeKind), status, msg)
} }

View File

@@ -23,6 +23,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
@@ -82,7 +83,12 @@ func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool,
if item.GetArtifact() != nil { if item.GetArtifact() != nil {
revision = item.GetArtifact().Revision 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) revision = utils.TruncateHex(revision)
msg = utils.TruncateHex(msg) msg = utils.TruncateHex(msg)
return append(nameColumns(&item, includeNamespace, includeKind), return append(nameColumns(&item, includeNamespace, includeKind),

View File

@@ -60,6 +60,7 @@ type reconcilable interface {
GetAnnotations() map[string]string GetAnnotations() map[string]string
SetAnnotations(map[string]string) SetAnnotations(map[string]string)
isStatic() bool // is it a static object that does not have a reconciler?
lastHandledReconcileRequest() string // what was the last handled reconcile request? lastHandledReconcileRequest() string // what was the last handled reconcile request?
successMessage() string // what do you want to tell people when successfully reconciled? 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 return err
} }
if reconcile.object.isStatic() {
logger.Successf("reconciliation not supported by the object")
return nil
}
if reconcile.object.isSuspended() { if reconcile.object.isSuspended() {
return fmt.Errorf("resource is suspended") return fmt.Errorf("resource is suspended")
} }

View File

@@ -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{&notificationv1.Alert{}},
}.run,
}
func init() {
reconcileCmd.AddCommand(reconcileAlertCmd)
}
func (obj alertAdapter) lastHandledReconcileRequest() string {
return obj.Status.GetLastHandledReconcileRequest()
}

View File

@@ -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{&notificationv1.Provider{}},
}.run,
}
func init() {
reconcileCmd.AddCommand(reconcileAlertProviderCmd)
}
func (obj alertProviderAdapter) lastHandledReconcileRequest() string {
return obj.Status.GetLastHandledReconcileRequest()
}

View File

@@ -81,3 +81,7 @@ func (obj helmReleaseAdapter) getSource() (reconcileSource, types.NamespacedName
Namespace: ns, Namespace: ns,
} }
} }
func (obj helmReleaseAdapter) isStatic() bool {
return false
}

View File

@@ -48,3 +48,7 @@ func (obj imageRepositoryAdapter) lastHandledReconcileRequest() string {
func (obj imageRepositoryAdapter) successMessage() string { func (obj imageRepositoryAdapter) successMessage() string {
return fmt.Sprintf("scan fetched %d tags", obj.Status.LastScanResult.TagCount) return fmt.Sprintf("scan fetched %d tags", obj.Status.LastScanResult.TagCount)
} }
func (obj imageRepositoryAdapter) isStatic() bool {
return false
}

View File

@@ -56,3 +56,7 @@ func (obj imageUpdateAutomationAdapter) successMessage() string {
} }
return "automation not yet run" return "automation not yet run"
} }
func (obj imageUpdateAutomationAdapter) isStatic() bool {
return false
}

View File

@@ -88,3 +88,7 @@ func (obj kustomizationAdapter) getSource() (reconcileSource, types.NamespacedNa
Namespace: obj.Spec.SourceRef.Namespace, Namespace: obj.Spec.SourceRef.Namespace,
} }
} }
func (obj kustomizationAdapter) isStatic() bool {
return false
}

View File

@@ -42,3 +42,7 @@ func init() {
func (obj receiverAdapter) lastHandledReconcileRequest() string { func (obj receiverAdapter) lastHandledReconcileRequest() string {
return obj.Status.GetLastHandledReconcileRequest() return obj.Status.GetLastHandledReconcileRequest()
} }
func (obj receiverAdapter) isStatic() bool {
return false
}

View File

@@ -48,3 +48,7 @@ func (obj bucketAdapter) lastHandledReconcileRequest() string {
func (obj bucketAdapter) successMessage() string { func (obj bucketAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj bucketAdapter) isStatic() bool {
return false
}

View File

@@ -84,3 +84,7 @@ func (obj helmChartAdapter) getSource() (reconcileSource, types.NamespacedName)
Namespace: obj.Namespace, Namespace: obj.Namespace,
} }
} }
func (obj helmChartAdapter) isStatic() bool {
return false
}

View File

@@ -48,3 +48,7 @@ func (obj gitRepositoryAdapter) lastHandledReconcileRequest() string {
func (obj gitRepositoryAdapter) successMessage() string { func (obj gitRepositoryAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj gitRepositoryAdapter) isStatic() bool {
return false
}

View File

@@ -60,3 +60,7 @@ func (obj helmRepositoryAdapter) successMessage() string {
} }
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj helmRepositoryAdapter) isStatic() bool {
return obj.Spec.Type == sourcev1.HelmRepositoryTypeOCI
}

View File

@@ -48,3 +48,7 @@ func (obj ociRepositoryAdapter) lastHandledReconcileRequest() string {
func (obj ociRepositoryAdapter) successMessage() string { func (obj ociRepositoryAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision) return fmt.Sprintf("fetched revision %s", obj.Status.Artifact.Revision)
} }
func (obj ociRepositoryAdapter) isStatic() bool {
return false
}

View File

@@ -56,6 +56,7 @@ type resumable interface {
copyable copyable
statusable statusable
setUnsuspended() setUnsuspended()
isStatic() bool
successMessage() string successMessage() string
} }
@@ -212,8 +213,12 @@ func (resume resumeCommand) reconcile(ctx context.Context, res resumable) reconc
logger.Waitingf("waiting for %s reconciliation", resume.kind) logger.Waitingf("waiting for %s reconciliation", resume.kind)
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc := isObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject())
isObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject())); err != nil { if res.isStatic() {
readyConditionFunc = isStaticObjectReadyConditionFunc(resume.client, namespacedName, res.asClientObject())
}
if err := wait.PollUntilContextTimeout(ctx, rootArgs.pollInterval, rootArgs.timeout, true, readyConditionFunc); err != nil {
return reconcileResponse{ return reconcileResponse{
resumable: res, resumable: res,
err: err, err: err,

View File

@@ -55,6 +55,10 @@ func (obj alertAdapter) successMessage() string {
return "Alert reconciliation completed" return "Alert reconciliation completed"
} }
func (a alertAdapter) isStatic() bool {
return true
}
func (a alertListAdapter) resumeItem(i int) resumable { func (a alertListAdapter) resumeItem(i int) resumable {
return &alertAdapter{&a.AlertList.Items[i]} return &alertAdapter{&a.AlertList.Items[i]}
} }

View File

@@ -55,6 +55,10 @@ func (obj alertProviderAdapter) successMessage() string {
return "Provider reconciliation completed" return "Provider reconciliation completed"
} }
func (a alertProviderAdapter) isStatic() bool {
return true
}
func (a alertProviderListAdapter) resumeItem(i int) resumable { func (a alertProviderListAdapter) resumeItem(i int) resumable {
return &alertProviderAdapter{&a.ProviderList.Items[i]} return &alertProviderAdapter{&a.ProviderList.Items[i]}
} }