Add Get method in dual writer (#85589)

* Add Get method in dual writer

* Update pkg/apiserver/rest/dualwriter_mode3.go

Co-authored-by: Dan Cech <dcech@grafana.com>

* Actually run the tests

* no need for t.Run()

* Update pkg/apiserver/rest/dualwriter_mode3.go

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update pkg/apiserver/rest/dualwriter_mode3.go

Co-authored-by: Dan Cech <dcech@grafana.com>

* Update pkg/apiserver/rest/dualwriter_test.go

Co-authored-by: Dan Cech <dcech@grafana.com>

* Log improvements

* Fix method name

---------

Co-authored-by: Dan Cech <dcech@grafana.com>
This commit is contained in:
Leonor Oliveira
2024-04-09 15:08:20 +01:00
committed by GitHub
parent 1b1450e593
commit 518d3341d5
5 changed files with 112 additions and 0 deletions

View File

@@ -32,3 +32,8 @@ func (d *DualWriterMode1) Create(ctx context.Context, obj runtime.Object, create
return legacy.Create(ctx, obj, createValidation, options)
}
// Get overrides the default behavior of the DualWriter and reads only to LegacyStorage.
func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
return d.Legacy.Get(ctx, name, options)
}

View File

@@ -80,3 +80,8 @@ func enrichObject(orig, copy runtime.Object) (runtime.Object, error) {
return copy, nil
}
// Get overrides the default behavior of the Storage and retrieves an object from LegacyStorage
func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
return d.Legacy.Get(ctx, name, &metav1.GetOptions{})
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
@@ -38,3 +39,24 @@ func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, create
}
return created, nil
}
// Get overrides the default behavior of the Storage and retrieves an object from Unified Storage
// the object is still fetched from Legacy Storage if it's not found in Unified Storage
func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
legacy, ok := d.Legacy.(rest.Getter)
if !ok {
return nil, fmt.Errorf("legacy storage rest.Getter is missing")
}
s, err := d.Storage.Get(ctx, name, &metav1.GetOptions{})
if err == nil {
return s, err
}
if !apierrors.IsNotFound(err) {
return nil, err
}
klog.Info("object not found in unified storage. Getting it from legacy", "name", name)
return legacy.Get(ctx, name, &metav1.GetOptions{})
}

View File

@@ -23,3 +23,8 @@ func NewDualWriterMode4(legacy LegacyStorage, storage Storage) *DualWriterMode4
func (d *DualWriterMode4) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
return d.Storage.Create(ctx, obj, createValidation, options)
}
// Get overrides the default behavior of the Storage and retrieves an object from Unified Storage
func (d *DualWriterMode4) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
return d.Storage.Get(ctx, name, &metav1.GetOptions{})
}

View File

@@ -0,0 +1,75 @@
package rest
import (
"context"
"testing"
"github.com/zeebo/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const kind = "dummy"
func Test_Mode1(t *testing.T) {
var ls = (LegacyStorage)(nil)
var s = (Storage)(nil)
lsSpy := NewLegacyStorageSpyClient(ls)
sSpy := NewStorageSpyClient(s)
dw := NewDualWriterMode1(lsSpy, sSpy)
_, err := dw.Get(context.Background(), kind, &metav1.GetOptions{})
assert.NoError(t, err)
// it should use the Legacy Get implementation
assert.Equal(t, 1, lsSpy.Counts("LegacyStorage.Get"))
assert.Equal(t, 0, sSpy.Counts("Storage.Get"))
}
func Test_Mode2(t *testing.T) {
var ls = (LegacyStorage)(nil)
var s = (Storage)(nil)
lsSpy := NewLegacyStorageSpyClient(ls)
sSpy := NewStorageSpyClient(s)
dw := NewDualWriterMode2(lsSpy, sSpy)
_, err := dw.Get(context.Background(), kind, &metav1.GetOptions{})
assert.NoError(t, err)
// it should use the Legacy Get implementation
assert.Equal(t, 1, lsSpy.Counts("LegacyStorage.Get"))
assert.Equal(t, 0, sSpy.Counts("Storage.Get"))
}
func Mode3_Test(t *testing.T) {
var ls = (LegacyStorage)(nil)
var s = (Storage)(nil)
lsSpy := NewLegacyStorageSpyClient(ls)
sSpy := NewStorageSpyClient(s)
dw := NewDualWriterMode3(lsSpy, sSpy)
_, err := dw.Get(context.Background(), kind, &metav1.GetOptions{})
assert.NoError(t, err)
// it should use the Unified Storage Get implementation
assert.Equal(t, 0, lsSpy.Counts("LegacyStorage.Get"))
assert.Equal(t, 1, sSpy.Counts("Storage.Get"))
}
func Test_Mode4(t *testing.T) {
var ls = (LegacyStorage)(nil)
var s = (Storage)(nil)
lsSpy := NewLegacyStorageSpyClient(ls)
sSpy := NewStorageSpyClient(s)
dw := NewDualWriterMode3(lsSpy, sSpy)
_, err := dw.Get(context.Background(), kind, &metav1.GetOptions{})
assert.NoError(t, err)
// it should use the Unified Storage Get implementation
assert.Equal(t, 0, lsSpy.Counts("LegacyStorage.Get"))
assert.Equal(t, 1, sSpy.Counts("Storage.Get"))
}