From cac9e449baeab15bf88df7b12007de4cc49fdcd7 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Tue, 9 Dec 2025 10:46:09 +0100 Subject: [PATCH] Context propagation for InstanceManager Status and Delete - enhance the Status and Delete methods of the InstanceManager interface to require the context paramater - this is done to validate the approach and see if the handler and db related spans are then connected in one trace - the other methods of the interface will follow once that works [0] [0] this is also done because the diff of changes would become quite large if everything would be changed at once Issue-ID: MULTICLOUD-1538 Change-Id: Ia1ec590f3326773e0df1e6cefba97711975bbf48 Signed-off-by: Fiete Ostkamp --- src/k8splugin/api/brokerhandler.go | 2 +- src/k8splugin/api/instancehandler.go | 4 ++-- src/k8splugin/api/instancehandler_test.go | 11 ++++++----- src/k8splugin/go.mod | 2 +- src/k8splugin/internal/app/instance.go | 26 +++++++++++++------------- src/k8splugin/internal/app/instance_test.go | 7 ++++--- src/k8splugin/internal/app/subscription.go | 2 +- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/k8splugin/api/brokerhandler.go b/src/k8splugin/api/brokerhandler.go index ecfde8c4..e95c1c89 100644 --- a/src/k8splugin/api/brokerhandler.go +++ b/src/k8splugin/api/brokerhandler.go @@ -276,7 +276,7 @@ func (b brokerInstanceHandler) deleteHandler(w http.ResponseWriter, r *http.Requ vars := mux.Vars(r) instanceID := vars["instID"] - err := b.client.Delete(instanceID) + err := b.client.Delete(r.Context(), instanceID) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/src/k8splugin/api/instancehandler.go b/src/k8splugin/api/instancehandler.go index dd5fd0dd..4e67acf0 100644 --- a/src/k8splugin/api/instancehandler.go +++ b/src/k8splugin/api/instancehandler.go @@ -211,7 +211,7 @@ func (i instanceHandler) statusHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["instID"] - resp, err := i.client.Status(id, true) + resp, err := i.client.Status(r.Context(), id, true) if err != nil { log.Error("Error getting Status", log.Fields{ "error": err, @@ -314,7 +314,7 @@ func (i instanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["instID"] - err := i.client.Delete(id) + err := i.client.Delete(r.Context(), id) if err != nil { log.Error("Error Deleting Instance", log.Fields{ "error": err, diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go index f06af446..af867e44 100644 --- a/src/k8splugin/api/instancehandler_test.go +++ b/src/k8splugin/api/instancehandler_test.go @@ -15,6 +15,7 @@ package api import ( "bytes" + "context" "encoding/json" "io" "io/ioutil" @@ -35,9 +36,9 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -//Creating an embedded interface via anonymous variable -//This allows us to make mockDB satisfy the DatabaseConnection -//interface even if we are not implementing all the methods in it +// Creating an embedded interface via anonymous variable +// This allows us to make mockDB satisfy the DatabaseConnection +// interface even if we are not implementing all the methods in it type mockInstanceClient struct { app.InstanceManager // Items and err will be used to customize each test @@ -72,7 +73,7 @@ func (m *mockInstanceClient) Query(id, apiVersion, kind, name, labels string) (a return m.statusItem, nil } -func (m *mockInstanceClient) Status(id string, checkReady bool) (app.InstanceStatus, error) { +func (m *mockInstanceClient) Status(ctx context.Context, id string, checkReady bool) (app.InstanceStatus, error) { if m.err != nil { return app.InstanceStatus{}, m.err } @@ -96,7 +97,7 @@ func (m *mockInstanceClient) Find(rbName string, ver string, profile string, lab return m.miniitems, nil } -func (m *mockInstanceClient) Delete(id string) error { +func (m *mockInstanceClient) Delete(ctx context.Context, id string) error { return m.err } diff --git a/src/k8splugin/go.mod b/src/k8splugin/go.mod index 99ac69a2..81fc5c39 100644 --- a/src/k8splugin/go.mod +++ b/src/k8splugin/go.mod @@ -13,7 +13,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.3 go.mongodb.org/mongo-driver v1.7.5 go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.24.0 - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.24.0 go.opentelemetry.io/otel v1.2.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0 go.opentelemetry.io/otel/sdk v1.2.0 diff --git a/src/k8splugin/internal/app/instance.go b/src/k8splugin/internal/app/instance.go index 9455e23f..cd06a436 100644 --- a/src/k8splugin/internal/app/instance.go +++ b/src/k8splugin/internal/app/instance.go @@ -121,11 +121,11 @@ type InstanceManager interface { Upgrade(id string, u UpgradeRequest) (InstanceResponse, error) Get(id string) (InstanceResponse, error) GetFull(id string) (InstanceDbData, error) - Status(id string, checkReady bool) (InstanceStatus, error) + Status(ctx context.Context, id string, checkReady bool) (InstanceStatus, error) Query(id, apiVersion, kind, name, labels string) (InstanceStatus, error) List(rbname, rbversion, profilename string) ([]InstanceMiniResponse, error) Find(rbName string, ver string, profile string, labelKeys map[string]string) ([]InstanceMiniResponse, error) - Delete(id string) error + Delete(ctx context.Context, id string) error RecoverCreateOrDelete(id string) error } @@ -491,7 +491,7 @@ func (v *InstanceClient) Upgrade(id string, u UpgradeRequest) (InstanceResponse, if currentInstance.Request.CloudRegion != u.CloudRegion { newInstance, err := v.Create(i, "") if err == nil { - err = v.Delete(id) + err = v.Delete(context.TODO(), id) if err == nil { newInstanceDb, err := v.GetFull(newInstance.ID) oldKey := InstanceKey{ @@ -510,7 +510,7 @@ func (v *InstanceClient) Upgrade(id string, u UpgradeRequest) (InstanceResponse, } return newInstance, nil } else { - err2 := v.Delete(newInstance.ID) + err2 := v.Delete(context.TODO(), newInstance.ID) if err2 != nil { log.Printf("Delete of the instance from the new region failed with error %s", err2.Error()) } @@ -813,13 +813,13 @@ func (v *InstanceClient) Query(id, apiVersion, kind, name, labels string) (Insta } // Status returns the status for the instance -func (v *InstanceClient) Status(id string, checkReady bool) (InstanceStatus, error) { +func (v *InstanceClient) Status(ctx context.Context, id string, checkReady bool) (InstanceStatus, error) { //Read the status from the DB key := InstanceKey{ ID: id, } - value, err := db.DBconn.Read(context.TODO(), v.storeName, key, v.tagInst) + value, err := db.DBconn.Read(ctx, v.storeName, key, v.tagInst) if err != nil { return InstanceStatus{}, pkgerrors.Wrap(err, "Get Instance") } @@ -1071,7 +1071,7 @@ func (v *InstanceClient) Find(rbName string, version string, profile string, lab } // Delete the Instance from database -func (v *InstanceClient) Delete(id string) error { +func (v *InstanceClient) Delete(ctx context.Context, id string) error { inst, err := v.GetFull(id) if err != nil { return pkgerrors.Wrap(err, "Error getting Instance") @@ -1081,7 +1081,7 @@ func (v *InstanceClient) Delete(id string) error { } if inst.Status == "DELETED" { //The instance is deleted when the plugin comes back -> just remove from Db - err = db.DBconn.Delete(context.TODO(), v.storeName, key, v.tagInst) + err = db.DBconn.Delete(ctx, v.storeName, key, v.tagInst) if err != nil { log.Printf("Delete Instance DB Entry for release %s has error.", inst.ReleaseName) } @@ -1100,7 +1100,7 @@ func (v *InstanceClient) Delete(id string) error { inst.Status = "PRE-DELETE" inst.HookProgress = "" - err = db.DBconn.Update(context.TODO(), v.storeName, key, v.tagInst, inst) + err = db.DBconn.Update(ctx, v.storeName, key, v.tagInst, inst) if err != nil { log.Printf("Update Instance DB Entry for release %s has error.", inst.ReleaseName) } @@ -1111,7 +1111,7 @@ func (v *InstanceClient) Delete(id string) error { if err != nil { log.Printf(" Instance: %s, Error running pre-delete hooks error: %s", id, err) inst.Status = "PRE-DELETE-FAILED" - err2 := db.DBconn.Update(context.TODO(), v.storeName, key, v.tagInst, inst) + err2 := db.DBconn.Update(ctx, v.storeName, key, v.tagInst, inst) if err2 != nil { log.Printf("Update Instance DB Entry for release %s has error.", inst.ReleaseName) } @@ -1120,7 +1120,7 @@ func (v *InstanceClient) Delete(id string) error { } inst.Status = "DELETING" - err = db.DBconn.Update(context.TODO(), v.storeName, key, v.tagInst, inst) + err = db.DBconn.Update(ctx, v.storeName, key, v.tagInst, inst) if err != nil { log.Printf("Update Instance DB Entry for release %s has error.", inst.ReleaseName) } @@ -1149,7 +1149,7 @@ func (v *InstanceClient) Delete(id string) error { log.Printf(err.Error()) } - err = db.DBconn.Delete(context.TODO(), v.storeName, key, v.tagInst) + err = db.DBconn.Delete(ctx, v.storeName, key, v.tagInst) if err != nil { return pkgerrors.Wrap(err, "Delete Instance") } @@ -1158,7 +1158,7 @@ func (v *InstanceClient) Delete(id string) error { return nil } -//Continue the instantiation +// Continue the instantiation func (v *InstanceClient) RecoverCreateOrDelete(id string) error { instance, err := v.GetFull(id) if err != nil { diff --git a/src/k8splugin/internal/app/instance_test.go b/src/k8splugin/internal/app/instance_test.go index 86955fa3..611c31e9 100644 --- a/src/k8splugin/internal/app/instance_test.go +++ b/src/k8splugin/internal/app/instance_test.go @@ -15,6 +15,7 @@ limitations under the License. package app import ( + "context" "encoding/base64" "io/ioutil" "log" @@ -747,7 +748,7 @@ func TestInstanceDelete(t *testing.T) { ic := NewInstanceClient() id := "HaKpys8e" - err := ic.Delete(id) + err := ic.Delete(context.TODO(), id) if err != nil { t.Fatalf("TestInstanceDelete returned an error (%s)", err) } @@ -790,14 +791,14 @@ func TestInstanceDelete(t *testing.T) { ic := NewInstanceClient() id := "non-existing" - err := ic.Delete(id) + err := ic.Delete(context.TODO(), id) if err == nil { t.Fatal("Expected error, got pass", err) } }) } -//TODO: add a test when pre-hook is failed (if possible) +// TODO: add a test when pre-hook is failed (if possible) func TestInstanceWithHookCreate(t *testing.T) { err := LoadMockPlugins(utils.LoadedPlugins) if err != nil { diff --git a/src/k8splugin/internal/app/subscription.go b/src/k8splugin/internal/app/subscription.go index ff2cec4d..e353ca82 100644 --- a/src/k8splugin/internal/app/subscription.go +++ b/src/k8splugin/internal/app/subscription.go @@ -652,7 +652,7 @@ func runNotifyThread(instanceId, subName string) { } else { timeInSeconds = 5 } - newStatus, err := v.Status(instanceId, false) + newStatus, err := v.Status(context.Background(), instanceId, false) if err != nil { log.Error("Error getting current status", log.Fields{ "error": err.Error(), -- 2.16.6