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")
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)

View File

@@ -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
}

View File

@@ -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")

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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),

View File

@@ -60,6 +60,7 @@ type reconcilable interface {
GetAnnotations() 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?
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.isStatic() {
logger.Successf("reconciliation not supported by the object")
return nil
}
if reconcile.object.isSuspended() {
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,
}
}
func (obj helmReleaseAdapter) isStatic() bool {
return false
}

View File

@@ -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) isStatic() bool {
return false
}

View File

@@ -56,3 +56,7 @@ func (obj imageUpdateAutomationAdapter) successMessage() string {
}
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,
}
}
func (obj kustomizationAdapter) isStatic() bool {
return false
}

View File

@@ -42,3 +42,7 @@ func init() {
func (obj receiverAdapter) lastHandledReconcileRequest() string {
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 {
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,
}
}
func (obj helmChartAdapter) isStatic() bool {
return false
}

View File

@@ -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) 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)
}
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 {
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
statusable
setUnsuspended()
isStatic() bool
successMessage() string
}
@@ -212,8 +213,12 @@ 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.isStatic() {
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,

View File

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

View File

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