[Dual writer] Read kind value passed as dualwriter's argument (#91113)

* Include kind on the dualwriter to be used on metrics

* Use kind as argument

* Skip dual writer in mode4
This commit is contained in:
Leonor Oliveira
2024-07-29 13:57:44 +02:00
committed by GitHub
parent 604c99f137
commit 8345af928c
10 changed files with 116 additions and 197 deletions
+6 -6
View File
@@ -102,7 +102,7 @@ const (
// TODO: make this function private as there should only be one public way of setting the dual writing mode // TODO: make this function private as there should only be one public way of setting the dual writing mode
// NewDualWriter returns a new DualWriter. // NewDualWriter returns a new DualWriter.
func NewDualWriter(mode DualWriterMode, legacy LegacyStorage, storage Storage, reg prometheus.Registerer) DualWriter { func NewDualWriter(mode DualWriterMode, legacy LegacyStorage, storage Storage, reg prometheus.Registerer, kind string) DualWriter {
metrics := &dualWriterMetrics{} metrics := &dualWriterMetrics{}
metrics.init(reg) metrics.init(reg)
switch mode { switch mode {
@@ -110,18 +110,18 @@ func NewDualWriter(mode DualWriterMode, legacy LegacyStorage, storage Storage, r
// writing to legacy storage without `unifiedStorage` enabled. // writing to legacy storage without `unifiedStorage` enabled.
case Mode1: case Mode1:
// read and write only from legacy storage // read and write only from legacy storage
return newDualWriterMode1(legacy, storage, metrics) return newDualWriterMode1(legacy, storage, metrics, kind)
case Mode2: case Mode2:
// write to both, read from storage but use legacy as backup // write to both, read from storage but use legacy as backup
return newDualWriterMode2(legacy, storage, metrics) return newDualWriterMode2(legacy, storage, metrics, kind)
case Mode3: case Mode3:
// write to both, read from storage only // write to both, read from storage only
return newDualWriterMode3(legacy, storage, metrics) return newDualWriterMode3(legacy, storage, metrics, kind)
case Mode4: case Mode4:
// read and write only from storage // read and write only from storage
return newDualWriterMode4(legacy, storage, metrics) return newDualWriterMode4(legacy, storage, metrics, kind)
default: default:
return newDualWriterMode1(legacy, storage, metrics) return newDualWriterMode1(legacy, storage, metrics, kind)
} }
} }
+20 -41
View File
@@ -18,15 +18,16 @@ type DualWriterMode1 struct {
Legacy LegacyStorage Legacy LegacyStorage
Storage Storage Storage Storage
*dualWriterMetrics *dualWriterMetrics
Log klog.Logger kind string
Log klog.Logger
} }
const mode1Str = "1" const mode1Str = "1"
// NewDualWriterMode1 returns a new DualWriter in mode 1. // NewDualWriterMode1 returns a new DualWriter in mode 1.
// Mode 1 represents writing to and reading from LegacyStorage. // Mode 1 represents writing to and reading from LegacyStorage.
func newDualWriterMode1(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics) *DualWriterMode1 { func newDualWriterMode1(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, kind string) *DualWriterMode1 {
return &DualWriterMode1{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode1").WithValues("mode", mode1Str), dualWriterMetrics: dwm} return &DualWriterMode1{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode1").WithValues("mode", mode1Str, "kind", kind), dualWriterMetrics: dwm}
} }
// Mode returns the mode of the dual writer. // Mode returns the mode of the dual writer.
@@ -37,18 +38,17 @@ func (d *DualWriterMode1) Mode() DualWriterMode {
// Create overrides the behavior of the generic DualWriter and writes only to LegacyStorage. // Create overrides the behavior of the generic DualWriter and writes only to LegacyStorage.
func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
var method = "create" var method = "create"
var kind = original.GetObjectKind().GroupVersionKind().Kind log := d.Log.WithValues("method", method)
log := d.Log.WithValues("method", method, "kind", kind)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startLegacy := time.Now() startLegacy := time.Now()
created, err := d.Legacy.Create(ctx, original, createValidation, options) created, err := d.Legacy.Create(ctx, original, createValidation, options)
if err != nil { if err != nil {
log.Error(err, "unable to create object in legacy storage") log.Error(err, "unable to create object in legacy storage")
d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, d.kind, method, startLegacy)
return created, err return created, err
} }
d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode1Str, d.kind, method, startLegacy)
createdCopy := created.DeepCopyObject() createdCopy := created.DeepCopyObject()
@@ -62,7 +62,7 @@ func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, c
startStorage := time.Now() startStorage := time.Now()
storageObj, errObjectSt := d.Storage.Create(ctx, createdCopy, createValidation, options) storageObj, errObjectSt := d.Storage.Create(ctx, createdCopy, createValidation, options)
d.recordStorageDuration(errObjectSt != nil, mode1Str, kind, method, startStorage) d.recordStorageDuration(errObjectSt != nil, mode1Str, d.kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@@ -87,19 +87,14 @@ func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1.
if errLegacy != nil { if errLegacy != nil {
log.Error(errLegacy, "unable to get object in legacy storage") log.Error(errLegacy, "unable to get object in legacy storage")
} }
var kind string d.recordLegacyDuration(errLegacy != nil, mode1Str, d.kind, method, startLegacy)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordLegacyDuration(errLegacy != nil, mode1Str, kind, method, startLegacy)
go func(res runtime.Object) { go func(res runtime.Object) {
startStorage := time.Now() startStorage := time.Now()
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage get timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage get timeout"))
defer cancel() defer cancel()
storageObj, err := d.Storage.Get(ctx, name, options) storageObj, err := d.Storage.Get(ctx, name, options)
d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, d.kind, method, startStorage)
if err != nil { if err != nil {
log.Error(err, "unable to get object in storage") log.Error(err, "unable to get object in storage")
cancel() cancel()
@@ -126,18 +121,14 @@ func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion
if errLegacy != nil { if errLegacy != nil {
log.Error(errLegacy, "unable to list object in legacy storage") log.Error(errLegacy, "unable to list object in legacy storage")
} }
var kind string d.recordLegacyDuration(errLegacy != nil, mode1Str, d.kind, method, startLegacy)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordLegacyDuration(errLegacy != nil, mode1Str, kind, method, startLegacy)
go func(res runtime.Object) { go func(res runtime.Object) {
startStorage := time.Now() startStorage := time.Now()
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage list timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage list timeout"))
defer cancel() defer cancel()
storageObj, err := d.Storage.List(ctx, options) storageObj, err := d.Storage.List(ctx, options)
d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, d.kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@@ -158,13 +149,9 @@ func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidat
startLegacy := time.Now() startLegacy := time.Now()
res, async, err := d.Legacy.Delete(ctx, name, deleteValidation, options) res, async, err := d.Legacy.Delete(ctx, name, deleteValidation, options)
var kind string
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to delete object in legacy storage") log.Error(err, "unable to delete object in legacy storage")
d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, d.kind, method, startLegacy)
return res, async, err return res, async, err
} }
d.recordLegacyDuration(false, mode1Str, name, method, startLegacy) d.recordLegacyDuration(false, mode1Str, name, method, startLegacy)
@@ -174,7 +161,7 @@ func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidat
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage delete timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage delete timeout"))
defer cancel() defer cancel()
storageObj, _, err := d.Storage.Delete(ctx, name, deleteValidation, options) storageObj, _, err := d.Storage.Delete(ctx, name, deleteValidation, options)
d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, d.kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@@ -194,25 +181,21 @@ func (d *DualWriterMode1) DeleteCollection(ctx context.Context, deleteValidation
log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method) log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startLegacy := time.Now() startLegacy := time.Now()
res, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) res, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to delete collection in legacy storage") log.Error(err, "unable to delete collection in legacy storage")
d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, d.kind, method, startLegacy)
return res, err return res, err
} }
d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode1Str, d.kind, method, startLegacy)
go func(res runtime.Object) { go func(res runtime.Object) {
startStorage := time.Now() startStorage := time.Now()
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage deletecollection timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage deletecollection timeout"))
defer cancel() defer cancel()
storageObj, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions) storageObj, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions)
d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, d.kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@@ -230,19 +213,15 @@ func (d *DualWriterMode1) Update(ctx context.Context, name string, objInfo rest.
var method = "update" var method = "update"
log := d.Log.WithValues("name", name, "method", method, "name", name) log := d.Log.WithValues("name", name, "method", method, "name", name)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startLegacy := time.Now() startLegacy := time.Now()
res, async, err := d.Legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) res, async, err := d.Legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to update in legacy storage") log.Error(err, "unable to update in legacy storage")
d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, d.kind, method, startLegacy)
return res, async, err return res, async, err
} }
d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode1Str, d.kind, method, startLegacy)
go func(res runtime.Object) { go func(res runtime.Object) {
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage update timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage update timeout"))
@@ -278,7 +257,7 @@ func (d *DualWriterMode1) Update(ctx context.Context, name string, objInfo rest.
startStorage := time.Now() startStorage := time.Now()
defer cancel() defer cancel()
storageObj, _, errObjectSt := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) storageObj, _, errObjectSt := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
d.recordStorageDuration(errObjectSt != nil, mode1Str, kind, method, startStorage) d.recordStorageDuration(errObjectSt != nil, mode1Str, d.kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
+7 -6
View File
@@ -25,6 +25,7 @@ var exampleList = &example.PodList{TypeMeta: metav1.TypeMeta{Kind: "foo"}, ListM
var anotherList = &example.PodList{Items: []example.Pod{*anotherObj}} var anotherList = &example.PodList{Items: []example.Pod{*anotherObj}}
var p = prometheus.NewRegistry() var p = prometheus.NewRegistry()
var kind = "foo"
func TestMode1_Create(t *testing.T) { func TestMode1_Create(t *testing.T) {
type testCase struct { type testCase struct {
@@ -72,7 +73,7 @@ func TestMode1_Create(t *testing.T) {
tt.setupStorageFn(m) tt.setupStorageFn(m)
} }
dw := NewDualWriter(Mode1, ls, us, p) dw := NewDualWriter(Mode1, ls, us, p, kind)
obj, err := dw.Create(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.CreateOptions{}) obj, err := dw.Create(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.CreateOptions{})
@@ -135,7 +136,7 @@ func TestMode1_Get(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode1, ls, us, p) dw := NewDualWriter(Mode1, ls, us, p, kind)
obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{}) obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{})
@@ -186,7 +187,7 @@ func TestMode1_List(t *testing.T) {
tt.setupStorageFn(m) tt.setupStorageFn(m)
} }
dw := NewDualWriter(Mode1, ls, us, p) dw := NewDualWriter(Mode1, ls, us, p, kind)
_, err := dw.List(context.Background(), &metainternalversion.ListOptions{}) _, err := dw.List(context.Background(), &metainternalversion.ListOptions{})
@@ -241,7 +242,7 @@ func TestMode1_Delete(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode1, ls, us, p) dw := NewDualWriter(Mode1, ls, us, p, kind)
obj, _, err := dw.Delete(context.Background(), tt.input, func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{}) obj, _, err := dw.Delete(context.Background(), tt.input, func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{})
@@ -300,7 +301,7 @@ func TestMode1_DeleteCollection(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode1, ls, us, p) dw := NewDualWriter(Mode1, ls, us, p, kind)
obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, tt.input, &metainternalversion.ListOptions{}) obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, tt.input, &metainternalversion.ListOptions{})
@@ -376,7 +377,7 @@ func TestMode1_Update(t *testing.T) {
tt.setupGetFn(m, tt.input) tt.setupGetFn(m, tt.input)
} }
dw := NewDualWriter(Mode1, ls, us, p) dw := NewDualWriter(Mode1, ls, us, p, kind)
obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{}) obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{})
+27 -51
View File
@@ -21,15 +21,16 @@ type DualWriterMode2 struct {
Storage Storage Storage Storage
Legacy LegacyStorage Legacy LegacyStorage
*dualWriterMetrics *dualWriterMetrics
Log klog.Logger kind string
Log klog.Logger
} }
const mode2Str = "2" const mode2Str = "2"
// NewDualWriterMode2 returns a new DualWriter in mode 2. // NewDualWriterMode2 returns a new DualWriter in mode 2.
// Mode 2 represents writing to LegacyStorage and Storage and reading from LegacyStorage. // Mode 2 represents writing to LegacyStorage and Storage and reading from LegacyStorage.
func newDualWriterMode2(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics) *DualWriterMode2 { func newDualWriterMode2(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, kind string) *DualWriterMode2 {
return &DualWriterMode2{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode2").WithValues("mode", mode2Str), dualWriterMetrics: dwm} return &DualWriterMode2{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode2").WithValues("mode", mode2Str, "kind", kind), dualWriterMetrics: dwm}
} }
// Mode returns the mode of the dual writer. // Mode returns the mode of the dual writer.
@@ -40,18 +41,17 @@ func (d *DualWriterMode2) Mode() DualWriterMode {
// Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage. // Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage.
func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
var method = "create" var method = "create"
var kind = original.GetObjectKind().GroupVersionKind().Kind log := d.Log.WithValues("method", method)
log := d.Log.WithValues("method", method, "kind", kind)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startLegacy := time.Now() startLegacy := time.Now()
created, err := d.Legacy.Create(ctx, original, createValidation, options) created, err := d.Legacy.Create(ctx, original, createValidation, options)
if err != nil { if err != nil {
log.Error(err, "unable to create object in legacy storage") log.Error(err, "unable to create object in legacy storage")
d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, d.kind, method, startLegacy)
return created, err return created, err
} }
d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, d.kind, method, startLegacy)
if err := enrichLegacyObject(original, created); err != nil { if err := enrichLegacyObject(original, created); err != nil {
return created, err return created, err
@@ -61,10 +61,10 @@ func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, c
rsp, err := d.Storage.Create(ctx, created, createValidation, options) rsp, err := d.Storage.Create(ctx, created, createValidation, options)
if err != nil { if err != nil {
log.WithValues("name").Error(err, "unable to create object in storage") log.WithValues("name").Error(err, "unable to create object in storage")
d.recordStorageDuration(true, mode2Str, kind, method, startStorage) d.recordStorageDuration(true, mode2Str, d.kind, method, startStorage)
return rsp, err return rsp, err
} }
d.recordStorageDuration(false, mode2Str, kind, method, startStorage) d.recordStorageDuration(false, mode2Str, d.kind, method, startStorage)
areEqual := Compare(rsp, created) areEqual := Compare(rsp, created)
d.recordOutcome(mode2Str, getName(rsp), areEqual, method) d.recordOutcome(mode2Str, getName(rsp), areEqual, method)
@@ -82,12 +82,7 @@ func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.
startStorage := time.Now() startStorage := time.Now()
objStorage, err := d.Storage.Get(ctx, name, options) objStorage, err := d.Storage.Get(ctx, name, options)
var kind string d.recordStorageDuration(err != nil, mode2Str, d.kind, method, startStorage)
if objStorage != nil {
kind = objStorage.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode2Str, kind, method, startStorage)
if err != nil { if err != nil {
// if it errors because it's not found, we try to fetch it from the legacy storage // if it errors because it's not found, we try to fetch it from the legacy storage
if !apierrors.IsNotFound(err) { if !apierrors.IsNotFound(err) {
@@ -101,10 +96,10 @@ func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.
objLegacy, err := d.Legacy.Get(ctx, name, options) objLegacy, err := d.Legacy.Get(ctx, name, options)
if err != nil { if err != nil {
log.Error(err, "unable to fetch object from legacy") log.Error(err, "unable to fetch object from legacy")
d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, d.kind, method, startLegacy)
return objLegacy, err return objLegacy, err
} }
d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, d.kind, method, startLegacy)
areEqual := Compare(objStorage, objLegacy) areEqual := Compare(objStorage, objLegacy)
d.recordOutcome(mode2Str, name, areEqual, method) d.recordOutcome(mode2Str, name, areEqual, method)
@@ -128,16 +123,12 @@ func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion
startLegacy := time.Now() startLegacy := time.Now()
ll, err := d.Legacy.List(ctx, options) ll, err := d.Legacy.List(ctx, options)
var kind string
if ll != nil {
kind = ll.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to list objects from legacy storage") log.Error(err, "unable to list objects from legacy storage")
d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, d.kind, method, startLegacy)
return ll, err return ll, err
} }
d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, d.kind, method, startLegacy)
legacyList, err := meta.ExtractList(ll) legacyList, err := meta.ExtractList(ll)
if err != nil { if err != nil {
@@ -160,10 +151,10 @@ func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion
sl, err := d.Storage.List(ctx, &optionsStorage) sl, err := d.Storage.List(ctx, &optionsStorage)
if err != nil { if err != nil {
log.Error(err, "unable to list objects from storage") log.Error(err, "unable to list objects from storage")
d.recordStorageDuration(true, mode2Str, kind, method, startStorage) d.recordStorageDuration(true, mode2Str, d.kind, method, startStorage)
return sl, err return sl, err
} }
d.recordStorageDuration(false, mode2Str, kind, method, startStorage) d.recordStorageDuration(false, mode2Str, d.kind, method, startStorage)
storageList, err := meta.ExtractList(sl) storageList, err := meta.ExtractList(sl)
if err != nil { if err != nil {
@@ -205,18 +196,14 @@ func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation
log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method) log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startLegacy := time.Now() startLegacy := time.Now()
deleted, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) deleted, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions)
if deleted != nil {
kind = deleted.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.WithValues("deleted", deleted).Error(err, "failed to delete collection successfully from legacy storage") log.WithValues("deleted", deleted).Error(err, "failed to delete collection successfully from legacy storage")
d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, d.kind, method, startLegacy)
return deleted, err return deleted, err
} }
d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, d.kind, method, startLegacy)
legacyList, err := meta.ExtractList(deleted) legacyList, err := meta.ExtractList(deleted)
if err != nil { if err != nil {
@@ -237,10 +224,10 @@ func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation
res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, &optionsStorage) res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, &optionsStorage)
if err != nil { if err != nil {
log.WithValues("deleted", res).Error(err, "failed to delete collection successfully from Storage") log.WithValues("deleted", res).Error(err, "failed to delete collection successfully from Storage")
d.recordStorageDuration(true, mode2Str, kind, method, startStorage) d.recordStorageDuration(true, mode2Str, d.kind, method, startStorage)
return res, err return res, err
} }
d.recordStorageDuration(false, mode2Str, kind, method, startStorage) d.recordStorageDuration(false, mode2Str, d.kind, method, startStorage)
areEqual := Compare(res, deleted) areEqual := Compare(res, deleted)
d.recordOutcome(mode2Str, getName(res), areEqual, method) d.recordOutcome(mode2Str, getName(res), areEqual, method)
@@ -255,33 +242,29 @@ func (d *DualWriterMode2) Delete(ctx context.Context, name string, deleteValidat
var method = "delete" var method = "delete"
log := d.Log.WithValues("name", name, "method", method) log := d.Log.WithValues("name", name, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startLegacy := time.Now() startLegacy := time.Now()
deletedLS, async, err := d.Legacy.Delete(ctx, name, deleteValidation, options) deletedLS, async, err := d.Legacy.Delete(ctx, name, deleteValidation, options)
if deletedLS != nil {
kind = deletedLS.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
if !apierrors.IsNotFound(err) { if !apierrors.IsNotFound(err) {
log.WithValues("objectList", deletedLS).Error(err, "could not delete from legacy store") log.WithValues("objectList", deletedLS).Error(err, "could not delete from legacy store")
d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, d.kind, method, startLegacy)
return deletedLS, async, err return deletedLS, async, err
} }
} }
d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, d.kind, method, startLegacy)
startStorage := time.Now() startStorage := time.Now()
deletedS, _, err := d.Storage.Delete(ctx, name, deleteValidation, options) deletedS, _, err := d.Storage.Delete(ctx, name, deleteValidation, options)
if err != nil { if err != nil {
if !apierrors.IsNotFound(err) { if !apierrors.IsNotFound(err) {
log.WithValues("objectList", deletedS).Error(err, "could not delete from duplicate storage") log.WithValues("objectList", deletedS).Error(err, "could not delete from duplicate storage")
d.recordStorageDuration(true, mode2Str, kind, method, startStorage) d.recordStorageDuration(true, mode2Str, d.kind, method, startStorage)
} }
return deletedS, async, err return deletedS, async, err
} }
d.recordStorageDuration(false, mode2Str, kind, method, startStorage) d.recordStorageDuration(false, mode2Str, d.kind, method, startStorage)
areEqual := Compare(deletedS, deletedLS) areEqual := Compare(deletedS, deletedLS)
d.recordOutcome(mode2Str, name, areEqual, method) d.recordOutcome(mode2Str, name, areEqual, method)
@@ -297,13 +280,9 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest.
var method = "update" var method = "update"
log := d.Log.WithValues("name", name, "method", method) log := d.Log.WithValues("name", name, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
// get foundObj and (updated) object so they can be stored in legacy store // get foundObj and (updated) object so they can be stored in legacy store
foundObj, err := d.Storage.Get(ctx, name, &metav1.GetOptions{}) foundObj, err := d.Storage.Get(ctx, name, &metav1.GetOptions{})
if foundObj != nil {
kind = foundObj.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
if !apierrors.IsNotFound(err) { if !apierrors.IsNotFound(err) {
log.WithValues("object", foundObj).Error(err, "could not get object to update") log.WithValues("object", foundObj).Error(err, "could not get object to update")
@@ -314,9 +293,6 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest.
// obj can be populated in case it's found or empty in case it's not found // obj can be populated in case it's found or empty in case it's not found
updated, err := objInfo.UpdatedObject(ctx, foundObj) updated, err := objInfo.UpdatedObject(ctx, foundObj)
if updated != nil {
kind = updated.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.WithValues("object", updated).Error(err, "could not update or create object") log.WithValues("object", updated).Error(err, "could not update or create object")
return nil, false, err return nil, false, err
@@ -326,10 +302,10 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest.
obj, created, err := d.Legacy.Update(ctx, name, &updateWrapper{upstream: objInfo, updated: updated}, createValidation, updateValidation, forceAllowCreate, options) obj, created, err := d.Legacy.Update(ctx, name, &updateWrapper{upstream: objInfo, updated: updated}, createValidation, updateValidation, forceAllowCreate, options)
if err != nil { if err != nil {
log.WithValues("object", obj).Error(err, "could not update in legacy storage") log.WithValues("object", obj).Error(err, "could not update in legacy storage")
d.recordLegacyDuration(true, mode2Str, kind, "update", startLegacy) d.recordLegacyDuration(true, mode2Str, d.kind, "update", startLegacy)
return obj, created, err return obj, created, err
} }
d.recordLegacyDuration(false, mode2Str, kind, "update", startLegacy) d.recordLegacyDuration(false, mode2Str, d.kind, "update", startLegacy)
// if the object is found, create a new updateWrapper with the object found // if the object is found, create a new updateWrapper with the object found
if foundObj != nil { if foundObj != nil {
@@ -348,7 +324,7 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest.
res, created, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) res, created, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
if err != nil { if err != nil {
log.WithValues("object", res).Error(err, "could not update in storage") log.WithValues("object", res).Error(err, "could not update in storage")
d.recordStorageDuration(true, mode2Str, kind, "update", startStorage) d.recordStorageDuration(true, mode2Str, d.kind, "update", startStorage)
return res, created, err return res, created, err
} }
+6 -6
View File
@@ -67,7 +67,7 @@ func TestMode2_Create(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode2, ls, us, p) dw := NewDualWriter(Mode2, ls, us, p, kind)
obj, err := dw.Create(context.Background(), tt.input, createFn, &metav1.CreateOptions{}) obj, err := dw.Create(context.Background(), tt.input, createFn, &metav1.CreateOptions{})
@@ -143,7 +143,7 @@ func TestMode2_Get(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode2, ls, us, p) dw := NewDualWriter(Mode2, ls, us, p, kind)
obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{}) obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{})
@@ -196,7 +196,7 @@ func TestMode2_List(t *testing.T) {
tt.setupStorageFn(m) tt.setupStorageFn(m)
} }
dw := NewDualWriter(Mode2, ls, us, p) dw := NewDualWriter(Mode2, ls, us, p, kind)
obj, err := dw.List(context.Background(), &metainternalversion.ListOptions{}) obj, err := dw.List(context.Background(), &metainternalversion.ListOptions{})
@@ -289,7 +289,7 @@ func TestMode2_Delete(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode2, ls, us, p) dw := NewDualWriter(Mode2, ls, us, p, kind)
obj, _, err := dw.Delete(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.DeleteOptions{}) obj, _, err := dw.Delete(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.DeleteOptions{})
@@ -361,7 +361,7 @@ func TestMode2_DeleteCollection(t *testing.T) {
tt.setupStorageFn(m) tt.setupStorageFn(m)
} }
dw := NewDualWriter(Mode2, ls, us, p) dw := NewDualWriter(Mode2, ls, us, p, kind)
obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{TypeMeta: metav1.TypeMeta{Kind: tt.input}}, &metainternalversion.ListOptions{}) obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{TypeMeta: metav1.TypeMeta{Kind: tt.input}}, &metainternalversion.ListOptions{})
@@ -469,7 +469,7 @@ func TestMode2_Update(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode2, ls, us, p) dw := NewDualWriter(Mode2, ls, us, p, kind)
obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{}) obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{})
+19 -40
View File
@@ -16,13 +16,14 @@ type DualWriterMode3 struct {
Legacy LegacyStorage Legacy LegacyStorage
Storage Storage Storage Storage
*dualWriterMetrics *dualWriterMetrics
Log klog.Logger kind string
Log klog.Logger
} }
// newDualWriterMode3 returns a new DualWriter in mode 3. // newDualWriterMode3 returns a new DualWriter in mode 3.
// Mode 3 represents writing to LegacyStorage and Storage and reading from Storage. // Mode 3 represents writing to LegacyStorage and Storage and reading from Storage.
func newDualWriterMode3(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics) *DualWriterMode3 { func newDualWriterMode3(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, kind string) *DualWriterMode3 {
return &DualWriterMode3{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode3").WithValues("mode", mode3Str), dualWriterMetrics: dwm} return &DualWriterMode3{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode3").WithValues("mode", mode3Str, "kind", kind), dualWriterMetrics: dwm}
} }
// Mode returns the mode of the dual writer. // Mode returns the mode of the dual writer.
@@ -35,18 +36,17 @@ const mode3Str = "3"
// Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage. // Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage.
func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
var method = "create" var method = "create"
var kind = obj.GetObjectKind().GroupVersionKind().Kind log := d.Log.WithValues("method", method)
log := d.Log.WithValues("kind", kind, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now() startStorage := time.Now()
created, err := d.Storage.Create(ctx, obj, createValidation, options) created, err := d.Storage.Create(ctx, obj, createValidation, options)
if err != nil { if err != nil {
log.Error(err, "unable to create object in storage") log.Error(err, "unable to create object in storage")
d.recordLegacyDuration(true, mode3Str, kind, method, startStorage) d.recordLegacyDuration(true, mode3Str, d.kind, method, startStorage)
return created, err return created, err
} }
d.recordStorageDuration(false, mode3Str, kind, method, startStorage) d.recordStorageDuration(false, mode3Str, d.kind, method, startStorage)
go func() { go func() {
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy create timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy create timeout"))
@@ -54,7 +54,7 @@ func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, create
startLegacy := time.Now() startLegacy := time.Now()
_, errObjectSt := d.Legacy.Create(ctx, obj, createValidation, options) _, errObjectSt := d.Legacy.Create(ctx, obj, createValidation, options)
d.recordLegacyDuration(errObjectSt != nil, mode3Str, kind, method, startLegacy) d.recordLegacyDuration(errObjectSt != nil, mode3Str, d.kind, method, startLegacy)
}() }()
return created, err return created, err
@@ -71,12 +71,7 @@ func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1.
if err != nil { if err != nil {
log.Error(err, "unable to get object in storage") log.Error(err, "unable to get object in storage")
} }
d.recordStorageDuration(err != nil, mode3Str, d.kind, method, startStorage)
var kind string
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode3Str, kind, method, startStorage)
return res, err return res, err
} }
@@ -92,11 +87,7 @@ func (d *DualWriterMode3) List(ctx context.Context, options *metainternalversion
if err != nil { if err != nil {
log.Error(err, "unable to list object in storage") log.Error(err, "unable to list object in storage")
} }
var kind string d.recordStorageDuration(err != nil, mode3Str, d.kind, method, startStorage)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode3Str, kind, method, startStorage)
return res, err return res, err
} }
@@ -106,15 +97,11 @@ func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidat
log := d.Log.WithValues("name", name, "method", method) log := d.Log.WithValues("name", name, "method", method)
ctx = klog.NewContext(ctx, d.Log) ctx = klog.NewContext(ctx, d.Log)
var kind string
startStorage := time.Now() startStorage := time.Now()
res, async, err := d.Storage.Delete(ctx, name, deleteValidation, options) res, async, err := d.Storage.Delete(ctx, name, deleteValidation, options)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to delete object in storage") log.Error(err, "unable to delete object in storage")
d.recordStorageDuration(true, mode3Str, kind, method, startStorage) d.recordStorageDuration(true, mode3Str, d.kind, method, startStorage)
return res, async, err return res, async, err
} }
d.recordStorageDuration(false, mode3Str, name, method, startStorage) d.recordStorageDuration(false, mode3Str, name, method, startStorage)
@@ -124,7 +111,7 @@ func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidat
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy delete timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy delete timeout"))
defer cancel() defer cancel()
_, _, err := d.Legacy.Delete(ctx, name, deleteValidation, options) _, _, err := d.Legacy.Delete(ctx, name, deleteValidation, options)
d.recordLegacyDuration(err != nil, mode3Str, kind, method, startLegacy) d.recordLegacyDuration(err != nil, mode3Str, d.kind, method, startLegacy)
}() }()
return res, async, err return res, async, err
@@ -135,19 +122,15 @@ func (d *DualWriterMode3) Update(ctx context.Context, name string, objInfo rest.
var method = "update" var method = "update"
log := d.Log.WithValues("name", name, "method", method) log := d.Log.WithValues("name", name, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startStorage := time.Now() startStorage := time.Now()
res, async, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) res, async, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to update in storage") log.Error(err, "unable to update in storage")
d.recordLegacyDuration(true, mode3Str, kind, method, startStorage) d.recordLegacyDuration(true, mode3Str, d.kind, method, startStorage)
return res, async, err return res, async, err
} }
d.recordStorageDuration(false, mode3Str, kind, method, startStorage) d.recordStorageDuration(false, mode3Str, d.kind, method, startStorage)
go func() { go func() {
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy update timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy update timeout"))
@@ -155,7 +138,7 @@ func (d *DualWriterMode3) Update(ctx context.Context, name string, objInfo rest.
startLegacy := time.Now() startLegacy := time.Now()
defer cancel() defer cancel()
_, _, errObjectSt := d.Legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) _, _, errObjectSt := d.Legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
d.recordLegacyDuration(errObjectSt != nil, mode3Str, kind, method, startLegacy) d.recordLegacyDuration(errObjectSt != nil, mode3Str, d.kind, method, startLegacy)
}() }()
return res, async, err return res, async, err
@@ -166,26 +149,22 @@ func (d *DualWriterMode3) DeleteCollection(ctx context.Context, deleteValidation
var method = "delete-collection" var method = "delete-collection"
log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method) log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startStorage := time.Now() startStorage := time.Now()
res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions) res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
if err != nil { if err != nil {
log.Error(err, "unable to delete collection in storage") log.Error(err, "unable to delete collection in storage")
d.recordStorageDuration(true, mode3Str, kind, method, startStorage) d.recordStorageDuration(true, mode3Str, d.kind, method, startStorage)
return res, err return res, err
} }
d.recordStorageDuration(false, mode3Str, kind, method, startStorage) d.recordStorageDuration(false, mode3Str, d.kind, method, startStorage)
go func() { go func() {
startLegacy := time.Now() startLegacy := time.Now()
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy deletecollection timeout")) ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy deletecollection timeout"))
defer cancel() defer cancel()
_, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) _, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions)
d.recordStorageDuration(err != nil, mode3Str, kind, method, startLegacy) d.recordStorageDuration(err != nil, mode3Str, d.kind, method, startLegacy)
}() }()
return res, err return res, err
@@ -194,7 +173,7 @@ func (d *DualWriterMode3) DeleteCollection(ctx context.Context, deleteValidation
//TODO: uncomment when storage watch is implemented //TODO: uncomment when storage watch is implemented
// func (d *DualWriterMode3) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { // func (d *DualWriterMode3) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) {
// var method = "watch" // var method = "watch"
// d.Log.WithValues("kind", options.Kind, "method", method, "mode", mode3Str).Info("starting to watch") // d.Log.WithValues("kind", d.kind, "method", method, "mode", mode3Str).Info("starting to watch")
// return d.Storage.Watch(ctx, options) // return d.Storage.Watch(ctx, options)
// } // }
+6 -6
View File
@@ -60,7 +60,7 @@ func TestMode3_Create(t *testing.T) {
tt.setupStorageFn(m) tt.setupStorageFn(m)
} }
dw := NewDualWriter(Mode3, ls, us, p) dw := NewDualWriter(Mode3, ls, us, p, kind)
obj, err := dw.Create(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.CreateOptions{}) obj, err := dw.Create(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.CreateOptions{})
@@ -117,7 +117,7 @@ func TestMode3_Get(t *testing.T) {
} }
p := prometheus.NewRegistry() p := prometheus.NewRegistry()
dw := NewDualWriter(Mode3, ls, us, p) dw := NewDualWriter(Mode3, ls, us, p, kind)
obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{}) obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{})
@@ -171,7 +171,7 @@ func TestMode3_List(t *testing.T) {
tt.setupStorageFn(m, tt.options) tt.setupStorageFn(m, tt.options)
} }
dw := NewDualWriter(Mode3, ls, us, p) dw := NewDualWriter(Mode3, ls, us, p, kind)
res, err := dw.List(context.Background(), tt.options) res, err := dw.List(context.Background(), tt.options)
@@ -225,7 +225,7 @@ func TestMode3_Delete(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode3, ls, us, p) dw := NewDualWriter(Mode3, ls, us, p, kind)
obj, _, err := dw.Delete(context.Background(), tt.input, func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{}) obj, _, err := dw.Delete(context.Background(), tt.input, func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{})
@@ -279,7 +279,7 @@ func TestMode3_DeleteCollection(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode3, ls, us, p) dw := NewDualWriter(Mode3, ls, us, p, kind)
obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, tt.input, &metainternalversion.ListOptions{}) obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, tt.input, &metainternalversion.ListOptions{})
@@ -340,7 +340,7 @@ func TestMode3_Update(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode3, ls, us, p) dw := NewDualWriter(Mode3, ls, us, p, kind)
obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{}) obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{})
+13 -33
View File
@@ -15,15 +15,16 @@ type DualWriterMode4 struct {
Legacy LegacyStorage Legacy LegacyStorage
Storage Storage Storage Storage
*dualWriterMetrics *dualWriterMetrics
Log klog.Logger kind string
Log klog.Logger
} }
const mode4Str = "4" const mode4Str = "4"
// newDualWriterMode4 returns a new DualWriter in mode 4. // newDualWriterMode4 returns a new DualWriter in mode 4.
// Mode 4 represents writing and reading from Storage. // Mode 4 represents writing and reading from Storage.
func newDualWriterMode4(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics) *DualWriterMode4 { func newDualWriterMode4(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, kind string) *DualWriterMode4 {
return &DualWriterMode4{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode4").WithValues("mode", mode4Str), dualWriterMetrics: dwm} return &DualWriterMode4{Legacy: legacy, Storage: storage, Log: klog.NewKlogr().WithName("DualWriterMode4").WithValues("mode", mode4Str, "kind", kind), dualWriterMetrics: dwm}
} }
// Mode returns the mode of the dual writer. // Mode returns the mode of the dual writer.
@@ -36,8 +37,7 @@ func (d *DualWriterMode4) Mode() DualWriterMode {
// Create overrides the behavior of the generic DualWriter and writes only to Storage. // Create overrides the behavior of the generic DualWriter and writes only to Storage.
func (d *DualWriterMode4) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { func (d *DualWriterMode4) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
var method = "create" var method = "create"
var kind = obj.GetObjectKind().GroupVersionKind().Kind log := d.Log.WithValues("method", method)
log := d.Log.WithValues("method", method, "kind", kind)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now() startStorage := time.Now()
@@ -45,7 +45,7 @@ func (d *DualWriterMode4) Create(ctx context.Context, obj runtime.Object, create
if err != nil { if err != nil {
log.Error(err, "unable to create object in storage") log.Error(err, "unable to create object in storage")
} }
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) d.recordStorageDuration(err != nil, mode4Str, d.kind, method, startStorage)
return res, err return res, err
} }
@@ -60,11 +60,7 @@ func (d *DualWriterMode4) Get(ctx context.Context, name string, options *metav1.
if err != nil { if err != nil {
log.Error(err, "unable to create object in storage") log.Error(err, "unable to create object in storage")
} }
var kind string d.recordStorageDuration(err != nil, mode4Str, d.kind, method, startStorage)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, err return res, err
} }
@@ -73,16 +69,12 @@ func (d *DualWriterMode4) Delete(ctx context.Context, name string, deleteValidat
log := d.Log.WithValues("name", name, "method", method) log := d.Log.WithValues("name", name, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startStorage := time.Now() startStorage := time.Now()
res, async, err := d.Storage.Delete(ctx, name, deleteValidation, options) res, async, err := d.Storage.Delete(ctx, name, deleteValidation, options)
if err != nil { if err != nil {
log.Error(err, "unable to delete object in storage") log.Error(err, "unable to delete object in storage")
} }
if res != nil { d.recordStorageDuration(err != nil, mode4Str, d.kind, method, startStorage)
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, async, err return res, async, err
} }
@@ -91,36 +83,28 @@ func (d *DualWriterMode4) DeleteCollection(ctx context.Context, deleteValidation
var method = "delete-collection" var method = "delete-collection"
log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method, "mode", mode4Str) log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method, "mode", mode4Str)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startStorage := time.Now() startStorage := time.Now()
res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions) res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions)
if err != nil { if err != nil {
log.Error(err, "unable to delete collection in storage") log.Error(err, "unable to delete collection in storage")
} }
if res != nil { d.recordStorageDuration(err != nil, mode4Str, d.kind, method, startStorage)
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, err return res, err
} }
// Update overrides the generic behavior of the Storage and writes only to US. // Update overrides the generic behavior of the Storage and writes only to US.
func (d *DualWriterMode4) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { func (d *DualWriterMode4) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
var method = "update" var method = "update"
log := d.Log.WithValues("name", name, "method", method) log := d.Log.WithValues("name", name, "kind", d.kind, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
var kind string
startStorage := time.Now() startStorage := time.Now()
res, async, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) res, async, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
if err != nil { if err != nil {
log.Error(err, "unable to update object in storage") log.Error(err, "unable to update object in storage")
} }
if res != nil { d.recordStorageDuration(err != nil, mode4Str, d.kind, method, startStorage)
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, async, err return res, async, err
} }
@@ -134,18 +118,14 @@ func (d *DualWriterMode4) List(ctx context.Context, options *metainternalversion
if err != nil { if err != nil {
log.Error(err, "unable to list objects in storage") log.Error(err, "unable to list objects in storage")
} }
var kind string d.recordStorageDuration(err != nil, mode4Str, d.kind, method, startStorage)
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, err return res, err
} }
//TODO: uncomment when storage watch is implemented //TODO: uncomment when storage watch is implemented
// func (d *DualWriterMode4) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { // func (d *DualWriterMode4) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) {
// var method = "watch" // var method = "watch"
// d.Log.WithValues("kind", kind, "method", method, "mode", mode4Str).Info("starting to watch") // d.Log.WithValues("kind", d.kind, "method", method, "mode", mode4Str).Info("starting to watch")
// return d.Storage.Watch(ctx, options) // return d.Storage.Watch(ctx, options)
// } // }
+6 -6
View File
@@ -53,7 +53,7 @@ func TestMode4_Create(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode4, ls, us, p) dw := NewDualWriter(Mode4, ls, us, p, kind)
obj, err := dw.Create(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.CreateOptions{}) obj, err := dw.Create(context.Background(), tt.input, func(context.Context, runtime.Object) error { return nil }, &metav1.CreateOptions{})
@@ -110,7 +110,7 @@ func TestMode4_Get(t *testing.T) {
} }
p := prometheus.NewRegistry() p := prometheus.NewRegistry()
dw := NewDualWriter(Mode4, ls, us, p) dw := NewDualWriter(Mode4, ls, us, p, kind)
obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{}) obj, err := dw.Get(context.Background(), tt.input, &metav1.GetOptions{})
@@ -166,7 +166,7 @@ func TestMode4_List(t *testing.T) {
tt.setupStorageFn(m, tt.options) tt.setupStorageFn(m, tt.options)
} }
dw := NewDualWriter(Mode4, ls, us, p) dw := NewDualWriter(Mode4, ls, us, p, kind)
res, err := dw.List(context.Background(), tt.options) res, err := dw.List(context.Background(), tt.options)
@@ -220,7 +220,7 @@ func TestMode4_Delete(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode4, ls, us, p) dw := NewDualWriter(Mode4, ls, us, p, kind)
obj, _, err := dw.Delete(context.Background(), tt.input, func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{}) obj, _, err := dw.Delete(context.Background(), tt.input, func(ctx context.Context, obj runtime.Object) error { return nil }, &metav1.DeleteOptions{})
@@ -275,7 +275,7 @@ func TestMode4_DeleteCollection(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode4, ls, us, p) dw := NewDualWriter(Mode4, ls, us, p, kind)
obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, tt.input, &metainternalversion.ListOptions{}) obj, err := dw.DeleteCollection(context.Background(), func(ctx context.Context, obj runtime.Object) error { return nil }, tt.input, &metainternalversion.ListOptions{})
@@ -330,7 +330,7 @@ func TestMode4_Update(t *testing.T) {
tt.setupStorageFn(m, tt.input) tt.setupStorageFn(m, tt.input)
} }
dw := NewDualWriter(Mode4, ls, us, p) dw := NewDualWriter(Mode4, ls, us, p, kind)
obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{}) obj, _, err := dw.Update(context.Background(), tt.input, updatedObjInfoObj{}, func(ctx context.Context, obj runtime.Object) error { return nil }, func(ctx context.Context, obj, old runtime.Object) error { return nil }, false, &metav1.UpdateOptions{})
+6 -2
View File
@@ -174,10 +174,14 @@ func InstallAPIs(
if err != nil { if err != nil {
return nil, err return nil, err
} }
if currentMode == grafanarest.Mode0 { switch currentMode {
case grafanarest.Mode0:
return legacy, nil return legacy, nil
case grafanarest.Mode4:
return storage, nil
default:
} }
return grafanarest.NewDualWriter(currentMode, legacy, storage, reg), nil return grafanarest.NewDualWriter(currentMode, legacy, storage, reg, key), nil
} }
} }