mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 17:02:20 +08:00

--------- Co-authored-by: Ieva <ieva.vasiljeva@grafana.com> Co-authored-by: Gabriel MABILLE <gabriel.mabille@grafana.com> Co-authored-by: Marco de Abreu <marco.deabreu@grafana.com> Co-authored-by: Georges Chaudy <chaudyg@gmail.com>
113 lines
4.2 KiB
Go
113 lines
4.2 KiB
Go
package dashboard
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apiserver/pkg/registry/generic"
|
|
"k8s.io/apiserver/pkg/registry/generic/registry"
|
|
"k8s.io/apiserver/pkg/registry/rest"
|
|
|
|
"github.com/grafana/authlib/types"
|
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
|
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
|
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
|
"github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy"
|
|
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
|
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
|
"github.com/grafana/grafana/pkg/storage/unified/apistore"
|
|
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
|
)
|
|
|
|
type DashboardStorage struct {
|
|
Access legacy.DashboardAccess
|
|
DashboardService dashboards.DashboardService
|
|
}
|
|
|
|
func (s *DashboardStorage) NewStore(dash utils.ResourceInfo, scheme *runtime.Scheme, defaultOptsGetter generic.RESTOptionsGetter, reg prometheus.Registerer, permissions dashboards.PermissionsRegistrationService, ac types.AccessClient) (grafanarest.Storage, error) {
|
|
server, err := resource.NewResourceServer(resource.ResourceServerOptions{
|
|
Backend: s.Access,
|
|
Reg: reg,
|
|
AccessClient: ac,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defaultOpts, err := defaultOptsGetter.GetRESTOptions(dash.GroupResource(), nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client := legacy.NewDirectResourceClient(server) // same context
|
|
optsGetter := apistore.NewRESTOptionsGetterForClient(client,
|
|
defaultOpts.StorageConfig.Config, nil,
|
|
)
|
|
optsGetter.RegisterOptions(dash.GroupResource(), apistore.StorageOptions{
|
|
EnableFolderSupport: true,
|
|
RequireDeprecatedInternalID: true,
|
|
Permissions: permissions.SetDefaultPermissionsAfterCreate,
|
|
})
|
|
|
|
store, err := grafanaregistry.NewRegistryStore(scheme, dash, optsGetter)
|
|
return &storeWrapper{
|
|
Store: store,
|
|
DashboardService: s.DashboardService,
|
|
}, err
|
|
}
|
|
|
|
type storeWrapper struct {
|
|
*registry.Store
|
|
DashboardService dashboards.DashboardService
|
|
}
|
|
|
|
// Create will create the dashboard using legacy storage and make sure the internal ID is set on the return object
|
|
func (s *storeWrapper) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
|
|
ctx = legacy.WithLegacyAccess(ctx)
|
|
|
|
obj, err := s.Store.Create(ctx, obj, createValidation, options)
|
|
access := legacy.GetLegacyAccess(ctx)
|
|
if access != nil && access.DashboardID > 0 {
|
|
meta, _ := utils.MetaAccessor(obj)
|
|
if meta != nil {
|
|
// skip the linter error for deprecated function
|
|
meta.SetDeprecatedInternalID(access.DashboardID) //nolint:staticcheck
|
|
}
|
|
}
|
|
meta, metaErr := utils.MetaAccessor(obj)
|
|
if metaErr == nil {
|
|
// Reconstruct the same UID as done at the storage level
|
|
// https://github.com/grafana/grafana/blob/a84e96fba29c3a1bb384fdbad1c9c658cc79ec8f/pkg/registry/apis/dashboard/legacy/sql_dashboards.go#L287
|
|
// This is necessary because the UID generated during the creation via legacy storage is actually never stored in the database
|
|
// and the one returned here is wrong.
|
|
meta.SetUID(gapiutil.CalculateClusterWideUID(obj))
|
|
}
|
|
|
|
if err != nil {
|
|
return obj, err
|
|
}
|
|
|
|
if metaErr != nil {
|
|
return obj, metaErr
|
|
}
|
|
|
|
return obj, nil
|
|
}
|
|
|
|
// Update will update the dashboard using legacy storage and make sure the internal ID is set on the return object
|
|
func (s *storeWrapper) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
|
|
ctx = legacy.WithLegacyAccess(ctx)
|
|
obj, created, err := s.Store.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
|
|
access := legacy.GetLegacyAccess(ctx)
|
|
if access != nil && access.DashboardID > 0 {
|
|
meta, _ := utils.MetaAccessor(obj)
|
|
if meta != nil {
|
|
// skip the linter error for deprecated function
|
|
meta.SetDeprecatedInternalID(access.DashboardID) //nolint:staticcheck
|
|
}
|
|
}
|
|
return obj, created, err
|
|
}
|