diff --git a/pkg/registry/apis/dashboard/access/README.md b/pkg/registry/apis/dashboard/legacy/README.md similarity index 100% rename from pkg/registry/apis/dashboard/access/README.md rename to pkg/registry/apis/dashboard/legacy/README.md diff --git a/pkg/registry/apis/dashboard/access/sql_dashboards.go b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go similarity index 99% rename from pkg/registry/apis/dashboard/access/sql_dashboards.go rename to pkg/registry/apis/dashboard/legacy/sql_dashboards.go index 99375d8d0d4..35410bbb5af 100644 --- a/pkg/registry/apis/dashboard/access/sql_dashboards.go +++ b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go @@ -1,4 +1,4 @@ -package access +package legacy import ( "context" diff --git a/pkg/registry/apis/dashboard/access/storage.go b/pkg/registry/apis/dashboard/legacy/storage.go similarity index 99% rename from pkg/registry/apis/dashboard/access/storage.go rename to pkg/registry/apis/dashboard/legacy/storage.go index b45806de0da..693889d38dd 100644 --- a/pkg/registry/apis/dashboard/access/storage.go +++ b/pkg/registry/apis/dashboard/legacy/storage.go @@ -1,4 +1,4 @@ -package access +package legacy import ( "context" diff --git a/pkg/registry/apis/dashboard/access/token.go b/pkg/registry/apis/dashboard/legacy/token.go similarity index 99% rename from pkg/registry/apis/dashboard/access/token.go rename to pkg/registry/apis/dashboard/legacy/token.go index ded79df908c..e811561b957 100644 --- a/pkg/registry/apis/dashboard/access/token.go +++ b/pkg/registry/apis/dashboard/legacy/token.go @@ -1,4 +1,4 @@ -package access +package legacy import ( "fmt" diff --git a/pkg/registry/apis/dashboard/access/types.go b/pkg/registry/apis/dashboard/legacy/types.go similarity index 98% rename from pkg/registry/apis/dashboard/access/types.go rename to pkg/registry/apis/dashboard/legacy/types.go index cb5cd6aa682..a8778d1cd4e 100644 --- a/pkg/registry/apis/dashboard/access/types.go +++ b/pkg/registry/apis/dashboard/legacy/types.go @@ -1,4 +1,4 @@ -package access +package legacy import ( "context" diff --git a/pkg/registry/apis/dashboard/legacy_storage.go b/pkg/registry/apis/dashboard/legacy_storage.go index 6e6605692ca..c546934ad71 100644 --- a/pkg/registry/apis/dashboard/legacy_storage.go +++ b/pkg/registry/apis/dashboard/legacy_storage.go @@ -8,20 +8,21 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" - "github.com/grafana/grafana/pkg/registry/apis/dashboard/access" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" "github.com/grafana/grafana/pkg/storage/unified/apistore" "github.com/grafana/grafana/pkg/storage/unified/resource" ) type dashboardStorage struct { resource common.ResourceInfo - access access.DashboardAccess + access legacy.DashboardAccess tableConverter rest.TableConvertor server resource.ResourceServer } -func (s *dashboardStorage) newStore(scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter) (rest.Storage, error) { +func (s *dashboardStorage) newStore(scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter) (grafanarest.LegacyStorage, error) { server, err := resource.NewResourceServer(resource.ResourceServerOptions{ Store: s.access, Search: s.access, diff --git a/pkg/registry/apis/dashboard/register.go b/pkg/registry/apis/dashboard/register.go index b33f009edf6..6453e22a2be 100644 --- a/pkg/registry/apis/dashboard/register.go +++ b/pkg/registry/apis/dashboard/register.go @@ -17,11 +17,12 @@ import ( dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" "github.com/grafana/grafana/pkg/apiserver/builder" + grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/tracing" - "github.com/grafana/grafana/pkg/registry/apis/dashboard/access" + "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils" @@ -39,7 +40,7 @@ type DashboardsAPIBuilder struct { dashboardService dashboards.DashboardService accessControl accesscontrol.AccessControl - store *dashboardStorage + legacy *dashboardStorage log log.Logger } @@ -65,9 +66,9 @@ func RegisterAPIService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, dashboardService: dashboardService, accessControl: accessControl, - store: &dashboardStorage{ + legacy: &dashboardStorage{ resource: dashboard.DashboardResourceInfo, - access: access.NewDashboardAccess(sql, namespacer, dashStore, provisioning), + access: legacy.NewDashboardAccess(sql, namespacer, dashStore, provisioning), tableConverter: gapiutil.NewTableConverter( dashboard.DashboardResourceInfo.GroupResource(), []metav1.TableColumnDefinition{ @@ -144,8 +145,8 @@ func (b *DashboardsAPIBuilder) GetAPIGroupInfo( ) (*genericapiserver.APIGroupInfo, error) { apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(dashboard.GROUP, scheme, metav1.ParameterCodec, codecs) - dash := b.store.resource - legacyStore, err := b.store.newStore(scheme, optsGetter) + dash := b.legacy.resource + legacyStore, err := b.legacy.newStore(scheme, optsGetter) if err != nil { return nil, err } @@ -156,22 +157,23 @@ func (b *DashboardsAPIBuilder) GetAPIGroupInfo( builder: b, } storage[dash.StoragePath("history")] = apistore.NewHistoryConnector( - b.store.server, // as client??? + b.legacy.server, // as client??? dashboard.DashboardResourceInfo.GroupResource(), ) - // // Dual writes if a RESTOptionsGetter is provided - // if desiredMode != grafanarest.Mode0 && optsGetter != nil { - // options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: grafanaregistry.GetAttrs} - // if err := store.CompleteWithOptions(options); err != nil { - // return nil, err - // } - // storage[resourceInfo.StoragePath()] = grafanarest.NewDualWriter( - // grafanarest.Mode1, - // store, //legacyStore, - // store, - // reg) - // } + // Dual writes if a RESTOptionsGetter is provided + if desiredMode != grafanarest.Mode0 && optsGetter != nil { + store, err := newStorage(scheme) + if err != nil { + return nil, err + } + + options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: grafanaregistry.GetAttrs} + if err := store.CompleteWithOptions(options); err != nil { + return nil, err + } + storage[dash.StoragePath()] = grafanarest.NewDualWriter(grafanarest.Mode1, legacyStore, store, reg) + } apiGroupInfo.VersionedResourcesStorageMap[dashboard.VERSION] = storage return &apiGroupInfo, nil diff --git a/pkg/registry/apis/dashboard/storage.go b/pkg/registry/apis/dashboard/storage.go new file mode 100644 index 00000000000..ace79bc02e3 --- /dev/null +++ b/pkg/registry/apis/dashboard/storage.go @@ -0,0 +1,60 @@ +package dashboard + +import ( + "fmt" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils" +) + +var _ grafanarest.Storage = (*storage)(nil) + +type storage struct { + *genericregistry.Store +} + +func newStorage(scheme *runtime.Scheme) (*storage, error) { + strategy := grafanaregistry.NewStrategy(scheme) + resourceInfo := v0alpha1.DashboardResourceInfo + store := &genericregistry.Store{ + NewFunc: resourceInfo.NewFunc, + NewListFunc: resourceInfo.NewListFunc, + KeyRootFunc: grafanaregistry.KeyRootFunc(resourceInfo.GroupResource()), + KeyFunc: grafanaregistry.NamespaceKeyFunc(resourceInfo.GroupResource()), + PredicateFunc: grafanaregistry.Matcher, + DefaultQualifiedResource: resourceInfo.GroupResource(), + SingularQualifiedResource: resourceInfo.SingularGroupResource(), + CreateStrategy: strategy, + UpdateStrategy: strategy, + DeleteStrategy: strategy, + } + + store.TableConvertor = gapiutil.NewTableConverter( + store.DefaultQualifiedResource, + []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Title", Type: "string", Format: "string", Description: "The dashboard name"}, + {Name: "Created At", Type: "date"}, + }, + func(obj any) ([]interface{}, error) { + dash, ok := obj.(*v0alpha1.Dashboard) + if ok { + if dash != nil { + return []interface{}{ + dash.Name, + dash.Spec.GetNestedString("title"), + dash.CreationTimestamp.UTC().Format(time.RFC3339), + }, nil + } + } + return nil, fmt.Errorf("expected dashboard or summary") + }) + return &storage{Store: store}, nil +} diff --git a/pkg/registry/apis/dashboard/sub_dto.go b/pkg/registry/apis/dashboard/sub_dto.go index 0b7a9ab9745..a336cf61b10 100644 --- a/pkg/registry/apis/dashboard/sub_dto.go +++ b/pkg/registry/apis/dashboard/sub_dto.go @@ -99,7 +99,7 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob Resource: dashboard.DashboardResourceInfo.GroupResource().Resource, Name: name, } - store := r.builder.store.access + store := r.builder.legacy.access rsp, err := store.Read(ctx, &resource.ReadRequest{Key: key}) if err != nil { return nil, err