mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Cloud migration: Refactor get by org ID to dashboard svc (#98646)
This commit is contained in:
parent
9b1ecaedda
commit
58ed8a9ec2
@ -399,18 +399,15 @@ func Test_OnlyQueriesStatusFromGMSWhenRequired(t *testing.T) {
|
||||
func Test_DeletedDashboardsNotMigrated(t *testing.T) {
|
||||
s := setUpServiceTest(t, false).(*Service)
|
||||
|
||||
/** NOTE: this is not used at the moment since we changed the service
|
||||
|
||||
// modify what the mock returns for just this test case
|
||||
dashMock := s.dashboardService.(*dashboards.FakeDashboardService)
|
||||
dashMock.On("GetAllDashboards", mock.Anything).Return(
|
||||
dashMock.On("GetAllDashboardsByOrgId", mock.Anything).Return(
|
||||
[]*dashboards.Dashboard{
|
||||
{UID: "1", OrgID: 1, Data: simplejson.New()},
|
||||
{UID: "2", OrgID: 1, Data: simplejson.New(), Deleted: time.Now()},
|
||||
},
|
||||
nil,
|
||||
)
|
||||
*/
|
||||
|
||||
data, err := s.getMigrationDataJSON(context.TODO(), &user.SignedInUser{OrgID: 1})
|
||||
assert.NoError(t, err)
|
||||
|
@ -277,7 +277,7 @@ func (s *Service) getDashboardAndFolderCommands(ctx context.Context, signedInUse
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDashboardAndFolderCommands")
|
||||
defer span.End()
|
||||
|
||||
dashs, err := s.store.GetAllDashboardsByOrgId(ctx, signedInUser.GetOrgID())
|
||||
dashs, err := s.dashboardService.GetAllDashboardsByOrgId(ctx, signedInUser.GetOrgID())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
)
|
||||
|
||||
type store interface {
|
||||
@ -26,7 +25,4 @@ type store interface {
|
||||
// - GetSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error)
|
||||
// - GetSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error)
|
||||
// - DeleteSnapshotResources(ctx context.Context, snapshotUid string) error
|
||||
|
||||
// TODO move this function dashboards/databases/databases.go
|
||||
GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error)
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
secretskv "github.com/grafana/grafana/pkg/services/secrets/kvstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
@ -465,19 +464,3 @@ func (ss *sqlStore) decryptToken(ctx context.Context, cm *cloudmigration.CloudMi
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO move this function dashboards/databases/databases.go
|
||||
func (ss *sqlStore) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error) {
|
||||
//ctx, span := tracer.Start(ctx, "dashboards.database.GetAllDashboardsByOrgId")
|
||||
//defer span.End()
|
||||
|
||||
var dashs = make([]*dashboards.Dashboard, 0)
|
||||
err := ss.db.WithDbSession(ctx, func(session *db.Session) error {
|
||||
// "deleted IS NULL" is to avoid deleted dashboards
|
||||
return session.Where("org_id = ? AND deleted IS NULL", orgID).Find(&dashs)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dashs, nil
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ type DashboardService interface {
|
||||
CountInFolders(ctx context.Context, orgID int64, folderUIDs []string, user identity.Requester) (int64, error)
|
||||
GetDashboardsSharedWithUser(ctx context.Context, user identity.Requester) ([]*Dashboard, error)
|
||||
GetAllDashboards(ctx context.Context) ([]*Dashboard, error)
|
||||
GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*Dashboard, error)
|
||||
SoftDeleteDashboard(ctx context.Context, orgID int64, dashboardUid string) error
|
||||
RestoreDashboard(ctx context.Context, dashboard *Dashboard, user identity.Requester, optionalFolderUID string) error
|
||||
CleanUpDeletedDashboards(ctx context.Context) (int64, error)
|
||||
@ -86,6 +87,7 @@ type Store interface {
|
||||
DeleteDashboardsInFolders(ctx context.Context, request *DeleteDashboardsInFolderRequest) error
|
||||
|
||||
GetAllDashboards(ctx context.Context) ([]*Dashboard, error)
|
||||
GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*Dashboard, error)
|
||||
GetSoftDeletedExpiredDashboards(ctx context.Context, duration time.Duration) ([]*Dashboard, error)
|
||||
SoftDeleteDashboard(ctx context.Context, orgID int64, dashboardUid string) error
|
||||
SoftDeleteDashboardsInFolders(ctx context.Context, orgID int64, folderUids []string) error
|
||||
|
@ -198,6 +198,36 @@ func (_m *FakeDashboardService) GetAllDashboards(ctx context.Context) ([]*Dashbo
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
|
||||
func (_m *FakeDashboardService) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*Dashboard, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetAllDashboardsByOrgId")
|
||||
}
|
||||
|
||||
var r0 []*Dashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) ([]*Dashboard, error)); ok {
|
||||
return rf(ctx, orgID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) []*Dashboard); ok {
|
||||
r0 = rf(ctx, orgID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*Dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
|
||||
r1 = rf(ctx, orgID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetDashboard provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardService) GetDashboard(ctx context.Context, query *GetDashboardQuery) (*Dashboard, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
@ -1048,6 +1048,21 @@ func (d *dashboardStore) GetAllDashboards(ctx context.Context) ([]*dashboards.Da
|
||||
return dashboards, nil
|
||||
}
|
||||
|
||||
func (d *dashboardStore) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error) {
|
||||
ctx, span := tracer.Start(ctx, "dashboards.database.GetAllDashboardsByOrgId")
|
||||
defer span.End()
|
||||
|
||||
var dashs = make([]*dashboards.Dashboard, 0)
|
||||
err := d.store.WithDbSession(ctx, func(session *db.Session) error {
|
||||
// "deleted IS NULL" is to avoid deleted dashboards
|
||||
return session.Where("org_id = ? AND deleted IS NULL", orgID).Find(&dashs)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dashs, nil
|
||||
}
|
||||
|
||||
func (d *dashboardStore) GetSoftDeletedExpiredDashboards(ctx context.Context, duration time.Duration) ([]*dashboards.Dashboard, error) {
|
||||
ctx, span := tracer.Start(ctx, "dashboards.database.GetSoftDeletedExpiredDashboards")
|
||||
defer span.End()
|
||||
|
@ -266,6 +266,32 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
|
||||
assert.Equal(t, len(queryResult), 1)
|
||||
})
|
||||
|
||||
t.Run("Should be able to get all dashboards for an org", func(t *testing.T) {
|
||||
setup()
|
||||
dash1 := insertTestDashboard(t, dashboardStore, "org3test1", 3, 0, "", false, "org 1 test 1")
|
||||
dash2 := insertTestDashboard(t, dashboardStore, "org3test2", 3, 0, "", false, "org 1 test 2")
|
||||
dash3 := insertTestDashboard(t, dashboardStore, "org4test1", 4, 0, "", false, "org 2 test 1")
|
||||
|
||||
dashs, err := dashboardStore.GetAllDashboardsByOrgId(context.Background(), 3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(dashs), 2)
|
||||
uids := []string{}
|
||||
for _, d := range dashs {
|
||||
uids = append(uids, d.UID)
|
||||
}
|
||||
require.Contains(t, uids, dash1.UID)
|
||||
require.Contains(t, uids, dash2.UID)
|
||||
|
||||
dashs, err = dashboardStore.GetAllDashboardsByOrgId(context.Background(), 4)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(dashs), 1)
|
||||
require.Equal(t, dash3.UID, dashs[0].UID)
|
||||
|
||||
dashs, err = dashboardStore.GetAllDashboardsByOrgId(context.Background(), 5)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(dashs), 0)
|
||||
})
|
||||
|
||||
t.Run("Should be able to create dashboard", func(t *testing.T) {
|
||||
setup()
|
||||
cmd := dashboards.SaveDashboardCommand{
|
||||
|
@ -903,6 +903,14 @@ func (dr *DashboardServiceImpl) GetAllDashboards(ctx context.Context) ([]*dashbo
|
||||
return dr.dashboardStore.GetAllDashboards(ctx)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error) {
|
||||
if dr.features.IsEnabledGlobally(featuremgmt.FlagKubernetesCliDashboards) {
|
||||
return dr.listDashboardsThroughK8s(ctx, orgID)
|
||||
}
|
||||
|
||||
return dr.dashboardStore.GetAllDashboardsByOrgId(ctx, orgID)
|
||||
}
|
||||
|
||||
func getHitType(item dashboards.DashboardSearchProjection) model.HitType {
|
||||
var hitType model.HitType
|
||||
if item.IsFolder {
|
||||
|
@ -515,6 +515,58 @@ func TestGetAllDashboards(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetAllDashboardsByOrgId(t *testing.T) {
|
||||
fakeStore := dashboards.FakeDashboardStore{}
|
||||
defer fakeStore.AssertExpectations(t)
|
||||
service := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
dashboardStore: &fakeStore,
|
||||
}
|
||||
|
||||
t.Run("Should fallback to dashboard store if Kubernetes feature flags are not enabled", func(t *testing.T) {
|
||||
service.features = featuremgmt.WithFeatures()
|
||||
fakeStore.On("GetAllDashboardsByOrgId", mock.Anything).Return([]*dashboards.Dashboard{}, nil).Once()
|
||||
dashboard, err := service.GetAllDashboardsByOrgId(context.Background(), 1)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dashboard)
|
||||
fakeStore.AssertExpectations(t)
|
||||
})
|
||||
|
||||
t.Run("Should use Kubernetes client if feature flags are enabled", func(t *testing.T) {
|
||||
ctx, k8sClientMock, k8sResourceMock := setupK8sDashboardTests(service)
|
||||
|
||||
dashboardUnstructured := unstructured.Unstructured{Object: map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"name": "uid",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"test": "test",
|
||||
"version": int64(1),
|
||||
"title": "testing slugify",
|
||||
},
|
||||
}}
|
||||
|
||||
dashboardExpected := dashboards.Dashboard{
|
||||
UID: "uid", // uid is the name of the k8s object
|
||||
Title: "testing slugify",
|
||||
Slug: "testing-slugify", // slug is taken from title
|
||||
OrgID: 1, // orgID is populated from the query
|
||||
Version: 1, // default to version 1
|
||||
Data: simplejson.NewFromAny(map[string]any{"test": "test", "title": "testing slugify", "uid": "uid", "version": int64(1)}),
|
||||
}
|
||||
|
||||
k8sClientMock.On("getClient", mock.Anything, int64(1)).Return(k8sResourceMock, true).Once()
|
||||
k8sResourceMock.On("List", mock.Anything, mock.Anything).Return(&unstructured.UnstructuredList{Items: []unstructured.Unstructured{dashboardUnstructured}}, nil).Once()
|
||||
|
||||
dashes, err := service.GetAllDashboardsByOrgId(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dashes)
|
||||
k8sClientMock.AssertExpectations(t)
|
||||
// make sure the conversion is working
|
||||
require.True(t, reflect.DeepEqual(dashes, []*dashboards.Dashboard{&dashboardExpected}))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSaveDashboard(t *testing.T) {
|
||||
fakeStore := dashboards.FakeDashboardStore{}
|
||||
defer fakeStore.AssertExpectations(t)
|
||||
|
@ -208,6 +208,38 @@ func (_m *FakeDashboardStore) GetAllDashboards(ctx context.Context) ([]*Dashboar
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
|
||||
// GetAllDashboardsByOrgId provides a mock function with given fields: ctx
|
||||
func (_m *FakeDashboardStore) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*Dashboard, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetAllDashboardsByOrgId")
|
||||
}
|
||||
|
||||
var r0 []*Dashboard
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) ([]*Dashboard, error)); ok {
|
||||
return rf(ctx, orgID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) []*Dashboard); ok {
|
||||
r0 = rf(ctx, orgID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*Dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
|
||||
r1 = rf(ctx, orgID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
|
||||
// GetDashboard provides a mock function with given fields: ctx, query
|
||||
func (_m *FakeDashboardStore) GetDashboard(ctx context.Context, query *GetDashboardQuery) (*Dashboard, error) {
|
||||
ret := _m.Called(ctx, query)
|
||||
|
Loading…
Reference in New Issue
Block a user