sidero/app/caps-controller-manager/controllers/serverbinding_controller.go
Andrey Smirnov 061ee8e57d
refactor: remove pre-ServerBinding leftovers, use remote cached clients
This PR has two major changes:

* retire the code which supported seamless migration from
pre-ServerBinding era to ServerBindings: creating `ServerBinding` on the
fly from the `MetalMachine` and `Server`; as there's no migration path
from pre-ServerBinding Sidero to the new version, it's time to drop it
* instead of creating workload cluster Kubernetes client each time, use
CAPI standard class to cache the client; the problem with "leaking"
clients is that HTTP/2 clients are almost never gc'ed, so they stay in
memory keeping an open connection with keepalives going both ways, so
caching lowers the load both on the controller and the control plane
endpoint

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2022-04-12 22:35:46 +03:00

96 lines
3.1 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package controllers
import (
"context"
"github.com/go-logr/logr"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3"
metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1"
)
// ServerBindingReconciler reconciles a ServerBinding object.
type ServerBindingReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
Recorder record.EventRecorder
}
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=serverbindings,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=serverbindings/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=metalmachines,verbs=get;list;watch
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=metalmachines/status,verbs=get;list;watch
// +kubebuilder:rbac:groups=metal.sidero.dev,resources=serverclasses,verbs=get;list;watch;
// +kubebuilder:rbac:groups=metal.sidero.dev,resources=serverclasses/status,verbs=get;list;watch;
// +kubebuilder:rbac:groups=metal.sidero.dev,resources=servers,verbs=get;list;watch;
// +kubebuilder:rbac:groups=metal.sidero.dev,resources=servers/status,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
func (r *ServerBindingReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Result, err error) {
logger := r.Log.WithValues("serverbinding", req.NamespacedName)
serverBinding := &infrav1.ServerBinding{}
err = r.Get(ctx, req.NamespacedName, serverBinding)
if apierrors.IsNotFound(err) {
return ctrl.Result{}, nil
}
if err != nil {
return ctrl.Result{}, err
}
// Initialize the patch helper
patchHelper, err := patch.NewHelper(serverBinding, r.Client)
if err != nil {
return ctrl.Result{}, err
}
// Always attempt to Patch the ServerBinding object and status after each reconciliation.
defer func() {
if e := patchHelper.Patch(ctx, serverBinding); e != nil {
logger.Error(e, "failed to patch metalMachine")
if err == nil {
err = e
}
}
}()
var server metalv1.Server
err = r.Get(ctx, req.NamespacedName, &server)
if err != nil {
if apierrors.IsNotFound(err) {
serverBinding.Status.Ready = false
return ctrl.Result{}, nil
}
return ctrl.Result{}, err
}
serverBinding.Status.Ready = true
return ctrl.Result{}, nil
}
func (r *ServerBindingReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
return ctrl.NewControllerManagedBy(mgr).
WithOptions(options).
For(&infrav1.ServerBinding{}).
Complete(r)
}