mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Restructure cloudmigration service (#83211)
* Restructure cloudmigation service * Adjust codewoners and wire * Comment out unused metrics
This commit is contained in:
56
pkg/services/cloudmigration/api/api.go
Normal file
56
pkg/services/cloudmigration/api/api.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
type MigrationAPI struct {
|
||||
cloudMigrationsService cloudmigration.Service
|
||||
routeRegister routing.RouteRegister
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func RegisterApi(
|
||||
rr routing.RouteRegister,
|
||||
cms cloudmigration.Service,
|
||||
) *MigrationAPI {
|
||||
api := &MigrationAPI{
|
||||
log: log.New("cloudmigrations.api"),
|
||||
routeRegister: rr,
|
||||
cloudMigrationsService: cms,
|
||||
}
|
||||
api.registerEndpoints()
|
||||
return api
|
||||
}
|
||||
|
||||
// RegisterAPIEndpoints Registers Endpoints on Grafana Router
|
||||
func (api *MigrationAPI) registerEndpoints() {
|
||||
api.routeRegister.Group("/api/cloudmigrations", func(apiRoute routing.RouteRegister) {
|
||||
apiRoute.Post(
|
||||
"/migrate_datasources",
|
||||
routing.Wrap(api.MigrateDatasources),
|
||||
)
|
||||
}, middleware.ReqGrafanaAdmin)
|
||||
}
|
||||
|
||||
func (api *MigrationAPI) MigrateDatasources(c *contextmodel.ReqContext) response.Response {
|
||||
var req cloudmigration.MigrateDatasourcesRequestDTO
|
||||
if err := web.Bind(c.Req, &req); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
|
||||
resp, err := api.cloudMigrationsService.MigrateDatasources(c.Req.Context(), &cloudmigration.MigrateDatasourcesRequest{MigrateToPDC: req.MigrateToPDC, MigrateCredentials: req.MigrateCredentials})
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "data source migrations error", err)
|
||||
}
|
||||
|
||||
return response.JSON(http.StatusOK, cloudmigration.MigrateDatasourcesResponseDTO{DatasourcesMigrated: resp.DatasourcesMigrated})
|
||||
}
|
||||
12
pkg/services/cloudmigration/api/api_test.go
Normal file
12
pkg/services/cloudmigration/api/api_test.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_OnlyEnabledForGrafanaAdmi(t *testing.T) {
|
||||
// TODO: implement
|
||||
assert.True(t, true)
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration/api"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// CloudMigrationsServiceImpl Define the Service Implementation.
|
||||
type Service struct {
|
||||
store store
|
||||
|
||||
log log.Logger
|
||||
cfg *setting.Cfg
|
||||
|
||||
features featuremgmt.FeatureToggles
|
||||
dsService datasources.DataSourceService
|
||||
|
||||
api *api.MigrationAPI
|
||||
// metrics *Metrics
|
||||
}
|
||||
|
||||
var LogPrefix = "cloudmigration.service"
|
||||
|
||||
var _ cloudmigration.Service = (*Service)(nil)
|
||||
|
||||
// ProvideService Factory for method used by wire to inject dependencies.
|
||||
// builds the service, and api, and configures routes
|
||||
func ProvideService(
|
||||
cfg *setting.Cfg,
|
||||
features featuremgmt.FeatureToggles,
|
||||
db db.DB,
|
||||
dsService datasources.DataSourceService,
|
||||
routeRegister routing.RouteRegister,
|
||||
prom prometheus.Registerer,
|
||||
) cloudmigration.Service {
|
||||
if !features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrations) {
|
||||
return &NoopServiceImpl{}
|
||||
}
|
||||
|
||||
s := &Service{
|
||||
store: &sqlStore{db: db},
|
||||
log: log.New(LogPrefix),
|
||||
cfg: cfg,
|
||||
features: features,
|
||||
dsService: dsService,
|
||||
}
|
||||
s.api = api.RegisterApi(routeRegister, s)
|
||||
|
||||
if err := s.registerMetrics(prom); err != nil {
|
||||
s.log.Warn("error registering prom metrics", "error", err.Error())
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Service) MigrateDatasources(ctx context.Context, request *cloudmigration.MigrateDatasourcesRequest) (*cloudmigration.MigrateDatasourcesResponse, error) {
|
||||
return s.store.MigrateDatasources(ctx, request)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
)
|
||||
|
||||
// CloudMigrationsServiceImpl Define the Service Implementation.
|
||||
type NoopServiceImpl struct{}
|
||||
|
||||
var _ cloudmigration.Service = (*NoopServiceImpl)(nil)
|
||||
|
||||
func (s *NoopServiceImpl) MigrateDatasources(ctx context.Context, request *cloudmigration.MigrateDatasourcesRequest) (*cloudmigration.MigrateDatasourcesResponse, error) {
|
||||
return nil, cloudmigration.ErrFeatureDisabledError
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_NoopServiceDoesNothing(t *testing.T) {
|
||||
s := &NoopServiceImpl{}
|
||||
_, e := s.MigrateDatasources(context.Background(), &cloudmigration.MigrateDatasourcesRequest{})
|
||||
assert.ErrorIs(t, e, cloudmigration.ErrFeatureDisabledError)
|
||||
}
|
||||
26
pkg/services/cloudmigration/cloudmigrationimpl/metric.go
Normal file
26
pkg/services/cloudmigration/cloudmigrationimpl/metric.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// type Metrics struct {
|
||||
// log log.Logger
|
||||
// }
|
||||
|
||||
func (s *Service) registerMetrics(prom prometheus.Registerer) error {
|
||||
for _, m := range cloudmigration.PromMetrics {
|
||||
if err := prom.Register(m); err != nil {
|
||||
var alreadyRegisterErr prometheus.AlreadyRegisteredError
|
||||
if errors.As(err, &alreadyRegisterErr) {
|
||||
s.log.Warn("metric already registered", "metric", m)
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
11
pkg/services/cloudmigration/cloudmigrationimpl/store.go
Normal file
11
pkg/services/cloudmigration/cloudmigrationimpl/store.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
)
|
||||
|
||||
type store interface {
|
||||
MigrateDatasources(context.Context, *cloudmigration.MigrateDatasourcesRequest) (*cloudmigration.MigrateDatasourcesResponse, error)
|
||||
}
|
||||
16
pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go
Normal file
16
pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
)
|
||||
|
||||
type sqlStore struct {
|
||||
db db.DB
|
||||
}
|
||||
|
||||
func (ss *sqlStore) MigrateDatasources(ctx context.Context, request *cloudmigration.MigrateDatasourcesRequest) (*cloudmigration.MigrateDatasourcesResponse, error) {
|
||||
return nil, cloudmigration.ErrInternalNotImplementedError
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cloudmigrationimpl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMigrateDatasources(t *testing.T) {
|
||||
// TODO: Write this test
|
||||
}
|
||||
9
pkg/services/cloudmigration/cloudmigrations.go
Normal file
9
pkg/services/cloudmigration/cloudmigrations.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package cloudmigration
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
MigrateDatasources(context.Context, *MigrateDatasourcesRequest) (*MigrateDatasourcesResponse, error)
|
||||
}
|
||||
15
pkg/services/cloudmigration/cloudmigrationtest/fake.go
Normal file
15
pkg/services/cloudmigration/cloudmigrationtest/fake.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package cloudmigrationtest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
ExpectedError error
|
||||
}
|
||||
|
||||
func (s *Service) MigrateDatasources(ctx context.Context, request *cloudmigration.MigrateDatasourcesRequest) (*cloudmigration.MigrateDatasourcesResponse, error) {
|
||||
return nil, cloudmigration.ErrInternalNotImplementedError
|
||||
}
|
||||
43
pkg/services/cloudmigration/model.go
Normal file
43
pkg/services/cloudmigration/model.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package cloudmigration
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInternalNotImplementedError = errutil.Internal("cloudmigrations.notImplemented", errutil.WithPublicMessage("Internal server error"))
|
||||
ErrFeatureDisabledError = errutil.Internal("cloudmigrations.disabled", errutil.WithPublicMessage("Cloud migrations are disabled on this instance"))
|
||||
)
|
||||
|
||||
type MigrateDatasourcesRequest struct {
|
||||
MigrateToPDC bool
|
||||
MigrateCredentials bool
|
||||
}
|
||||
|
||||
type MigrateDatasourcesResponse struct {
|
||||
DatasourcesMigrated int
|
||||
}
|
||||
|
||||
type MigrateDatasourcesRequestDTO struct {
|
||||
MigrateToPDC bool `json:"migrateToPDC"`
|
||||
MigrateCredentials bool `json:"migrateCredentials"`
|
||||
}
|
||||
|
||||
type MigrateDatasourcesResponseDTO struct {
|
||||
DatasourcesMigrated int `json:"datasourcesMigrated"`
|
||||
}
|
||||
|
||||
const (
|
||||
namespace = "grafana"
|
||||
subsystem = "cloudmigrations"
|
||||
)
|
||||
|
||||
var PromMetrics = []prometheus.Collector{
|
||||
prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "datasources_migrated",
|
||||
Help: "Total amount of data sources migrated",
|
||||
}, []string{"pdc_converted"}),
|
||||
}
|
||||
Reference in New Issue
Block a user