Skip to content

Commit

Permalink
fix warden delete sync bug (#329)
Browse files Browse the repository at this point in the history
* fix warden delete sync bug
  • Loading branch information
tiancandevloper committed Aug 14, 2023
1 parent e2db829 commit 0ce7e55
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 29 deletions.
19 changes: 19 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# v1.8.6

## BugFix
- fix warden delete sync bug [#329](https://github.com/kubecube-io/KubeCube/pull/329)

## Dependencies

- hnc v1.0
- nginx-ingress v0.46.0
- helm 3.5
- metrics-server v0.4.1
- elasticsearch 7.8
- kubecube-monitoring 15.4.8
- thanos 3.18.0
- logseer v1.0.0
- logagent v1.0.0
- kubecube-audit v1.2.0
- kubecube-webconsole v1.2.4

# v1.8.5

## BugFix
Expand Down
74 changes: 45 additions & 29 deletions pkg/warden/syncmgr/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"strconv"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
Expand Down Expand Up @@ -58,39 +59,62 @@ func (s *SyncManager) SetupCtrlWithManager(resource client.Object, objFunc Gener

r := reconcile.Func(func(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
var (
action = Skip
err error
obj = resource
action = Skip
err error
pivotObj = resource
localObj = resource
)

// record sync log
defer func() {
clog.Info("sync: %s %v, name: %v, namespace: %v, err: %v", action, obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName(), obj.GetNamespace(), err)
clog.Info("sync: %s %v, name: %v, namespace: %v, err: %v", action, pivotObj.GetObjectKind().GroupVersionKind().Kind, pivotObj.GetName(), pivotObj.GetNamespace(), err)
}()

getLocalObj := func() error {

localObj, err = objFunc(pivotObj)
if err != nil {
return err
}

trimObjMeta(pivotObj)

err = localClient.Get(ctx, req.NamespacedName, localObj)
return err
}

// delete
deleteObjFunc := func() (reconcile.Result, error) {
gvk, err := apiutil.GVKForObject(obj, s.Manager.GetScheme())
err = getLocalObj()
if err != nil {
if errors.IsNotFound(err) {
return ctrl.Result{}, nil
}
return reconcile.Result{}, err
}
var gvk schema.GroupVersionKind
gvk, err = apiutil.GVKForObject(localObj, s.Manager.GetScheme())
if err != nil {
return ctrl.Result{}, err
}
groupKind := gvk.GroupKind()
if groupKind.Group == tenantv1.GroupVersion.Group {
if groupKind.Kind == "Tenant" || groupKind.Kind == "Project" {
err = s.updateSpecialObjForDelete(obj, objFunc, ctx, req)
err = s.updateSpecialObjForDelete(localObj, objFunc, ctx, req)
if err != nil {
return ctrl.Result{}, err
}
}
}
action = Delete
err = localClient.Delete(ctx, obj, &client.DeleteOptions{})
err = localClient.Delete(ctx, localObj, &client.DeleteOptions{})
if err != nil && errors.IsNotFound(err) {
return reconcile.Result{}, nil
}
return reconcile.Result{}, err
}

if err = pivotClient.Get(ctx, req.NamespacedName, obj); err != nil {
if err = pivotClient.Get(ctx, req.NamespacedName, pivotObj); err != nil {
// If the object is a tenant or project, add an annotation to inform the webhook to allow it to be deleted
// delete: when object is not exist in pivot cluster
if errors.IsNotFound(err) {
Expand All @@ -99,61 +123,53 @@ func (s *SyncManager) SetupCtrlWithManager(resource client.Object, objFunc Gener
return reconcile.Result{}, err
}

newObj, err := objFunc(obj)
if err != nil {
return reconcile.Result{}, err
}

trimObjMeta(obj)

err = localClient.Get(ctx, req.NamespacedName, newObj)
err = getLocalObj()
if err != nil {
if errors.IsNotFound(err) {
// create: when object is not exist in local cluster
action = Create
err = localClient.Create(ctx, obj, &client.CreateOptions{})
err = localClient.Create(ctx, pivotObj, &client.CreateOptions{})
if err != nil {
return reconcile.Result{Requeue: true}, err
return ctrl.Result{}, err
}
return reconcile.Result{}, nil
return ctrl.Result{}, nil
}
return reconcile.Result{}, err
return ctrl.Result{}, err
}

//If it is the same resource, the managed resource must be created first than the local resource.
//Based on this, if the management and control creation time is later than the local creation time, it is a new resource
//Warning, this relies on the local clock, which can cause problems when the clock is wrong or when the clock goes backwards

pivotCreateTimestamp := obj.GetCreationTimestamp()
localCreateTimestamp := newObj.GetCreationTimestamp()
pivotCreateTimestamp := pivotObj.GetCreationTimestamp()
localCreateTimestamp := localObj.GetCreationTimestamp()
if pivotCreateTimestamp.UnixNano() > localCreateTimestamp.UnixNano() {
result, err := deleteObjFunc()
if err != nil {
return result, err
}
action = Create
err = localClient.Create(ctx, obj, &client.CreateOptions{})
err = localClient.Create(ctx, pivotObj, &client.CreateOptions{})
if err != nil {
return reconcile.Result{Requeue: true}, err
}
return reconcile.Result{}, nil
}

pivotRsVersion, err := strconv.Atoi(obj.GetAnnotations()[pivotResourceVersion])
pivotRsVersion, err := strconv.Atoi(pivotObj.GetAnnotations()[pivotResourceVersion])
if err != nil {
return reconcile.Result{}, err
}
localRsVersion, err := strconv.Atoi(newObj.GetAnnotations()[pivotResourceVersion])
localRsVersion, err := strconv.Atoi(localObj.GetAnnotations()[pivotResourceVersion])
if err != nil {
return reconcile.Result{}, err
}

// update: when pivot resource version bigger than local resource version
if pivotRsVersion > localRsVersion {
action = Update
obj.SetResourceVersion(newObj.GetResourceVersion())
obj.SetUID(newObj.GetUID())
err = localClient.Update(ctx, obj, &client.UpdateOptions{})
pivotObj.SetResourceVersion(localObj.GetResourceVersion())
pivotObj.SetUID(localObj.GetUID())
err = localClient.Update(ctx, pivotObj, &client.UpdateOptions{})
if err != nil {
return reconcile.Result{}, err
}
Expand Down

0 comments on commit 0ce7e55

Please sign in to comment.