Dashboard Migrations: V28 singlestat panel and deprecated variable properties (#108416)
Co-authored-by: Ivan Ortega <ivanortegaalba@gmail.com>
This commit is contained in:
co-authored by
Ivan Ortega
parent
3dcda77462
commit
5ad751ea28
@@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
func TestDashboardAPIBuilder_Mutate(t *testing.T) {
|
||||
migration.Initialize(testutil.GetTestProvider())
|
||||
migration.Initialize(testutil.GetTestDataSourceProvider(), testutil.GetTestPanelProvider())
|
||||
tests := []struct {
|
||||
name string
|
||||
inputObj runtime.Object
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
type PluginStorePanelProvider struct {
|
||||
pluginStore pluginstore.Store
|
||||
buildVersion string
|
||||
}
|
||||
|
||||
func (p *PluginStorePanelProvider) GetPanels() []schemaversion.PanelPluginInfo {
|
||||
plugins := p.pluginStore.Plugins(context.Background(), plugins.TypePanel)
|
||||
|
||||
panels := make([]schemaversion.PanelPluginInfo, len(plugins))
|
||||
for i, plugin := range plugins {
|
||||
version := plugin.Info.Version
|
||||
if version == "" {
|
||||
version = p.buildVersion
|
||||
}
|
||||
panels[i] = schemaversion.PanelPluginInfo{
|
||||
ID: plugin.ID,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
return panels
|
||||
}
|
||||
|
||||
func (p *PluginStorePanelProvider) GetPanelPlugin(id string) schemaversion.PanelPluginInfo {
|
||||
for _, plugin := range p.GetPanels() {
|
||||
if plugin.ID == id {
|
||||
return plugin
|
||||
}
|
||||
}
|
||||
|
||||
return schemaversion.PanelPluginInfo{}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPluginStorePanelProvider_GetPanels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
plugins []pluginstore.Plugin
|
||||
buildVersion string
|
||||
expectedPanels []schemaversion.PanelPluginInfo
|
||||
}{
|
||||
{
|
||||
name: "should return all panel plugins with their versions",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "gauge", Info: plugins.Info{Version: "1.0.0"}},
|
||||
},
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "stat", Info: plugins.Info{Version: "2.0.0"}},
|
||||
},
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "timeseries", Info: plugins.Info{Version: "3.0.0"}},
|
||||
},
|
||||
},
|
||||
buildVersion: "10.0.0",
|
||||
expectedPanels: []schemaversion.PanelPluginInfo{
|
||||
{ID: "gauge", Version: "1.0.0"},
|
||||
{ID: "stat", Version: "2.0.0"},
|
||||
{ID: "timeseries", Version: "3.0.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should use build version when plugin version is empty",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "gauge", Info: plugins.Info{Version: ""}},
|
||||
},
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "stat", Info: plugins.Info{Version: "2.0.0"}},
|
||||
},
|
||||
},
|
||||
buildVersion: "10.0.0",
|
||||
expectedPanels: []schemaversion.PanelPluginInfo{
|
||||
{ID: "gauge", Version: "10.0.0"},
|
||||
{ID: "stat", Version: "2.0.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty slice when no plugins",
|
||||
plugins: []pluginstore.Plugin{},
|
||||
buildVersion: "10.0.0",
|
||||
expectedPanels: []schemaversion.PanelPluginInfo{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create mock plugin store
|
||||
mockStore := &mockPluginStore{
|
||||
plugins: tt.plugins,
|
||||
}
|
||||
|
||||
// Create mock setting
|
||||
mockSetting := &setting.Cfg{
|
||||
BuildVersion: tt.buildVersion,
|
||||
}
|
||||
|
||||
// Create provider
|
||||
provider := &PluginStorePanelProvider{
|
||||
pluginStore: mockStore,
|
||||
buildVersion: mockSetting.BuildVersion,
|
||||
}
|
||||
|
||||
// Call the function
|
||||
result := provider.GetPanels()
|
||||
|
||||
// Assert results
|
||||
assert.Len(t, result, len(tt.expectedPanels))
|
||||
for i, expected := range tt.expectedPanels {
|
||||
assert.Equal(t, expected.ID, result[i].ID)
|
||||
assert.Equal(t, expected.Version, result[i].Version)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluginStorePanelProvider_GetPanelPlugin(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
plugins []pluginstore.Plugin
|
||||
buildVersion string
|
||||
searchID string
|
||||
expectedPanel schemaversion.PanelPluginInfo
|
||||
}{
|
||||
{
|
||||
name: "should return panel plugin when found",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "gauge", Info: plugins.Info{Version: "1.0.0"}},
|
||||
},
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "stat", Info: plugins.Info{Version: "2.0.0"}},
|
||||
},
|
||||
},
|
||||
buildVersion: "10.0.0",
|
||||
searchID: "stat",
|
||||
expectedPanel: schemaversion.PanelPluginInfo{
|
||||
ID: "stat",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return panel plugin with build version when plugin version is empty",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "gauge", Info: plugins.Info{Version: ""}},
|
||||
},
|
||||
},
|
||||
buildVersion: "10.0.0",
|
||||
searchID: "gauge",
|
||||
expectedPanel: schemaversion.PanelPluginInfo{
|
||||
ID: "gauge",
|
||||
Version: "10.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty panel plugin when not found",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{
|
||||
JSONData: plugins.JSONData{ID: "gauge", Info: plugins.Info{Version: "1.0.0"}},
|
||||
},
|
||||
},
|
||||
buildVersion: "10.0.0",
|
||||
searchID: "nonexistent",
|
||||
expectedPanel: schemaversion.PanelPluginInfo{},
|
||||
},
|
||||
{
|
||||
name: "should return empty panel plugin when no plugins exist",
|
||||
plugins: []pluginstore.Plugin{},
|
||||
buildVersion: "10.0.0",
|
||||
searchID: "gauge",
|
||||
expectedPanel: schemaversion.PanelPluginInfo{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockStore := &mockPluginStore{
|
||||
plugins: tt.plugins,
|
||||
}
|
||||
|
||||
mockSetting := &setting.Cfg{
|
||||
BuildVersion: tt.buildVersion,
|
||||
}
|
||||
|
||||
provider := &PluginStorePanelProvider{
|
||||
pluginStore: mockStore,
|
||||
buildVersion: mockSetting.BuildVersion,
|
||||
}
|
||||
|
||||
result := provider.GetPanelPlugin(tt.searchID)
|
||||
|
||||
assert.Equal(t, tt.expectedPanel.ID, result.ID)
|
||||
assert.Equal(t, tt.expectedPanel.Version, result.Version)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockPluginStore struct {
|
||||
plugins []pluginstore.Plugin
|
||||
}
|
||||
|
||||
func (m *mockPluginStore) Plugin(ctx context.Context, pluginID string) (pluginstore.Plugin, bool) {
|
||||
for _, p := range m.plugins {
|
||||
if p.ID == pluginID {
|
||||
return p, true
|
||||
}
|
||||
}
|
||||
return pluginstore.Plugin{}, false
|
||||
}
|
||||
|
||||
func (m *mockPluginStore) Plugins(ctx context.Context, pluginTypes ...plugins.Type) []pluginstore.Plugin {
|
||||
return m.plugins
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/librarypanels"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/search/sort"
|
||||
@@ -101,6 +102,7 @@ func RegisterAPIService(
|
||||
apiregistration builder.APIRegistrar,
|
||||
dashboardService dashboards.DashboardService,
|
||||
provisioningDashboardService dashboards.DashboardProvisioningService,
|
||||
pluginStore pluginstore.Store,
|
||||
datasourceService datasources.DataSourceService,
|
||||
dashboardPermissions dashboards.PermissionsRegistrationService,
|
||||
accessControl accesscontrol.AccessControl,
|
||||
@@ -150,6 +152,9 @@ func RegisterAPIService(
|
||||
}
|
||||
migration.Initialize(&datasourceInfoProvider{
|
||||
datasourceService: datasourceService,
|
||||
}, &PluginStorePanelProvider{
|
||||
pluginStore: pluginStore,
|
||||
buildVersion: cfg.BuildVersion,
|
||||
})
|
||||
apiregistration.RegisterAPI(builder)
|
||||
return builder
|
||||
|
||||
@@ -732,7 +732,7 @@ func Initialize(cfg *setting.Cfg, opts Options, apiOpts api.ServerOptions) (*Ser
|
||||
identitySynchronizer := authnimpl.ProvideIdentitySynchronizer(authnimplService)
|
||||
ldapImpl := service10.ProvideService(cfg, featureToggles, ssosettingsimplService)
|
||||
apiService := api4.ProvideService(cfg, routeRegisterImpl, accessControl, userService, authinfoimplService, ossGroups, identitySynchronizer, orgService, ldapImpl, userAuthTokenService, bundleregistryService)
|
||||
dashboardsAPIBuilder := dashboard.RegisterAPIService(cfg, featureToggles, apiserverService, dashboardService, dashboardProvisioningService, service15, dashboardServiceImpl, accessControl, accessClient, provisioningServiceImpl, dashboardsStore, registerer, sqlStore, tracingService, resourceClient, dualwriteService, sortService, quotaService, dashboardFolderStoreImpl, libraryPanelService, eventualRestConfigProvider, userService)
|
||||
dashboardsAPIBuilder := dashboard.RegisterAPIService(cfg, featureToggles, apiserverService, dashboardService, dashboardProvisioningService, pluginstoreService, service15, dashboardServiceImpl, accessControl, accessClient, provisioningServiceImpl, dashboardsStore, registerer, sqlStore, tracingService, resourceClient, dualwriteService, sortService, quotaService, dashboardFolderStoreImpl, libraryPanelService, eventualRestConfigProvider, userService)
|
||||
snapshotsAPIBuilder := dashboardsnapshot.RegisterAPIService(serviceImpl, apiserverService, cfg, featureToggles, sqlStore, registerer)
|
||||
featureFlagAPIBuilder := featuretoggle.RegisterAPIService(featureManager, accessControl, apiserverService, cfg, registerer)
|
||||
dataSourceAPIBuilder, err := datasource.RegisterAPIService(featureToggles, apiserverService, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, pluginstoreService, accessControl, registerer)
|
||||
@@ -1297,7 +1297,7 @@ func InitializeForTest(t sqlutil.ITestDB, testingT interface {
|
||||
identitySynchronizer := authnimpl.ProvideIdentitySynchronizer(authnimplService)
|
||||
ldapImpl := service10.ProvideService(cfg, featureToggles, ssosettingsimplService)
|
||||
apiService := api4.ProvideService(cfg, routeRegisterImpl, accessControl, userService, authinfoimplService, ossGroups, identitySynchronizer, orgService, ldapImpl, userAuthTokenService, bundleregistryService)
|
||||
dashboardsAPIBuilder := dashboard.RegisterAPIService(cfg, featureToggles, apiserverService, dashboardService, dashboardProvisioningService, service15, dashboardServiceImpl, accessControl, accessClient, provisioningServiceImpl, dashboardsStore, registerer, sqlStore, tracingService, resourceClient, dualwriteService, sortService, quotaService, dashboardFolderStoreImpl, libraryPanelService, eventualRestConfigProvider, userService)
|
||||
dashboardsAPIBuilder := dashboard.RegisterAPIService(cfg, featureToggles, apiserverService, dashboardService, dashboardProvisioningService, pluginstoreService, service15, dashboardServiceImpl, accessControl, accessClient, provisioningServiceImpl, dashboardsStore, registerer, sqlStore, tracingService, resourceClient, dualwriteService, sortService, quotaService, dashboardFolderStoreImpl, libraryPanelService, eventualRestConfigProvider, userService)
|
||||
snapshotsAPIBuilder := dashboardsnapshot.RegisterAPIService(serviceImpl, apiserverService, cfg, featureToggles, sqlStore, registerer)
|
||||
featureFlagAPIBuilder := featuretoggle.RegisterAPIService(featureManager, accessControl, apiserverService, cfg, registerer)
|
||||
dataSourceAPIBuilder, err := datasource.RegisterAPIService(featureToggles, apiserverService, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, pluginstoreService, accessControl, registerer)
|
||||
|
||||
Reference in New Issue
Block a user