Files
netbird-kubernetes-operator/internal/controller/group_controller.go
T
Philip LaineandGitHub 0c542db9d7 Fix group reconcile removing peers (#226)
This changes the group reconcile to get the existing group first and
then update it in place. If not done like this peers will be removed
from the group on the next reconcile.

Fixes #221
2026-05-05 11:12:50 +02:00

113 lines
3.1 KiB
Go

package controller
import (
"context"
"time"
"github.com/fluxcd/pkg/runtime/conditions"
"github.com/fluxcd/pkg/runtime/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
"github.com/netbirdio/netbird/shared/management/http/api"
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
"github.com/netbirdio/kubernetes-operator/internal/k8sutil"
)
type GroupReconciler struct {
client.Client
Netbird *netbird.Client
}
// +kubebuilder:rbac:groups=netbird.io,resources=groups,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=netbird.io,resources=groups/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=netbird.io,resources=groups/finalizers,verbs=update
func (r *GroupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
group := &nbv1alpha1.Group{}
err := r.Get(ctx, req.NamespacedName, group)
if err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
sp := patch.NewSerialPatcher(group, r.Client)
if !group.DeletionTimestamp.IsZero() {
return r.reconcileDelete(ctx, sp, group)
}
controllerutil.AddFinalizer(group, k8sutil.Finalizer("group"))
err = sp.Patch(ctx, group)
if err != nil {
return ctrl.Result{}, err
}
groupID, err := func() (string, error) {
if group.Status.GroupID != "" {
groupResp, err := r.Netbird.Groups.Get(ctx, group.Status.GroupID)
if err == nil {
peers := []string{}
for _, peer := range groupResp.Peers {
peers = append(peers, peer.Id)
}
groupReq := api.GroupRequest{
Name: group.Spec.Name,
Peers: &peers,
Resources: &groupResp.Resources,
}
resp, err := r.Netbird.Groups.Update(ctx, group.Status.GroupID, groupReq)
if err != nil && !netbird.IsNotFound(err) {
return "", err
}
if err == nil {
return resp.Id, nil
}
}
}
groupReq := api.GroupRequest{
Name: group.Spec.Name,
}
resp, err := r.Netbird.Groups.Create(ctx, groupReq)
if err != nil {
return "", err
}
return resp.Id, nil
}()
if err != nil {
return ctrl.Result{}, err
}
group.Status.GroupID = groupID
conditions.MarkTrue(group, nbv1alpha1.ReadyCondition, nbv1alpha1.ReconciledReason, "")
err = sp.Patch(ctx, group, patch.WithStatusObservedGeneration{})
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{RequeueAfter: 15 * time.Minute}, nil
}
func (r *GroupReconciler) reconcileDelete(ctx context.Context, sp *patch.SerialPatcher, group *nbv1alpha1.Group) (ctrl.Result, error) {
if group.Status.GroupID != "" {
err := r.Netbird.Groups.Delete(ctx, group.Status.GroupID)
if err != nil && !netbird.IsNotFound(err) {
return ctrl.Result{}, err
}
}
controllerutil.RemoveFinalizer(group, k8sutil.Finalizer("group"))
err := sp.Patch(ctx, group)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
func (r *GroupReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&nbv1alpha1.Group{}).
Complete(r)
}