Skip to content

Implement RemoteNodeSet controllers #179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c19e804
impl remoteNodeSet api objects
kobzonega Jan 23, 2024
18e5378
remoteSpec to define region and zone
kobzonega Jan 23, 2024
7e8b3b2
processing remoteNodeSet objects in storage/database controllers
kobzonega Jan 23, 2024
3c27d7a
append remoteNodeSet builders in storage/database resources
kobzonega Jan 24, 2024
a29603f
fix resourceBuilders for remote resources
kobzonega Jan 26, 2024
030edf2
fix nested if
kobzonega Feb 6, 2024
f402f0e
update rbac for remoteNodeSet objects
kobzonega Feb 6, 2024
c907552
fixes tests
kobzonega Feb 6, 2024
c70ba20
use only cluster field for remote
kobzonega Feb 8, 2024
41f7938
impl remote controllers
kobzonega Feb 8, 2024
534ba72
Merge branch 'master' into YDBOPS-9039
kobzonega Feb 8, 2024
97f2096
add remoteFinalizer to wait resource deletion
kobzonega Feb 9, 2024
2f49d90
fixes tests
kobzonega Feb 6, 2024
98b294f
fix go.mod
kobzonega Feb 8, 2024
1d85876
fix e2e tests check running and ready pods (#177)
kobzonega Feb 6, 2024
0a82ea2
remove useless constants
kobzonega Feb 9, 2024
d4fd3f2
use apiutil to recognize resource Kind
kobzonega Feb 12, 2024
ed19e24
update crds and generated deepcopy
kobzonega Feb 12, 2024
b770066
fixes tests
kobzonega Feb 6, 2024
fcfe3af
get resource kind by gvk apiutil
kobzonega Feb 12, 2024
10ed733
ut tests for deletion
kobzonega Feb 12, 2024
a9c9fbc
fix golangci lint errors
kobzonega Feb 12, 2024
3855260
fix ut tests
kobzonega Feb 12, 2024
e5b3c3f
update unit-tests
kobzonega Feb 13, 2024
fb28a33
using cluster cache instead of manager
kobzonega Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add remoteFinalizer to wait resource deletion
  • Loading branch information
kobzonega committed Feb 9, 2024
commit 97f2096c6b038015fd5a286029f7b5a47a2efd2b
1 change: 1 addition & 0 deletions cmd/ydb-kubernetes-operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func main() {
}
}

//nolint:nestif
if remoteKubeconfig != "" && remoteCluster != "" {
remoteConfig, err := clientcmd.BuildConfigFromFlags("", remoteKubeconfig)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/controllers/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,7 @@ const (
PrimaryResourceNamespaceAnnotation = "ydb.tech/primary-resource-namespace"
PrimaryResourceTypeAnnotation = "ydb.tech/primary-resource-type"

RemoteFinalizerKey = "ydb.tech/remote-finalizer"

OwnerControllerKey = ".metadata.controller"
)
1 change: 0 additions & 1 deletion internal/controllers/remotedatabasenodeset/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ func (r *Reconciler) updateStatus(
Name: remoteDatabaseNodeSet.Name,
Namespace: remoteDatabaseNodeSet.Namespace,
}, &databaseNodeSet)

if err != nil {
if errors.IsNotFound(err) {
r.RemoteRecorder.Event(
Expand Down
69 changes: 53 additions & 16 deletions internal/controllers/remotestoragenodeset/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"

"github.com/go-logr/logr"
apierrs "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/selection"
Expand All @@ -13,6 +13,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/cluster"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
Expand Down Expand Up @@ -43,14 +44,48 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
logger := log.FromContext(ctx)

remoteStorageNodeSet := &api.RemoteStorageNodeSet{}

// we'll ignore not-found errors, since they can't be fixed by an immediate
// requeue (we'll need to wait for a new notification), and we can get them
// on deleted requests.
if err := r.RemoteClient.Get(ctx, req.NamespacedName, remoteStorageNodeSet); err != nil {
if apierrs.IsNotFound(err) {
logger.Info("RemoteStorageNodeSet has been deleted")
return r.handleRemoteResourceDeleted(ctx, req)
if apierrors.IsNotFound(err) {
logger.Info("StorageNodeSet has been deleted")
return ctrl.Result{Requeue: false}, nil
}
logger.Error(err, "unable to get RemoteStorageNodeSet")
return ctrl.Result{}, err
return ctrl.Result{RequeueAfter: DefaultRequeueDelay}, nil
}

// examine DeletionTimestamp to determine if object is under deletion
if remoteStorageNodeSet.ObjectMeta.DeletionTimestamp.IsZero() {
// The object is not being deleted, so if it does not have our finalizer,
// then lets add the finalizer and update the object. This is equivalent
// to registering our finalizer.
if !controllerutil.ContainsFinalizer(remoteStorageNodeSet, RemoteFinalizerKey) {
controllerutil.AddFinalizer(remoteStorageNodeSet, RemoteFinalizerKey)
if err := r.RemoteClient.Update(ctx, remoteStorageNodeSet); err != nil {
return ctrl.Result{RequeueAfter: DefaultRequeueDelay}, err
}
}
} else {
// The object is being deleted
if controllerutil.ContainsFinalizer(remoteStorageNodeSet, RemoteFinalizerKey) {
// our finalizer is present, so lets handle any external dependency
if err := r.deleteExternalResources(ctx, remoteStorageNodeSet); err != nil {
// if fail to delete the external dependency here, return with error
// so that it can be retried.
return ctrl.Result{RequeueAfter: DefaultRequeueDelay}, err
}

// remove our finalizer from the list and update it.
controllerutil.RemoveFinalizer(remoteStorageNodeSet, RemoteFinalizerKey)
if err := r.RemoteClient.Update(ctx, remoteStorageNodeSet); err != nil {
return ctrl.Result{RequeueAfter: DefaultRequeueDelay}, err
}
}

// Stop reconciliation as the item is being deleted
return ctrl.Result{Requeue: false}, nil
}

result, err := r.Sync(ctx, remoteStorageNodeSet)
Expand All @@ -61,26 +96,28 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
return result, err
}

func (r *Reconciler) handleRemoteResourceDeleted(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *Reconciler) deleteExternalResources(ctx context.Context, remoteStorageNodeSet *api.RemoteStorageNodeSet) error {
logger := log.FromContext(ctx)

storageNodeSet := &api.StorageNodeSet{}

if err := r.Client.Get(ctx, req.NamespacedName, storageNodeSet); err != nil {
if apierrs.IsNotFound(err) {
logger.Info("StorageNodeSet has been deleted")
return ctrl.Result{Requeue: false}, nil
if err := r.Client.Get(ctx, types.NamespacedName{
Name: remoteStorageNodeSet.Name,
Namespace: remoteStorageNodeSet.Namespace,
}, storageNodeSet); err != nil {
if apierrors.IsNotFound(err) {
logger.Info("StorageNodeSet not found")
return nil
}
logger.Error(err, "unable to get StorageNodeSet")
return ctrl.Result{}, err
return err
}

if err := r.Client.Delete(ctx, storageNodeSet); err != nil {
logger.Error(err, "unable to delete StorageNodeSet")
return ctrl.Result{}, err
return err
}

return ctrl.Result{Requeue: false}, nil
return nil
}

// SetupWithManager sets up the controller with the Manager.
Expand Down Expand Up @@ -108,7 +145,7 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, remoteCluster *cluster.C
}

return ctrl.NewControllerManagedBy(mgr).
Named("RemoteStorageNodeSet").
Named("remotestoragenodeset").
Watches(source.NewKindWithCache(&api.RemoteStorageNodeSet{}, cluster.GetCache()), &handler.EnqueueRequestForObject{}).
Watches(&source.Kind{Type: &api.StorageNodeSet{}}, handler.EnqueueRequestsFromMapFunc(annotationFilter)).
Complete(r)
Expand Down
7 changes: 3 additions & 4 deletions internal/controllers/remotestoragenodeset/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ func (r *Reconciler) Sync(ctx context.Context, crRemoteStorageNodeSet *ydbv1alph
var result ctrl.Result
var err error

RemoteStorageNodeSet := resources.NewRemoteStorageNodeSet(crRemoteStorageNodeSet)
stop, result, err = r.handleResourcesSync(ctx, &RemoteStorageNodeSet)
remoteStorageNodeSet := resources.NewRemoteStorageNodeSet(crRemoteStorageNodeSet)
stop, result, err = r.handleResourcesSync(ctx, &remoteStorageNodeSet)
if stop {
return result, err
}

stop, result, err = r.updateStatus(ctx, &RemoteStorageNodeSet)
stop, result, err = r.updateStatus(ctx, &remoteStorageNodeSet)
if stop {
return result, err
}
Expand Down Expand Up @@ -106,7 +106,6 @@ func (r *Reconciler) updateStatus(
Name: remoteStorageNodeSet.Name,
Namespace: remoteStorageNodeSet.Namespace,
}, &storageNodeSet)

if err != nil {
if errors.IsNotFound(err) {
r.RemoteRecorder.Event(
Expand Down
4 changes: 2 additions & 2 deletions internal/controllers/storagenodeset/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/go-logr/logr"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/record"
Expand Down Expand Up @@ -47,7 +47,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
crStorageNodeSet := &api.StorageNodeSet{}
err := r.Get(ctx, req.NamespacedName, crStorageNodeSet)
if err != nil {
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
logger.Info("StorageNodeSet has been deleted")
return ctrl.Result{Requeue: false}, nil
}
Expand Down