diff --git a/clm/cmd/apply.go b/clm/cmd/apply.go index 9be2fa3d..f5bc5a80 100644 --- a/clm/cmd/apply.go +++ b/clm/cmd/apply.go @@ -7,6 +7,7 @@ package cmd import ( "context" + "errors" "fmt" "os" "time" @@ -17,7 +18,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apitypes "k8s.io/apimachinery/pkg/types" - utilerrors "k8s.io/apimachinery/pkg/util/errors" "github.com/sap/component-operator-runtime/clm/internal/backoff" "github.com/sap/component-operator-runtime/clm/internal/manifests" @@ -108,7 +108,7 @@ func newApplyCmd() *cobra.Command { release.State = component.StateError } if updateErr := releaseClient.Update(context.TODO(), release); updateErr != nil { - err = utilerrors.NewAggregate([]error{err, updateErr}) + err = errors.Join(err, updateErr) } }() diff --git a/clm/cmd/delete.go b/clm/cmd/delete.go index 0a30d599..bc47a86c 100644 --- a/clm/cmd/delete.go +++ b/clm/cmd/delete.go @@ -7,12 +7,12 @@ package cmd import ( "context" + "errors" "fmt" "os" "time" "github.com/spf13/cobra" - utilerrors "k8s.io/apimachinery/pkg/util/errors" "github.com/sap/component-operator-runtime/clm/internal/backoff" "github.com/sap/component-operator-runtime/clm/internal/release" @@ -87,7 +87,7 @@ func newDeleteCmd() *cobra.Command { release.State = component.StateError } if updateErr := releaseClient.Update(context.TODO(), release); updateErr != nil { - err = utilerrors.NewAggregate([]error{err, updateErr}) + err = errors.Join(err, updateErr) } }() diff --git a/go.mod b/go.mod index bce2f503..fc07073a 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/go-git/go-git v4.7.0+incompatible github.com/go-logr/logr v1.4.3 github.com/gobwas/glob v0.2.3 - github.com/hashicorp/go-multierror v1.1.1 github.com/iancoleman/strcase v0.3.0 github.com/onsi/ginkgo/v2 v2.27.3 github.com/onsi/gomega v1.38.3 @@ -60,7 +59,6 @@ require ( github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect diff --git a/go.sum b/go.sum index e3b0e79d..b66fce63 100644 --- a/go.sum +++ b/go.sum @@ -102,11 +102,6 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= diff --git a/internal/clientfactory/factory.go b/internal/clientfactory/factory.go index 08d4f1db..3149f8a0 100644 --- a/internal/clientfactory/factory.go +++ b/internal/clientfactory/factory.go @@ -9,7 +9,6 @@ import ( "crypto/sha256" "encoding/json" "fmt" - "net/http" "reflect" "sync" "time" @@ -121,12 +120,6 @@ func (f *ClientFactory) Get(kubeConfig []byte, impersonationUser string, imperso return clnt, nil } - config.Wrap(func(rt http.RoundTripper) http.RoundTripper { - return roundTripperFunc(func(r *http.Request) (*http.Response, error) { - metrics.Requests.WithLabelValues(f.controllerName, r.Method).Inc() - return rt.RoundTrip(r) - }) - }) clnt, err := NewClientFor(config, f.scheme, f.name) if err != nil { return nil, err @@ -149,11 +142,3 @@ func sha256sum(data any) string { sha256sum := sha256.Sum256(dataAsJson) return string(sha256sum[:]) } - -type roundTripperFunc func(r *http.Request) (*http.Response, error) - -var _ http.RoundTripper = roundTripperFunc(nil) - -func (f roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { - return f(r) -} diff --git a/internal/helm/hooks.go b/internal/helm/hooks.go index c58ced6d..d2361e4f 100644 --- a/internal/helm/hooks.go +++ b/internal/helm/hooks.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -44,7 +44,7 @@ func ParseHookMetadata(object client.Object) (*HookMetadata, error) { if value, ok := annotations[annotationKeyHookWeight]; ok { weight, err := strconv.Atoi(value) if err != nil { - return nil, errors.Wrapf(err, "invalid hook weight: %s", value) + return nil, legacyerrors.Wrapf(err, "invalid hook weight: %s", value) } if weight < HookMinWeight || weight > HookMaxWeight { return nil, fmt.Errorf("invalid hook weight: %d (allowed range: %d..%d)", weight, HookMinWeight, HookMaxWeight) diff --git a/internal/templatex/functions.go b/internal/templatex/functions.go index 020f5da9..57525984 100644 --- a/internal/templatex/functions.go +++ b/internal/templatex/functions.go @@ -9,13 +9,13 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "math" "strconv" "strings" "text/template" - "github.com/pkg/errors" "github.com/sap/go-generics/slices" "github.com/spf13/cast" @@ -232,7 +232,7 @@ func parseIPv4Address(data any) (uint32, error) { } octets := strings.Split(s, ".") if len(octets) != 4 { - return 0, errors.New("invalid IP address") + return 0, fmt.Errorf("invalid IP address") } var r uint64 for i := uint64(0); i < 4; i++ { diff --git a/internal/walk/walk.go b/internal/walk/walk.go index 135d3857..91d304d7 100644 --- a/internal/walk/walk.go +++ b/internal/walk/walk.go @@ -6,12 +6,11 @@ SPDX-License-Identifier: Apache-2.0 package walk import ( + "errors" "fmt" "reflect" "strconv" "strings" - - "github.com/hashicorp/go-multierror" ) type WalkFunc func(x any, path []string, tag reflect.StructTag) error @@ -42,7 +41,7 @@ func Walk(x any, f WalkFunc) error { } errs := walk(v, nil, "", f) if len(errs) > 0 { - return multierror.Append(nil, errs...) + return errors.Join(errs...) } return nil } diff --git a/pkg/component/reconciler.go b/pkg/component/reconciler.go index e777ad6e..66a681dc 100755 --- a/pkg/component/reconciler.go +++ b/pkg/component/reconciler.go @@ -7,7 +7,9 @@ package component import ( "context" + "errors" "fmt" + "net/http" "reflect" "regexp" "strconv" @@ -15,7 +17,7 @@ import ( "sync" "time" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "github.com/sap/go-generics/slices" corev1 "k8s.io/api/core/v1" @@ -23,8 +25,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" apitypes "k8s.io/apimachinery/pkg/types" - utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" "k8s.io/client-go/util/workqueue" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -82,7 +84,7 @@ const ( defaultReapplyInterval = 60 * time.Minute ) -// TODO: should we pass cluster.Client to hooks instead of just client.Client? +// TODO: should we pass cluster.Client to hooks instead of just client.Client (or, in the other direction, just client.Reader)? // HookFunc is the function signature that can be used to // establish callbacks at certain points in the reconciliation logic. @@ -132,18 +134,21 @@ type ReconcilerOptions struct { // target client. SchemeBuilder types.SchemeBuilder // NewClient allows to modify or replace the default client used by the reconciler. - // The returned client is used by the reconciler to manage the component instances, and passed to hooks. + // The returned client is used by the reconciler to manage the component instances. // Its scheme therefore must recognize the component type. NewClient NewClientFunc } // Reconciler provides the implementation of controller-runtime's Reconciler interface, for a given Component type T. type Reconciler[T Component] struct { - name string - id string - groupVersionKind schema.GroupVersionKind - controllerName string - client cluster.Client + name string + id string + groupVersionKind schema.GroupVersionKind + controllerName string + // TODO: client could be just a client.Client + client cluster.Client + // TODO: hookClient could be just a client.Client or even client.Reader + hookClient cluster.Client eventRecorder events.DeduplicatingRecorder resourceGenerator manifests.Generator statusAnalyzer status.StatusAnalyzer @@ -225,7 +230,7 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result log.V(1).Info("not found; ignoring") return ctrl.Result{}, nil } - return ctrl.Result{}, errors.Wrap(err, "unexpected get error") + return ctrl.Result{}, legacyerrors.Wrap(err, "unexpected get error") } component.GetObjectKind().SetGroupVersionKind(r.groupVersionKind) // componentDigest is populated after setting up the status handler, right before the post-read hook phase @@ -290,7 +295,7 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result // remains to be done; note: it may happen (if the apply runs successfully through on the first iteration) // that status.processingSince is never set, and this additional trigger does not happen if status.ProcessingSince != nil { - result = ctrl.Result{RequeueAfter: 1 * time.Millisecond} + result = ctrl.Result{RequeueAfter: time.Millisecond} } // clear processing state; note that processing will be off until the next component digest change; // if (for whatever reason) the state would again flip to Processing, or an error would occur, then @@ -439,7 +444,7 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result } } if updateErr := r.client.Status().Update(ctx, component, client.FieldOwner(*r.options.FieldOwner)); updateErr != nil { - err = utilerrors.NewAggregate([]error{err, updateErr}) + err = errors.Join(err, updateErr) result = ctrl.Result{} } }() @@ -447,13 +452,13 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result // set a first status (and requeue, because the status update itself will not trigger another reconciliation because of the event filter set) if status.ObservedGeneration <= 0 { status.SetState(StatePending, ReadyConditionReasonNew, "First seen") - return ctrl.Result{RequeueAfter: 1 * time.Millisecond}, nil + return ctrl.Result{RequeueAfter: time.Millisecond}, nil } // resolve references - componentDigest, err = resolveReferences(ctx, r.client, component) + componentDigest, err = resolveReferences(ctx, r.client, r.hookClient, component) if err != nil { - return ctrl.Result{}, errors.Wrap(err, "error resolving references") + return ctrl.Result{}, legacyerrors.Wrap(err, "error resolving references") } if component.GetDeletionTimestamp().IsZero() { @@ -467,7 +472,7 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result status.ProcessingDigest = componentDigest r.backoff.Forget(req) status.SetState(StateProcessing, ReadyConditionReasonRestarting, "Restarting processing due to component changes") - return ctrl.Result{RequeueAfter: 1 * time.Millisecond}, nil + return ctrl.Result{RequeueAfter: time.Millisecond}, nil } } else { status.ProcessingSince = nil @@ -481,19 +486,19 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result hookCtx := NewContext(ctx). WithReconcilerName(r.name) for hookOrder, hook := range r.postReadHooks { - if err := hook(hookCtx, r.client, component); err != nil { - return ctrl.Result{}, errors.Wrapf(err, "error running post-read hook (%d)", hookOrder) + if err := hook(hookCtx, r.hookClient, component); err != nil { + return ctrl.Result{}, legacyerrors.Wrapf(err, "error running post-read hook (%d)", hookOrder) } } // setup target localClient, err := r.getLocalClientForComponent(component) if err != nil { - return ctrl.Result{}, errors.Wrap(err, "error getting local client for component") + return ctrl.Result{}, legacyerrors.Wrap(err, "error getting local client for component") } targetClient, err := r.getClientForComponent(component) if err != nil { - return ctrl.Result{}, errors.Wrap(err, "error getting client for component") + return ctrl.Result{}, legacyerrors.Wrap(err, "error getting client for component") } targetOptions := r.getOptionsForComponent(component) target := newReconcileTarget[T](r.name, r.id, localClient, targetClient, r.resourceGenerator, targetOptions) @@ -510,30 +515,30 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result // TODO: optionally (to be completely consistent) set finalizer through a mutating webhook if added := controllerutil.AddFinalizer(component, *r.options.Finalizer); added { if err := r.client.Update(ctx, component, client.FieldOwner(*r.options.FieldOwner)); err != nil { - return ctrl.Result{}, errors.Wrap(err, "error adding finalizer") + return ctrl.Result{}, legacyerrors.Wrap(err, "error adding finalizer") } // trigger another round trip // this is necessary because the update call invalidates potential changes done to the component by the post-read // hook above; this means, not to the object itself, but for example to loaded secrets or config maps; // in the following round trip, the finalizer will already be there, and the update will not happen again - return ctrl.Result{RequeueAfter: 1 * time.Millisecond}, nil + return ctrl.Result{RequeueAfter: time.Millisecond}, nil } log.V(2).Info("reconciling dependent resources") for hookOrder, hook := range r.preReconcileHooks { - if err := hook(hookCtx, r.client, component); err != nil { - return ctrl.Result{}, errors.Wrapf(err, "error running pre-reconcile hook (%d)", hookOrder) + if err := hook(hookCtx, r.hookClient, component); err != nil { + return ctrl.Result{}, legacyerrors.Wrapf(err, "error running pre-reconcile hook (%d)", hookOrder) } } ok, err := target.Apply(ctx, component, componentDigest) if err != nil { log.V(1).Info("error while reconciling dependent resources") - return ctrl.Result{}, errors.Wrap(err, "error reconciling dependent resources") + return ctrl.Result{}, legacyerrors.Wrap(err, "error reconciling dependent resources") } if ok { for hookOrder, hook := range r.postReconcileHooks { - if err := hook(hookCtx, r.client, component); err != nil { - return ctrl.Result{}, errors.Wrapf(err, "error running post-reconcile hook (%d)", hookOrder) + if err := hook(hookCtx, r.hookClient, component); err != nil { + return ctrl.Result{}, legacyerrors.Wrapf(err, "error running post-reconcile hook (%d)", hookOrder) } } log.V(1).Info("all dependent resources successfully reconciled") @@ -554,14 +559,14 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result } } else { for hookOrder, hook := range r.preDeleteHooks { - if err := hook(hookCtx, r.client, component); err != nil { - return ctrl.Result{}, errors.Wrapf(err, "error running pre-delete hook (%d)", hookOrder) + if err := hook(hookCtx, r.hookClient, component); err != nil { + return ctrl.Result{}, legacyerrors.Wrapf(err, "error running pre-delete hook (%d)", hookOrder) } } allowed, msg, err := target.IsDeletionAllowed(ctx, component) if err != nil { log.V(1).Info("error while checking if deletion is allowed") - return ctrl.Result{}, errors.Wrap(err, "error checking whether deletion is possible") + return ctrl.Result{}, legacyerrors.Wrap(err, "error checking whether deletion is possible") } if !allowed { // deletion is blocked because of existing managed CROs and so on @@ -583,19 +588,19 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result ok, err := target.Delete(ctx, component) if err != nil { log.V(1).Info("error while deleting dependent resources") - return ctrl.Result{}, errors.Wrap(err, "error deleting dependent resources") + return ctrl.Result{}, legacyerrors.Wrap(err, "error deleting dependent resources") } if ok { for hookOrder, hook := range r.postDeleteHooks { - if err := hook(hookCtx, r.client, component); err != nil { - return ctrl.Result{}, errors.Wrapf(err, "error running post-delete hook (%d)", hookOrder) + if err := hook(hookCtx, r.hookClient, component); err != nil { + return ctrl.Result{}, legacyerrors.Wrapf(err, "error running post-delete hook (%d)", hookOrder) } } // all dependent resources are already gone, so that's it log.V(1).Info("all dependent resources are successfully deleted; removing finalizer") if removed := controllerutil.RemoveFinalizer(component, *r.options.Finalizer); removed { if err := r.client.Update(ctx, component, client.FieldOwner(*r.options.FieldOwner)); err != nil { - return ctrl.Result{}, errors.Wrap(err, "error removing finalizer") + return ctrl.Result{}, legacyerrors.Wrap(err, "error removing finalizer") } } // skip status update, since the instance will anyway deleted timely by the API server @@ -691,11 +696,14 @@ func (r *Reconciler[T]) WithPostDeleteHook(hook HookFunc[T]) *Reconciler[T] { // Register the reconciler with a given controller-runtime Manager and Builder. // This will call For() and Complete() on the provided builder. -// It populates the recnciler's client with an enhnanced client derived from mgr.GetClient() and mgr.GetConfig(). -// That client is used for three purposes: +// It populates the reconciler's client with a dedicated client derived from mgr.GetConfig() and mgr.GetScheme(). +// That client is used for the following purposes: // - reading/updating the reconciled component, sending events for this component +// - it is used to resolve configmap(key) and secret(key) references; +// as a consequence, mgr.GetScheme() must recognize the core group (v1) and the component type. +// Note that the manager's client (that is mgr.GetClient()) is used as well, for the following purposes: // - it is passed to hooks -// - it is passed to the factory for target clients as a default local client +// - is is used to resolved generic references, that is, spec fields implementing the Reference[T] interface. func (r *Reconciler[T]) SetupWithManagerAndBuilder(mgr ctrl.Manager, blder *ctrl.Builder) error { r.setupMutex.Lock() defer r.setupMutex.Unlock() @@ -705,28 +713,38 @@ func (r *Reconciler[T]) SetupWithManagerAndBuilder(mgr ctrl.Manager, blder *ctrl kubeSystemNamespace := &corev1.Namespace{} if err := mgr.GetAPIReader().Get(context.Background(), apitypes.NamespacedName{Name: "kube-system"}, kubeSystemNamespace); err != nil { - return errors.Wrap(err, "error retrieving uid of kube-system namespace") + return legacyerrors.Wrap(err, "error retrieving uid of kube-system namespace") } r.id = string(kubeSystemNamespace.UID) - discoveryClient, err := discovery.NewDiscoveryClientForConfigAndClient(mgr.GetConfig(), mgr.GetHTTPClient()) - if err != nil { - return errors.Wrap(err, "error creating discovery client") - } - r.client = cluster.NewClient(mgr.GetClient(), discoveryClient, mgr.GetEventRecorderFor(r.name), mgr.GetConfig(), mgr.GetHTTPClient()) + var err error + config := rest.CopyConfig(mgr.GetConfig()) + config.Wrap(func(rt http.RoundTripper) http.RoundTripper { + return roundTripperFunc(func(request *http.Request) (*http.Response, error) { + metrics.Requests.WithLabelValues(r.controllerName, request.Method).Inc() + return rt.RoundTrip(request) + }) + }) + r.client, err = clientfactory.NewClientFor(config, mgr.GetScheme(), r.name) if r.options.NewClient != nil { clnt, err := r.options.NewClient(r.client) if err != nil { - return errors.Wrap(err, "error calling custom client constructor") + return legacyerrors.Wrap(err, "error calling custom client constructor") } r.client = clnt } r.eventRecorder = *events.NewDeduplicatingRecorder(r.client.EventRecorder()) + discoveryClient, err := discovery.NewDiscoveryClientForConfigAndClient(config, mgr.GetHTTPClient()) + if err != nil { + return legacyerrors.Wrap(err, "error creating discovery client") + } + r.hookClient = cluster.NewClient(mgr.GetClient(), discoveryClient, mgr.GetEventRecorderFor(r.name), config, mgr.GetHTTPClient()) + component := newComponent[T]() r.groupVersionKind, err = apiutil.GVKForObject(component, r.client.Scheme()) if err != nil { - return errors.Wrap(err, "error getting type metadata for component") + return legacyerrors.Wrap(err, "error getting type metadata for component") } // TODO: should this be more fully qualified, or configurable? // for now we reproduce the controller-runtime default (the lowercase kind of the reconciled type) @@ -739,9 +757,9 @@ func (r *Reconciler[T]) SetupWithManagerAndBuilder(mgr ctrl.Manager, blder *ctrl if r.options.SchemeBuilder != nil { schemeBuilders = append(schemeBuilders, r.options.SchemeBuilder) } - r.clients, err = clientfactory.NewClientFactory(r.name, r.controllerName, mgr.GetConfig(), schemeBuilders) + r.clients, err = clientfactory.NewClientFactory(r.name, r.controllerName, config, schemeBuilders) if err != nil { - return errors.Wrap(err, "error creating client factory") + return legacyerrors.Wrap(err, "error creating client factory") } if err := blder. @@ -754,7 +772,7 @@ func (r *Reconciler[T]) SetupWithManagerAndBuilder(mgr ctrl.Manager, blder *ctrl source.WithBufferSize[apitypes.NamespacedName, reconcile.Request](triggerBufferSize))). Named(r.controllerName). Complete(r); err != nil { - return errors.Wrap(err, "error creating controller") + return legacyerrors.Wrap(err, "error creating controller") } r.setupComplete = true @@ -790,7 +808,7 @@ func (r *Reconciler[T]) getLocalClientForComponent(component T) (cluster.Client, } clnt, err := r.clients.Get(nil, impersonationUser, impersonationGroups) if err != nil { - return nil, errors.Wrap(err, "error getting local client") + return nil, legacyerrors.Wrap(err, "error getting local client") } return clnt, nil } @@ -837,7 +855,7 @@ func (r *Reconciler[T]) getClientForComponent(component T) (cluster.Client, erro } clnt, err := r.clients.Get(kubeConfig, impersonationUser, impersonationGroups) if err != nil { - return nil, errors.Wrap(err, "error getting target client") + return nil, legacyerrors.Wrap(err, "error getting target client") } return clnt, nil } @@ -884,3 +902,11 @@ func (r *Reconciler[T]) getOptionsForComponent(component T) reconciler.Reconcile } return options } + +type roundTripperFunc func(r *http.Request) (*http.Response, error) + +var _ http.RoundTripper = roundTripperFunc(nil) + +func (f roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { + return f(r) +} diff --git a/pkg/component/reference.go b/pkg/component/reference.go index 8a6b6533..c4740c28 100644 --- a/pkg/component/reference.go +++ b/pkg/component/reference.go @@ -18,7 +18,7 @@ import ( apitypes "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "github.com/sap/component-operator-runtime/internal/walk" "github.com/sap/component-operator-runtime/pkg/types" ) @@ -56,9 +56,9 @@ func (r *ConfigMapReference) load(ctx context.Context, clnt client.Client, names if ignoreNotFound { return nil } - return types.NewRetriableError(errors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name), ref(retryAfter)) + return types.NewRetriableError(legacyerrors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name), ref(retryAfter)) } else { - return errors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name) + return legacyerrors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name) } } r.data = configMap.Data @@ -105,9 +105,9 @@ func (r *ConfigMapKeyReference) load(ctx context.Context, clnt client.Client, na if ignoreNotFound { return nil } - return types.NewRetriableError(errors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name), ref(retryAfter)) + return types.NewRetriableError(legacyerrors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name), ref(retryAfter)) } else { - return errors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name) + return legacyerrors.Wrapf(err, "error loading configmap %s/%s", namespace, r.Name) } } if r.Key != "" { @@ -166,9 +166,9 @@ func (r *SecretReference) load(ctx context.Context, clnt client.Client, namespac if ignoreNotFound { return nil } - return types.NewRetriableError(errors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name), ref(retryAfter)) + return types.NewRetriableError(legacyerrors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name), ref(retryAfter)) } else { - return errors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name) + return legacyerrors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name) } } r.data = secret.Data @@ -215,9 +215,9 @@ func (r *SecretKeyReference) load(ctx context.Context, clnt client.Client, names if ignoreNotFound { return nil } - return types.NewRetriableError(errors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name), ref(retryAfter)) + return types.NewRetriableError(legacyerrors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name), ref(retryAfter)) } else { - return errors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name) + return legacyerrors.Wrapf(err, "error loading secret %s/%s", namespace, r.Name) } } if r.Key != "" { @@ -272,7 +272,7 @@ type Reference[T Component] interface { Digest() string } -func resolveReferences[T Component](ctx context.Context, clnt client.Client, component T) (string, error) { +func resolveReferences[T Component](ctx context.Context, clnt client.Client, hookClient client.Client, component T) (string, error) { digestData := make(map[string]any) spec := getSpec(component) digestData["generation"] = component.GetGeneration() @@ -331,7 +331,7 @@ func resolveReferences[T Component](ctx context.Context, clnt client.Client, com if v := reflect.ValueOf(r); r == nil || v.Kind() == reflect.Pointer && v.IsNil() { return nil } - if err := r.Load(ctx, clnt, component); err != nil { + if err := r.Load(ctx, hookClient, component); err != nil { return err } digestData["refs:"+string(rawPath)] = r.Digest() diff --git a/pkg/component/target.go b/pkg/component/target.go index e2f612ed..4ed366ea 100644 --- a/pkg/component/target.go +++ b/pkg/component/target.go @@ -8,7 +8,7 @@ package component import ( "context" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "github.com/sap/component-operator-runtime/pkg/cluster" "github.com/sap/component-operator-runtime/pkg/manifests" @@ -63,7 +63,7 @@ func (t *reconcileTarget[T]) Apply(ctx context.Context, component T, componentDi WithComponentDigest(componentDigest) objects, err := t.resourceGenerator.Generate(generateCtx, namespace, name, component.GetSpec()) if err != nil { - return false, errors.Wrap(err, "error rendering manifests") + return false, legacyerrors.Wrap(err, "error rendering manifests") } return t.reconciler.Apply(ctx, &status.Inventory, objects, namespace, ownerId, componentDigest) diff --git a/pkg/manifests/generator.go b/pkg/manifests/generator.go index d2bb8486..20b9ad60 100644 --- a/pkg/manifests/generator.go +++ b/pkg/manifests/generator.go @@ -8,7 +8,7 @@ package manifests import ( "context" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "sigs.k8s.io/controller-runtime/pkg/client" @@ -40,7 +40,7 @@ func (g *tranformableGenerator) Generate(ctx context.Context, namespace string, for i, transformer := range g.parameterTransformers { _parameters, err := transformer.TransformParameters(namespace, name, parameters) if err != nil { - return nil, errors.Wrapf(err, "error calling parameter transformer (%d)", i) + return nil, legacyerrors.Wrapf(err, "error calling parameter transformer (%d)", i) } parameters = _parameters } @@ -51,7 +51,7 @@ func (g *tranformableGenerator) Generate(ctx context.Context, namespace string, for i, transformer := range g.objectTransformers { _objects, err := transformer.TransformObjects(namespace, name, objects) if err != nil { - return nil, errors.Wrapf(err, "error calling object transformer (%d)", i) + return nil, legacyerrors.Wrapf(err, "error calling object transformer (%d)", i) } objects = _objects } diff --git a/pkg/reconciler/reconciler.go b/pkg/reconciler/reconciler.go index cb880b74..be56d7f9 100644 --- a/pkg/reconciler/reconciler.go +++ b/pkg/reconciler/reconciler.go @@ -14,7 +14,7 @@ import ( "time" "github.com/iancoleman/strcase" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/sap/go-generics/sets" "github.com/sap/go-generics/slices" @@ -279,7 +279,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // - check that non-unstructured types are known to the scheme, and validate/set their type information objects, err = normalizeObjects(objects, r.client.Scheme()) if err != nil { - return false, errors.Wrap(err, "error normalizing objects") + return false, legacyerrors.Wrap(err, "error normalizing objects") } // merge secret stringData into data; this is required/better because server-side-apply does not work well @@ -315,7 +315,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj if err == nil { scope = scopeFromRestMapping(restMapping) } else if !apimeta.IsNoMatchError(err) { - return false, errors.Wrapf(err, "error getting rest mapping for object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error getting rest mapping for object %s", types.ObjectKeyToString(object)) } for _, crd := range getCrds(objects) { if crd.Spec.Group == gvk.Group && crd.Spec.Names.Kind == gvk.Kind { @@ -332,7 +332,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj } } if err != nil { - return false, errors.Wrapf(err, "error getting rest mapping for object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error getting rest mapping for object %s", types.ObjectKeyToString(object)) } if object.GetNamespace() == "" && scope == scopeNamespaced { @@ -365,28 +365,28 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // validate annotations for _, object := range objects { if _, err := r.getAdoptionPolicy(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getReconcilePolicy(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getUpdatePolicy(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getDeletePolicy(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getReapplyInterval(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getApplyOrder(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getPurgeOrder(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } if _, err := r.getDeleteOrder(object); err != nil { - return false, errors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error validating object %s", types.ObjectKeyToString(object)) } // TODO: should status-hint be validated here as well? } @@ -430,15 +430,15 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj switch { case isNamespace(object): if getPurgeOrder(object) <= maxOrder { - return false, errors.Wrapf(fmt.Errorf("namespaces must not define a purge order"), "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(fmt.Errorf("namespaces must not define a purge order"), "error validating object %s", types.ObjectKeyToString(object)) } case isCrd(object): if getPurgeOrder(object) <= maxOrder { - return false, errors.Wrapf(fmt.Errorf("custom resource definitions must not define a purge order"), "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(fmt.Errorf("custom resource definitions must not define a purge order"), "error validating object %s", types.ObjectKeyToString(object)) } case isApiService(object): if getPurgeOrder(object) <= maxOrder { - return false, errors.Wrapf(fmt.Errorf("api services must not define a purge order"), "error validating object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(fmt.Errorf("api services must not define a purge order"), "error validating object %s", types.ObjectKeyToString(object)) } } } @@ -456,7 +456,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // this is in particular the case if the policy changes from or to ReconcilePolicyOnce. digest, err := calculateObjectDigest(object, componentDigest, getReconcilePolicy(object)) if err != nil { - return false, errors.Wrapf(err, "error calculating digest for object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error calculating digest for object %s", types.ObjectKeyToString(object)) } // if item was not found, append an empty item @@ -469,7 +469,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // fetch object (if existing) existingObject, err := r.readObject(ctx, object) if err != nil { - return false, errors.Wrapf(err, "error reading object %s", types.ObjectKeyToString(object)) + return false, legacyerrors.Wrapf(err, "error reading object %s", types.ObjectKeyToString(object)) } // check ownership // note: failing already here in case of a conflict prevents problems during apply and, in particular, during deletion @@ -602,10 +602,10 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj for _, namespace := range findMissingNamespaces(objects) { if err := r.client.Get(ctx, apitypes.NamespacedName{Name: namespace}, &corev1.Namespace{}); err != nil { if !apierrors.IsNotFound(err) { - return false, errors.Wrapf(err, "error reading namespace %s", namespace) + return false, legacyerrors.Wrapf(err, "error reading namespace %s", namespace) } if err := r.client.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, client.FieldOwner(r.fieldOwner)); err != nil { - return false, errors.Wrapf(err, "error creating namespace %s", namespace) + return false, legacyerrors.Wrapf(err, "error creating namespace %s", namespace) } } } @@ -624,13 +624,13 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj if item.Phase == PhaseScheduledForCompletion || item.Phase == PhaseCompleting { existingObject, err := r.readObject(ctx, item) if err != nil { - return false, errors.Wrapf(err, "error reading object %s", item) + return false, legacyerrors.Wrapf(err, "error reading object %s", item) } switch item.Phase { case PhaseScheduledForCompletion: if err := r.deleteObject(ctx, item, existingObject, hashedOwnerId); err != nil { - return false, errors.Wrapf(err, "error deleting object %s", item) + return false, legacyerrors.Wrapf(err, "error deleting object %s", item) } item.Phase = PhaseCompleting item.Status = status.TerminatingStatus @@ -719,7 +719,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // fetch object (if existing) existingObject, err := r.readObject(ctx, item) if err != nil { - return false, errors.Wrapf(err, "error reading object %s", item) + return false, legacyerrors.Wrapf(err, "error reading object %s", item) } setLabel(object, r.labelKeyOwnerId, hashedOwnerId) @@ -731,7 +731,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj now := time.Now() if existingObject == nil { if err := r.createObject(ctx, object, nil, updatePolicy); err != nil { - return false, errors.Wrapf(err, "error creating object %s", item) + return false, legacyerrors.Wrapf(err, "error creating object %s", item) } item.Phase = PhaseCreating item.Status = status.InProgressStatus @@ -743,12 +743,12 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj switch updatePolicy { case UpdatePolicyRecreate: if err := r.deleteObject(ctx, object, existingObject, hashedOwnerId); err != nil { - return false, errors.Wrapf(err, "error deleting (while recreating) object %s", item) + return false, legacyerrors.Wrapf(err, "error deleting (while recreating) object %s", item) } default: // TODO: perform an additional owner id check if err := r.updateObject(ctx, object, existingObject, nil, updatePolicy); err != nil { - return false, errors.Wrapf(err, "error updating object %s", item) + return false, legacyerrors.Wrapf(err, "error updating object %s", item) } } item.Phase = PhaseUpdating @@ -758,7 +758,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj } else { existingStatus, err := r.statusAnalyzer.ComputeStatus(existingObject) if err != nil { - return false, errors.Wrapf(err, "error checking status of object %s", item) + return false, legacyerrors.Wrapf(err, "error checking status of object %s", item) } if existingObject.GetDeletionTimestamp().IsZero() && existingStatus == status.CurrentStatus { item.Phase = PhaseReady @@ -837,7 +837,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // fetch object (if existing) existingObject, err := r.readObject(ctx, item) if err != nil { - return false, errors.Wrapf(err, "error reading object %s", item) + return false, legacyerrors.Wrapf(err, "error reading object %s", item) } switch item.Phase { @@ -861,7 +861,7 @@ func (r *Reconciler) Apply(ctx context.Context, inventory *[]*InventoryItem, obj // note: here is a theoretical risk that we delete an existing foreign object, because informers are not yet synced // however not sending the delete request is also not an option, because this might lead to orphaned own dependents if err := r.deleteObject(ctx, item, existingObject, hashedOwnerId); err != nil { - return false, errors.Wrapf(err, "error deleting object %s", item) + return false, legacyerrors.Wrapf(err, "error deleting object %s", item) } item.Phase = PhaseDeleting item.Status = status.TerminatingStatus @@ -952,7 +952,7 @@ func (r *Reconciler) Delete(ctx context.Context, inventory *[]*InventoryItem, ow // fetch object (if existing) existingObject, err := r.readObject(ctx, item) if err != nil { - return false, errors.Wrapf(err, "error reading object %s", item) + return false, legacyerrors.Wrapf(err, "error reading object %s", item) } switch item.Phase { @@ -987,7 +987,7 @@ func (r *Reconciler) Delete(ctx context.Context, inventory *[]*InventoryItem, ow // note: here is a theoretical risk that we delete an existing (foreign) object, because informers are not yet synced // however not sending the delete request is also not an option, because this might lead to orphaned own dependents if err := r.deleteObject(ctx, item, existingObject, hashedOwnerId); err != nil { - return false, errors.Wrapf(err, "error deleting object %s", item) + return false, legacyerrors.Wrapf(err, "error deleting object %s", item) } item.Phase = PhaseDeleting item.Status = status.TerminatingStatus @@ -1023,7 +1023,7 @@ func (r *Reconciler) IsDeletionAllowed(ctx context.Context, inventory *[]*Invent gk := schema.GroupKind(t) used, err := r.isTypeUsed(ctx, gk, hashedOwnerId, true) if err != nil { - return false, "", errors.Wrapf(err, "error checking usage of type %s", gk) + return false, "", legacyerrors.Wrapf(err, "error checking usage of type %s", gk) } if used { return false, fmt.Sprintf("type %s is still in use (instances exist)", gk), nil @@ -1044,12 +1044,12 @@ func (r *Reconciler) IsDeletionAllowed(ctx context.Context, inventory *[]*Invent if apierrors.IsNotFound(err) { continue } else { - return false, "", errors.Wrapf(err, "error retrieving crd %s", item.GetName()) + return false, "", legacyerrors.Wrapf(err, "error retrieving crd %s", item.GetName()) } } used, err := r.isCrdUsed(ctx, crd, hashedOwnerId, true) if err != nil { - return false, "", errors.Wrapf(err, "error checking usage of crd %s", item.GetName()) + return false, "", legacyerrors.Wrapf(err, "error checking usage of crd %s", item.GetName()) } if used { return false, fmt.Sprintf("crd %s is still in use (instances exist)", item.GetName()), nil @@ -1060,12 +1060,12 @@ func (r *Reconciler) IsDeletionAllowed(ctx context.Context, inventory *[]*Invent if apierrors.IsNotFound(err) { continue } else { - return false, "", errors.Wrapf(err, "error retrieving api service %s", item.GetName()) + return false, "", legacyerrors.Wrapf(err, "error retrieving api service %s", item.GetName()) } } used, err := r.isApiServiceUsed(ctx, apiService, hashedOwnerId, true) if err != nil { - return false, "", errors.Wrapf(err, "error checking usage of api service %s", item.GetName()) + return false, "", legacyerrors.Wrapf(err, "error checking usage of api service %s", item.GetName()) } if used { // TODO: other than with CRDs it is not clear for which types there are instances existing @@ -1392,7 +1392,7 @@ func (r *Reconciler) getReapplyInterval(object client.Object) (time.Duration, er } reapplyInterval, err := time.ParseDuration(value) if err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyReapplyInterval, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyReapplyInterval, value) } return reapplyInterval, nil } @@ -1404,10 +1404,10 @@ func (r *Reconciler) getApplyOrder(object client.Object) (int, error) { } applyOrder, err := strconv.Atoi(value) if err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyApplyOrder, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyApplyOrder, value) } if err := checkRange(applyOrder, minOrder, maxOrder); err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyApplyOrder, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyApplyOrder, value) } return applyOrder, nil } @@ -1419,10 +1419,10 @@ func (r *Reconciler) getPurgeOrder(object client.Object) (int, error) { } purgeOrder, err := strconv.Atoi(value) if err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyPurgeOrder, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyPurgeOrder, value) } if err := checkRange(purgeOrder, minOrder, maxOrder); err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyPurgeOrder, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyPurgeOrder, value) } return purgeOrder, nil } @@ -1434,10 +1434,10 @@ func (r *Reconciler) getDeleteOrder(object client.Object) (int, error) { } deleteOrder, err := strconv.Atoi(value) if err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyDeleteOrder, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyDeleteOrder, value) } if err := checkRange(deleteOrder, minOrder, maxOrder); err != nil { - return 0, errors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyDeleteOrder, value) + return 0, legacyerrors.Wrapf(err, "invalid value for annotation %s: %s", r.annotationKeyDeleteOrder, value) } return deleteOrder, nil } diff --git a/pkg/reconciler/ssa.go b/pkg/reconciler/ssa.go index 7007d561..e36f4ac9 100644 --- a/pkg/reconciler/ssa.go +++ b/pkg/reconciler/ssa.go @@ -10,7 +10,7 @@ import ( "fmt" "strings" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "github.com/sap/go-generics/slices" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -53,7 +53,7 @@ func replaceFieldManager(managedFields []metav1.ManagedFieldsEntry, managerPrefi } mergedFields, err := mergeManagedFieldsV1(managerEntry.FieldsV1, entry.FieldsV1) if err != nil { - return nil, false, errors.Wrap(err, "unable to merge managed fields") + return nil, false, legacyerrors.Wrap(err, "unable to merge managed fields") } managerEntry.FieldsV1 = mergedFields changed = true diff --git a/pkg/reconciler/util.go b/pkg/reconciler/util.go index 08f08129..a9ae7e64 100644 --- a/pkg/reconciler/util.go +++ b/pkg/reconciler/util.go @@ -13,7 +13,7 @@ import ( "fmt" "strings" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "github.com/sap/go-generics/slices" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -74,7 +74,7 @@ func calculateObjectDigest(obj client.Object, componentDigest string, reconcileP obj.SetManagedFields(nil) raw, err := json.Marshal(obj) if err != nil { - return "", errors.Wrapf(err, "error serializing object %s", types.ObjectKeyToString(obj)) + return "", legacyerrors.Wrapf(err, "error serializing object %s", types.ObjectKeyToString(obj)) } digest := sha256hex(raw) @@ -240,15 +240,15 @@ func normalizeObjects(objects []client.Object, scheme *runtime.Scheme) ([]client if scheme.Recognizes(gvk) { typedObject, err := scheme.New(gvk) if err != nil { - return nil, errors.Wrapf(err, "error instantiating type for object %s", types.ObjectKeyToString(object)) + return nil, legacyerrors.Wrapf(err, "error instantiating type for object %s", types.ObjectKeyToString(object)) } if typedObject, ok := typedObject.(client.Object); ok { if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredObject.Object, typedObject); err != nil { - return nil, errors.Wrapf(err, "error converting object %s", types.ObjectKeyToString(object)) + return nil, legacyerrors.Wrapf(err, "error converting object %s", types.ObjectKeyToString(object)) } normalizedObjects[i] = typedObject } else { - return nil, errors.Wrapf(err, "error instantiating type for object %s", types.ObjectKeyToString(object)) + return nil, legacyerrors.Wrapf(err, "error instantiating type for object %s", types.ObjectKeyToString(object)) } } else if isCrd(object) || isApiService(object) { return nil, fmt.Errorf("scheme does not recognize type of object %s", types.ObjectKeyToString(object)) @@ -258,7 +258,7 @@ func normalizeObjects(objects []client.Object, scheme *runtime.Scheme) ([]client } else { _gvk, err := apiutil.GVKForObject(object, scheme) if err != nil { - return nil, errors.Wrapf(err, "error retrieving scheme type information for object %s", types.ObjectKeyToString(object)) + return nil, legacyerrors.Wrapf(err, "error retrieving scheme type information for object %s", types.ObjectKeyToString(object)) } object = object.DeepCopyObject().(client.Object) if gvk.Version == "" || gvk.Kind == "" { diff --git a/scaffold/templates/pkg/operator/operator.go.tpl b/scaffold/templates/pkg/operator/operator.go.tpl index 04976a9a..fd5b4d2a 100644 --- a/scaffold/templates/pkg/operator/operator.go.tpl +++ b/scaffold/templates/pkg/operator/operator.go.tpl @@ -24,7 +24,7 @@ package operator import ( "flag" - "github.com/pkg/errors" + legacyerrors "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" ctrl "sigs.k8s.io/controller-runtime" @@ -112,7 +112,7 @@ func (o *Operator) Setup(mgr ctrl.Manager) error { // Replace this by a real resource generator (e.g. HelmGenerator or KustomizeGenerator, or your own one). resourceGenerator, err := manifests.NewDummyGenerator() if err != nil { - return errors.Wrap(err, "error initializing resource generator") + return legacyerrors.Wrap(err, "error initializing resource generator") } if err := component.NewReconciler[*operator{{ .groupVersion }}.{{ .kind }}]( @@ -120,7 +120,7 @@ func (o *Operator) Setup(mgr ctrl.Manager) error { resourceGenerator, component.ReconcilerOptions{}, ).SetupWithManager(mgr); err != nil { - return errors.Wrapf(err, "unable to create controller") + return legacyerrors.Wrapf(err, "unable to create controller") } {{- if or .validatingWebhookEnabled .mutatingWebhookEnabled }}