Get kind from runtime.Object. Unify metric names (#91041)

* Normalize name labels

* Access kind

* Read kind from the runtime object instead from the options object

* use kind from object on create
This commit is contained in:
Leonor Oliveira 2024-07-29 08:58:48 +01:00 committed by GitHub
parent a7679b5f8d
commit 6a1e835f12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 189 additions and 79 deletions

View File

@ -37,17 +37,18 @@ 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"
log := d.Log.WithValues("kind", options.Kind, "method", method) var kind = original.GetObjectKind().GroupVersionKind().Kind
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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy)
return created, err return created, err
} }
d.recordLegacyDuration(false, mode1Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy)
createdCopy := created.DeepCopyObject() createdCopy := created.DeepCopyObject()
@ -61,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, options.Kind, method, startStorage) d.recordStorageDuration(errObjectSt != nil, mode1Str, kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@ -78,7 +79,7 @@ func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, c
// Get overrides the behavior of the generic DualWriter and reads only from LegacyStorage. // Get overrides the behavior of the generic DualWriter and reads only from LegacyStorage.
func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
var method = "get" var method = "get"
log := d.Log.WithValues("kind", options.Kind, "method", method, "name", name) log := d.Log.WithValues("method", method, "name", name)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startLegacy := time.Now() startLegacy := time.Now()
@ -86,14 +87,19 @@ 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")
} }
d.recordLegacyDuration(errLegacy != nil, mode1Str, options.Kind, method, startLegacy) var kind string
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, options.Kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, 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()
@ -112,7 +118,7 @@ func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1.
// List overrides the behavior of the generic DualWriter and reads only from LegacyStorage. // List overrides the behavior of the generic DualWriter and reads only from LegacyStorage.
func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "list" var method = "list"
log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startLegacy := time.Now() startLegacy := time.Now()
@ -120,14 +126,18 @@ 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")
} }
d.recordLegacyDuration(errLegacy != nil, mode1Str, options.Kind, method, startLegacy) var kind string
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, options.Kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@ -143,14 +153,18 @@ func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion
func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
var method = "delete" var method = "delete"
log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method, "name", name) log := d.Log.WithValues("name", name, "method", method, "name", name)
ctx = klog.NewContext(ctx, d.Log) ctx = klog.NewContext(ctx, d.Log)
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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, 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)
@ -160,7 +174,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, options.Kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@ -177,24 +191,28 @@ func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidat
// DeleteCollection overrides the behavior of the generic DualWriter and deletes only from LegacyStorage. // DeleteCollection overrides the behavior of the generic DualWriter and deletes only from LegacyStorage.
func (d *DualWriterMode1) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode1) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "delete-collection" var method = "delete-collection"
log := d.Log.WithValues("kind", options.Kind, "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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy)
return res, err return res, err
} }
d.recordLegacyDuration(false, mode1Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, 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 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, options.Kind, method, startStorage) d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }
@ -210,17 +228,21 @@ func (d *DualWriterMode1) DeleteCollection(ctx context.Context, deleteValidation
func (d *DualWriterMode1) 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 *DualWriterMode1) 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, "kind", options.Kind, "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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy)
return res, async, err return res, async, err
} }
d.recordLegacyDuration(false, mode1Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode1Str, 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"))
@ -256,7 +278,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, options.Kind, method, startStorage) d.recordStorageDuration(errObjectSt != nil, mode1Str, kind, method, startStorage)
if err != nil { if err != nil {
cancel() cancel()
} }

View File

@ -40,17 +40,18 @@ 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"
log := d.Log.WithValues("kind", options.Kind, "method", method) var kind = original.GetObjectKind().GroupVersionKind().Kind
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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy)
return created, err return created, err
} }
d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy)
if err := enrichLegacyObject(original, created); err != nil { if err := enrichLegacyObject(original, created); err != nil {
return created, err return created, err
@ -60,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, options.Kind, method, startStorage) d.recordStorageDuration(true, mode2Str, kind, method, startStorage)
return rsp, err return rsp, err
} }
d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode2Str, 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)
@ -76,12 +77,17 @@ func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, c
// It retrieves an object from Storage if possible, and if not it falls back to LegacyStorage. // It retrieves an object from Storage if possible, and if not it falls back to LegacyStorage.
func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
var method = "get" var method = "get"
log := d.Log.WithValues("name", name, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) log := d.Log.WithValues("name", name, "resourceVersion", options.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now() startStorage := time.Now()
objStorage, err := d.Storage.Get(ctx, name, options) objStorage, err := d.Storage.Get(ctx, name, options)
d.recordStorageDuration(err != nil, mode2Str, options.Kind, method, startStorage) var kind string
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) {
@ -95,10 +101,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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy)
return objLegacy, err return objLegacy, err
} }
d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy)
areEqual := Compare(objStorage, objLegacy) areEqual := Compare(objStorage, objLegacy)
d.recordOutcome(mode2Str, name, areEqual, method) d.recordOutcome(mode2Str, name, areEqual, method)
@ -117,17 +123,21 @@ func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.
// It returns Storage entries if possible and falls back to LegacyStorage entries if not. // It returns Storage entries if possible and falls back to LegacyStorage entries if not.
func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "list" var method = "list"
log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy)
return ll, err return ll, err
} }
d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy)
legacyList, err := meta.ExtractList(ll) legacyList, err := meta.ExtractList(ll)
if err != nil { if err != nil {
@ -150,10 +160,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, options.Kind, method, startStorage) d.recordStorageDuration(true, mode2Str, kind, method, startStorage)
return sl, err return sl, err
} }
d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode2Str, kind, method, startStorage)
storageList, err := meta.ExtractList(sl) storageList, err := meta.ExtractList(sl)
if err != nil { if err != nil {
@ -192,17 +202,21 @@ func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion
// DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage. // DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage.
func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "delete-collection" var method = "delete-collection"
log := d.Log.WithValues("kind", options.Kind, "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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy)
return deleted, err return deleted, err
} }
d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy)
legacyList, err := meta.ExtractList(deleted) legacyList, err := meta.ExtractList(deleted)
if err != nil { if err != nil {
@ -223,10 +237,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, options.Kind, method, startStorage) d.recordStorageDuration(true, mode2Str, kind, method, startStorage)
return res, err return res, err
} }
d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode2Str, 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)
@ -239,30 +253,35 @@ func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation
func (d *DualWriterMode2) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { func (d *DualWriterMode2) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
var method = "delete" var method = "delete"
log := d.Log.WithValues("name", name, "kind", options.Kind, "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, options.Kind, method, startLegacy) d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy)
return deletedLS, async, err return deletedLS, async, err
} }
} }
d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) d.recordLegacyDuration(false, mode2Str, 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, options.Kind, method, startStorage) d.recordStorageDuration(true, mode2Str, kind, method, startStorage)
} }
return deletedS, async, err return deletedS, async, err
} }
d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode2Str, kind, method, startStorage)
areEqual := Compare(deletedS, deletedLS) areEqual := Compare(deletedS, deletedLS)
d.recordOutcome(mode2Str, name, areEqual, method) d.recordOutcome(mode2Str, name, areEqual, method)
@ -276,11 +295,15 @@ func (d *DualWriterMode2) Delete(ctx context.Context, name string, deleteValidat
// Update overrides the generic behavior of the Storage and writes first to the legacy storage and then to storage. // Update overrides the generic behavior of the Storage and writes first to the legacy storage and then to storage.
func (d *DualWriterMode2) 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 *DualWriterMode2) 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, "kind", options.Kind, "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")
@ -291,6 +314,9 @@ 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
@ -300,10 +326,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, options.Kind, "update", startLegacy) d.recordLegacyDuration(true, mode2Str, kind, "update", startLegacy)
return obj, created, err return obj, created, err
} }
d.recordLegacyDuration(false, mode2Str, options.Kind, "update", startLegacy) d.recordLegacyDuration(false, mode2Str, 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 {
@ -322,7 +348,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, options.Kind, "update", startStorage) d.recordStorageDuration(true, mode2Str, kind, "update", startStorage)
return res, created, err return res, created, err
} }

View File

@ -35,17 +35,18 @@ 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"
log := d.Log.WithValues("kind", options.Kind, "method", method) var kind = obj.GetObjectKind().GroupVersionKind().Kind
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, options.Kind, method, startStorage) d.recordLegacyDuration(true, mode3Str, kind, method, startStorage)
return created, err return created, err
} }
d.recordStorageDuration(false, mode3Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode3Str, 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"))
@ -53,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, options.Kind, method, startLegacy) d.recordLegacyDuration(errObjectSt != nil, mode3Str, kind, method, startLegacy)
}() }()
return created, err return created, err
@ -62,7 +63,7 @@ func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, create
// Get overrides the behavior of the generic DualWriter and retrieves an object from Storage. // Get overrides the behavior of the generic DualWriter and retrieves an object from Storage.
func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
var method = "get" var method = "get"
log := d.Log.WithValues("kind", options.Kind, "name", name, "method", method) log := d.Log.WithValues("name", name, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now() startStorage := time.Now()
@ -70,7 +71,12 @@ 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, options.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
} }
@ -78,7 +84,7 @@ func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1.
// List overrides the behavior of the generic DualWriter and reads only from Unified Store. // List overrides the behavior of the generic DualWriter and reads only from Unified Store.
func (d *DualWriterMode3) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode3) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "list" var method = "list"
log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "method", method) log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now() startStorage := time.Now()
@ -86,21 +92,29 @@ 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")
} }
d.recordStorageDuration(err != nil, mode3Str, options.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
} }
func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
var method = "delete" var method = "delete"
log := d.Log.WithValues("name", name, "kind", options.Kind, "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, options.Kind, method, startStorage) d.recordStorageDuration(true, mode3Str, 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)
@ -110,7 +124,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, options.Kind, method, startLegacy) d.recordLegacyDuration(err != nil, mode3Str, kind, method, startLegacy)
}() }()
return res, async, err return res, async, err
@ -119,17 +133,21 @@ func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidat
// Update overrides the behavior of the generic DualWriter and writes first to Storage and then to LegacyStorage. // Update overrides the behavior of the generic DualWriter and writes first to Storage and then to LegacyStorage.
func (d *DualWriterMode3) 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 *DualWriterMode3) 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, "kind", options.Kind, "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, options.Kind, method, startStorage) d.recordLegacyDuration(true, mode3Str, kind, method, startStorage)
return res, async, err return res, async, err
} }
d.recordStorageDuration(false, mode3Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode3Str, 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"))
@ -137,7 +155,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, options.Kind, method, startLegacy) d.recordLegacyDuration(errObjectSt != nil, mode3Str, kind, method, startLegacy)
}() }()
return res, async, err return res, async, err
@ -146,24 +164,28 @@ func (d *DualWriterMode3) Update(ctx context.Context, name string, objInfo rest.
// DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage. // DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage.
func (d *DualWriterMode3) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode3) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "delete-collection" var method = "delete-collection"
log := d.Log.WithValues("kind", options.Kind, "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, options.Kind, method, startStorage) d.recordStorageDuration(true, mode3Str, kind, method, startStorage)
return res, err return res, err
} }
d.recordStorageDuration(false, mode3Str, options.Kind, method, startStorage) d.recordStorageDuration(false, mode3Str, 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, options.Kind, method, startLegacy) d.recordStorageDuration(err != nil, mode3Str, kind, method, startLegacy)
}() }()
return res, err return res, err

View File

@ -2,6 +2,7 @@ package rest
import ( import (
"context" "context"
"time"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -35,77 +36,116 @@ 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"
log := d.Log.WithValues("kind", options.Kind, "method", method) var kind = obj.GetObjectKind().GroupVersionKind().Kind
log := d.Log.WithValues("method", method, "kind", kind)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now()
res, err := d.Storage.Create(ctx, obj, createValidation, options) res, 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.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, err return res, err
} }
// Get overrides the behavior of the generic DualWriter and retrieves an object from Storage. // Get overrides the behavior of the generic DualWriter and retrieves an object from Storage.
func (d *DualWriterMode4) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { func (d *DualWriterMode4) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
var method = "get" var method = "get"
log := d.Log.WithValues("kind", options.Kind, "method", method) log := d.Log.WithValues("method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now()
res, err := d.Storage.Get(ctx, name, options) res, err := d.Storage.Get(ctx, name, 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")
} }
var kind string
if res != nil {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, err return res, err
} }
func (d *DualWriterMode4) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { func (d *DualWriterMode4) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
var method = "delete" var method = "delete"
log := d.Log.WithValues("name", name, "kind", options.Kind, "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()
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 {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, async, err return res, async, err
} }
// DeleteCollection overrides the behavior of the generic DualWriter and deletes only from Storage. // DeleteCollection overrides the behavior of the generic DualWriter and deletes only from Storage.
func (d *DualWriterMode4) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode4) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "delete-collection" var method = "delete-collection"
log := d.Log.WithValues("kind", options.Kind, "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()
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 {
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, "kind", options.Kind, "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()
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 {
kind = res.GetObjectKind().GroupVersionKind().Kind
}
d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage)
return res, async, err return res, async, err
} }
func (d *DualWriterMode4) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { func (d *DualWriterMode4) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
var method = "list" var method = "list"
log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method)
ctx = klog.NewContext(ctx, log) ctx = klog.NewContext(ctx, log)
startStorage := time.Now()
res, err := d.Storage.List(ctx, options) res, err := d.Storage.List(ctx, options)
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
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", options.Kind, "method", method, "mode", mode4Str).Info("starting to watch") // d.Log.WithValues("kind", kind, "method", method, "mode", mode4Str).Info("starting to watch")
// return d.Storage.Watch(ctx, options) // return d.Storage.Watch(ctx, options)
// } // }

View File

@ -51,14 +51,14 @@ func (m *dualWriterMetrics) init(reg prometheus.Registerer) {
} }
} }
func (m *dualWriterMetrics) recordLegacyDuration(isError bool, mode string, name string, method string, startFrom time.Time) { func (m *dualWriterMetrics) recordLegacyDuration(isError bool, mode string, kind string, method string, startFrom time.Time) {
duration := time.Since(startFrom).Seconds() duration := time.Since(startFrom).Seconds()
m.legacy.WithLabelValues(strconv.FormatBool(isError), mode, name, method).Observe(duration) m.legacy.WithLabelValues(strconv.FormatBool(isError), mode, kind, method).Observe(duration)
} }
func (m *dualWriterMetrics) recordStorageDuration(isError bool, mode string, name string, method string, startFrom time.Time) { func (m *dualWriterMetrics) recordStorageDuration(isError bool, mode string, kind string, method string, startFrom time.Time) {
duration := time.Since(startFrom).Seconds() duration := time.Since(startFrom).Seconds()
m.storage.WithLabelValues(strconv.FormatBool(isError), mode, name, method).Observe(duration) m.storage.WithLabelValues(strconv.FormatBool(isError), mode, kind, method).Observe(duration)
} }
func (m *dualWriterMetrics) recordOutcome(mode string, name string, areEqual bool, method string) { func (m *dualWriterMetrics) recordOutcome(mode string, name string, areEqual bool, method string) {