Skip to content

Commit

Permalink
K8s/DualWriter: Remove legacy interface (grafana#101395)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryantxu authored Feb 27, 2025
1 parent b169046 commit 58457d4
Show file tree
Hide file tree
Showing 26 changed files with 108 additions and 299 deletions.
41 changes: 18 additions & 23 deletions pkg/apiserver/rest/dualwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,18 @@ var (
_ rest.SingularNameProvider = (DualWriter)(nil)
)

type dualWriteContextKey struct{}

func IsDualWriteUpdate(ctx context.Context) bool {
return ctx.Value(dualWriteContextKey{}) == true
}

func WithDualWriteUpdate(ctx context.Context) context.Context {
return context.WithValue(ctx, dualWriteContextKey{}, true)
}

// Function that will create a dual writer
type DualWriteBuilder func(gr schema.GroupResource, legacy LegacyStorage, storage Storage) (Storage, error)
type DualWriteBuilder func(gr schema.GroupResource, legacy Storage, unified Storage) (Storage, error)

// Storage is a storage implementation that satisfies the same interfaces as genericregistry.Store.
type Storage interface {
Expand All @@ -36,26 +46,12 @@ type Storage interface {
rest.TableConvertor
rest.SingularNameProvider
rest.Getter
// TODO: when watch is implemented, we can replace all the below with rest.StandardStorage
rest.Lister
rest.CreaterUpdater
rest.GracefulDeleter
rest.CollectionDeleter
}

// LegacyStorage is a storage implementation that writes to the Grafana SQL database.
type LegacyStorage interface {
rest.Storage
rest.Scoper
rest.SingularNameProvider
rest.CreaterUpdater
rest.Lister
rest.GracefulDeleter
rest.CollectionDeleter
rest.TableConvertor
rest.Getter
}

// DualWriter is a storage implementation that writes first to LegacyStorage and then to Storage.
// If writing to LegacyStorage fails, the write to Storage is skipped and the error is returned.
// Storage is used for all read operations. This is useful as a migration step from SQL based
Expand All @@ -79,7 +75,6 @@ type LegacyStorage interface {

type DualWriter interface {
Storage
LegacyStorage
Mode() DualWriterMode
}

Expand Down Expand Up @@ -110,8 +105,8 @@ const (
// NewDualWriter returns a new DualWriter.
func NewDualWriter(
mode DualWriterMode,
legacy LegacyStorage,
storage Storage,
legacy Storage,
unified Storage,
reg prometheus.Registerer,
resource string,
) Storage {
Expand All @@ -122,17 +117,17 @@ func NewDualWriter(
return legacy
case Mode1:
// read and write only from legacy storage
return newDualWriterMode1(legacy, storage, metrics, resource)
return newDualWriterMode1(legacy, unified, metrics, resource)
case Mode2:
// write to both, read from storage but use legacy as backup
return newDualWriterMode2(legacy, storage, metrics, resource)
return newDualWriterMode2(legacy, unified, metrics, resource)
case Mode3:
// write to both, read from storage only
return newDualWriterMode3(legacy, storage, metrics, resource)
return newDualWriterMode3(legacy, unified, metrics, resource)
case Mode4, Mode5:
return storage
return unified
default:
return newDualWriterMode1(legacy, storage, metrics, resource)
return newDualWriterMode1(legacy, unified, metrics, resource)
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/apiserver/rest/dualwriter_mode1.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

type DualWriterMode1 struct {
Legacy LegacyStorage
Legacy Storage
Storage Storage
*dualWriterMetrics
resource string
Expand All @@ -26,7 +26,7 @@ const mode1Str = "1"

// NewDualWriterMode1 returns a new DualWriter in mode 1.
// Mode 1 represents writing to and reading from LegacyStorage.
func newDualWriterMode1(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode1 {
func newDualWriterMode1(legacy Storage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode1 {
return &DualWriterMode1{
Legacy: legacy,
Storage: storage,
Expand Down
48 changes: 24 additions & 24 deletions pkg/apiserver/rest/dualwriter_mode1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ func TestMode1_Create(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -122,10 +122,10 @@ func TestMode1_CreateOnUnifiedStorage(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -190,10 +190,10 @@ func TestMode1_Get(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -251,10 +251,10 @@ func TestMode1_GetFromUnifiedStorage(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -308,10 +308,10 @@ func TestMode1_List(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -365,10 +365,10 @@ func TestMode1_ListFromUnifiedStorage(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -434,10 +434,10 @@ func TestMode1_Delete(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -494,10 +494,10 @@ func TestMode1_DeleteFromUnifiedStorage(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -565,10 +565,10 @@ func TestMode1_DeleteCollection(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -626,10 +626,10 @@ func TestMode1_DeleteCollectionFromUnifiedStorage(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -695,10 +695,10 @@ func TestMode1_Update(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -761,10 +761,10 @@ func TestMode1_UpdateOnUnifiedStorage(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down
10 changes: 2 additions & 8 deletions pkg/apiserver/rest/dualwriter_mode2.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,9 @@ import (
"github.com/grafana/grafana/pkg/apimachinery/utils"
)

type dualWriteContextKey struct{}

func IsDualWriteUpdate(ctx context.Context) bool {
return ctx.Value(dualWriteContextKey{}) == true
}

type DualWriterMode2 struct {
Storage Storage
Legacy LegacyStorage
Legacy Storage
*dualWriterMetrics
resource string
Log klog.Logger
Expand All @@ -35,7 +29,7 @@ const mode2Str = "2"
// newDualWriterMode2 returns a new DualWriter in mode 2.
// Mode 2 represents writing to LegacyStorage first, then to Storage.
// When reading, values from LegacyStorage will be returned.
func newDualWriterMode2(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode2 {
func newDualWriterMode2(legacy Storage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode2 {
return &DualWriterMode2{
Legacy: legacy,
Storage: storage,
Expand Down
24 changes: 12 additions & 12 deletions pkg/apiserver/rest/dualwriter_mode2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ func TestMode2_Create(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -138,10 +138,10 @@ func TestMode2_Get(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -212,10 +212,10 @@ func TestMode2_List(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -313,10 +313,10 @@ func TestMode2_Delete(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -382,10 +382,10 @@ func TestMode2_DeleteCollection(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down Expand Up @@ -451,10 +451,10 @@ func TestMode2_Update(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := (LegacyStorage)(nil)
l := (Storage)(nil)
s := (Storage)(nil)

ls := legacyStoreMock{&mock.Mock{}, l}
ls := storageMock{&mock.Mock{}, l}
us := storageMock{&mock.Mock{}, s}

if tt.setupLegacyFn != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/apiserver/rest/dualwriter_mode3.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

type DualWriterMode3 struct {
Legacy LegacyStorage
Legacy Storage
Storage Storage
watchImp rest.Watcher // watch is only available in mode 3 and 4
*dualWriterMetrics
Expand All @@ -27,7 +27,7 @@ type DualWriterMode3 struct {

// newDualWriterMode3 returns a new DualWriter in mode 3.
// Mode 3 represents writing to LegacyStorage and Storage and reading from Storage.
func newDualWriterMode3(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode3 {
func newDualWriterMode3(legacy Storage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode3 {
return &DualWriterMode3{
Legacy: legacy,
Storage: storage,
Expand Down
Loading

0 comments on commit 58457d4

Please sign in to comment.