CloudMigration: Create authapi service (#96581)
This commit is contained in:
@@ -3,13 +3,13 @@ package cloudmigration
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/gcom"
|
||||
"github.com/grafana/grafana/pkg/services/authapi"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
// GetToken Returns the cloud migration token if it exists.
|
||||
GetToken(ctx context.Context) (gcom.TokenView, error)
|
||||
GetToken(ctx context.Context) (authapi.TokenView, error)
|
||||
// CreateToken Creates a cloud migration token.
|
||||
CreateToken(ctx context.Context) (CreateAccessTokenResponse, error)
|
||||
// ValidateToken Sends a request to GMS to test the token.
|
||||
|
||||
@@ -19,6 +19,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/kvstore"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/authapi"
|
||||
"github.com/grafana/grafana/pkg/services/authapi/fake"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration/api"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration/gmsclient"
|
||||
@@ -62,6 +64,7 @@ type Service struct {
|
||||
|
||||
dsService datasources.DataSourceService
|
||||
gcomService gcom.Service
|
||||
authApiService authapi.Service
|
||||
dashboardService dashboards.DashboardService
|
||||
folderService folder.Service
|
||||
pluginStore pluginstore.Store
|
||||
@@ -151,9 +154,23 @@ func ProvideService(
|
||||
return nil, fmt.Errorf("creating http client for GCOM: %w", err)
|
||||
}
|
||||
s.gcomService = gcom.New(gcom.Config{ApiURL: cfg.GrafanaComAPIURL, Token: cfg.CloudMigration.GcomAPIToken}, httpClientGcom)
|
||||
|
||||
if features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAuthApiMig) {
|
||||
s.log.Info("using authapi client because feature flag is enabled")
|
||||
httpClientAuthApi, err := httpClientProvider.New()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating http client for AuthApi: %w", err)
|
||||
}
|
||||
// the api token is the same as for gcom
|
||||
s.authApiService = authapi.New(authapi.Config{ApiURL: cfg.CloudMigration.AuthAPIUrl, Token: cfg.CloudMigration.GcomAPIToken}, httpClientAuthApi)
|
||||
} else {
|
||||
s.log.Info("using gcom client for auth")
|
||||
s.authApiService = gcom.New(gcom.Config{ApiURL: cfg.GrafanaComAPIURL, Token: cfg.CloudMigration.GcomAPIToken}, httpClientGcom).(*gcom.GcomClient)
|
||||
}
|
||||
} else {
|
||||
s.gmsClient = gmsclient.NewInMemoryClient()
|
||||
s.gcomService = &gcomStub{policies: map[string]gcom.AccessPolicy{}, token: nil}
|
||||
s.gcomService = &gcomStub{}
|
||||
s.authApiService = &fake.AuthapiStub{Policies: map[string]authapi.AccessPolicy{}, Token: nil}
|
||||
s.cfg.StackID = "12345"
|
||||
}
|
||||
|
||||
@@ -169,7 +186,7 @@ func ProvideService(
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetToken(ctx context.Context) (gcom.TokenView, error) {
|
||||
func (s *Service) GetToken(ctx context.Context) (authapi.TokenView, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetToken")
|
||||
defer span.End()
|
||||
logger := s.log.FromContext(ctx)
|
||||
@@ -179,7 +196,7 @@ func (s *Service) GetToken(ctx context.Context) (gcom.TokenView, error) {
|
||||
defer cancel()
|
||||
instance, err := s.gcomService.GetInstanceByID(timeoutCtx, requestID, s.cfg.StackID)
|
||||
if err != nil {
|
||||
return gcom.TokenView{}, fmt.Errorf("fetching instance by id: id=%s %w", s.cfg.StackID, err)
|
||||
return authapi.TokenView{}, fmt.Errorf("fetching instance by id: id=%s %w", s.cfg.StackID, err)
|
||||
}
|
||||
|
||||
logger.Info("instance found", "slug", instance.Slug)
|
||||
@@ -189,14 +206,14 @@ func (s *Service) GetToken(ctx context.Context) (gcom.TokenView, error) {
|
||||
|
||||
timeoutCtx, cancel = context.WithTimeout(ctx, s.cfg.CloudMigration.ListTokensTimeout)
|
||||
defer cancel()
|
||||
tokens, err := s.gcomService.ListTokens(timeoutCtx, gcom.ListTokenParams{
|
||||
tokens, err := s.authApiService.ListTokens(timeoutCtx, authapi.ListTokenParams{
|
||||
RequestID: requestID,
|
||||
Region: instance.RegionSlug,
|
||||
AccessPolicyName: accessPolicyName,
|
||||
TokenName: accessTokenName,
|
||||
Region: instance.RegionSlug,
|
||||
})
|
||||
if err != nil {
|
||||
return gcom.TokenView{}, fmt.Errorf("listing tokens: %w", err)
|
||||
return authapi.TokenView{}, fmt.Errorf("listing tokens: %w", err)
|
||||
}
|
||||
logger.Info("found access tokens", "num_tokens", len(tokens))
|
||||
|
||||
@@ -208,7 +225,7 @@ func (s *Service) GetToken(ctx context.Context) (gcom.TokenView, error) {
|
||||
}
|
||||
|
||||
logger.Info("cloud migration token not found")
|
||||
return gcom.TokenView{}, fmt.Errorf("fetching cloud migration token: instance=%+v accessPolicyName=%s accessTokenName=%s %w",
|
||||
return authapi.TokenView{}, fmt.Errorf("fetching cloud migration token: instance=%+v accessPolicyName=%s accessTokenName=%s %w",
|
||||
instance, accessPolicyName, accessTokenName, cloudmigration.ErrTokenNotFound)
|
||||
}
|
||||
|
||||
@@ -231,7 +248,7 @@ func (s *Service) CreateToken(ctx context.Context) (cloudmigration.CreateAccessT
|
||||
|
||||
timeoutCtx, cancel = context.WithTimeout(ctx, s.cfg.CloudMigration.FetchAccessPolicyTimeout)
|
||||
defer cancel()
|
||||
existingAccessPolicy, err := s.findAccessPolicyByName(timeoutCtx, instance.RegionSlug, accessPolicyName)
|
||||
existingAccessPolicy, err := s.findAccessPolicyByName(timeoutCtx, accessPolicyName, instance.RegionSlug)
|
||||
if err != nil {
|
||||
return cloudmigration.CreateAccessTokenResponse{}, fmt.Errorf("fetching access policy by name: name=%s %w", accessPolicyName, err)
|
||||
}
|
||||
@@ -239,7 +256,7 @@ func (s *Service) CreateToken(ctx context.Context) (cloudmigration.CreateAccessT
|
||||
if existingAccessPolicy != nil {
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, s.cfg.CloudMigration.DeleteAccessPolicyTimeout)
|
||||
defer cancel()
|
||||
if _, err := s.gcomService.DeleteAccessPolicy(timeoutCtx, gcom.DeleteAccessPolicyParams{
|
||||
if _, err := s.authApiService.DeleteAccessPolicy(timeoutCtx, authapi.DeleteAccessPolicyParams{
|
||||
RequestID: requestID,
|
||||
AccessPolicyID: existingAccessPolicy.ID,
|
||||
Region: instance.RegionSlug,
|
||||
@@ -251,15 +268,15 @@ func (s *Service) CreateToken(ctx context.Context) (cloudmigration.CreateAccessT
|
||||
|
||||
timeoutCtx, cancel = context.WithTimeout(ctx, s.cfg.CloudMigration.CreateAccessPolicyTimeout)
|
||||
defer cancel()
|
||||
accessPolicy, err := s.gcomService.CreateAccessPolicy(timeoutCtx,
|
||||
gcom.CreateAccessPolicyParams{
|
||||
accessPolicy, err := s.authApiService.CreateAccessPolicy(timeoutCtx,
|
||||
authapi.CreateAccessPolicyParams{
|
||||
RequestID: requestID,
|
||||
Region: instance.RegionSlug,
|
||||
},
|
||||
gcom.CreateAccessPolicyPayload{
|
||||
authapi.CreateAccessPolicyPayload{
|
||||
Name: accessPolicyName,
|
||||
DisplayName: accessPolicyDisplayName,
|
||||
Realms: []gcom.Realm{{Type: "stack", Identifier: s.cfg.StackID, LabelPolicies: []gcom.LabelPolicy{}}},
|
||||
Realms: []authapi.Realm{{Type: "stack", Identifier: s.cfg.StackID, LabelPolicies: []authapi.LabelPolicy{}}},
|
||||
Scopes: []string{"cloud-migrations:read", "cloud-migrations:write"},
|
||||
})
|
||||
if err != nil {
|
||||
@@ -273,9 +290,12 @@ func (s *Service) CreateToken(ctx context.Context) (cloudmigration.CreateAccessT
|
||||
timeoutCtx, cancel = context.WithTimeout(ctx, s.cfg.CloudMigration.CreateTokenTimeout)
|
||||
defer cancel()
|
||||
|
||||
token, err := s.gcomService.CreateToken(timeoutCtx,
|
||||
gcom.CreateTokenParams{RequestID: requestID, Region: instance.RegionSlug},
|
||||
gcom.CreateTokenPayload{
|
||||
token, err := s.authApiService.CreateToken(timeoutCtx,
|
||||
authapi.CreateTokenParams{
|
||||
RequestID: requestID,
|
||||
Region: instance.RegionSlug,
|
||||
},
|
||||
authapi.CreateTokenPayload{
|
||||
AccessPolicyID: accessPolicy.ID,
|
||||
Name: accessTokenName,
|
||||
DisplayName: accessTokenDisplayName,
|
||||
@@ -303,14 +323,14 @@ func (s *Service) CreateToken(ctx context.Context) (cloudmigration.CreateAccessT
|
||||
return cloudmigration.CreateAccessTokenResponse{Token: base64.StdEncoding.EncodeToString(bytes)}, nil
|
||||
}
|
||||
|
||||
func (s *Service) findAccessPolicyByName(ctx context.Context, regionSlug, accessPolicyName string) (*gcom.AccessPolicy, error) {
|
||||
accessPolicies, err := s.gcomService.ListAccessPolicies(ctx, gcom.ListAccessPoliciesParams{
|
||||
func (s *Service) findAccessPolicyByName(ctx context.Context, accessPolicyName string, region string) (*authapi.AccessPolicy, error) {
|
||||
accessPolicies, err := s.authApiService.ListAccessPolicies(ctx, authapi.ListAccessPoliciesParams{
|
||||
RequestID: tracing.TraceIDFromContext(ctx, false),
|
||||
Region: regionSlug,
|
||||
Name: accessPolicyName,
|
||||
Region: region,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing access policies: name=%s region=%s :%w", accessPolicyName, regionSlug, err)
|
||||
return nil, fmt.Errorf("listing access policies: name=%s :%w", accessPolicyName, err)
|
||||
}
|
||||
|
||||
for _, accessPolicy := range accessPolicies {
|
||||
@@ -349,10 +369,10 @@ func (s *Service) DeleteToken(ctx context.Context, tokenID string) error {
|
||||
|
||||
timeoutCtx, cancel = context.WithTimeout(ctx, s.cfg.CloudMigration.DeleteTokenTimeout)
|
||||
defer cancel()
|
||||
if err := s.gcomService.DeleteToken(timeoutCtx, gcom.DeleteTokenParams{
|
||||
if err := s.authApiService.DeleteToken(timeoutCtx, authapi.DeleteTokenParams{
|
||||
RequestID: tracing.TraceIDFromContext(ctx, false),
|
||||
Region: instance.RegionSlug,
|
||||
TokenID: tokenID,
|
||||
Region: instance.RegionSlug,
|
||||
}); err != nil && !errors.Is(err, gcom.ErrTokenNotFound) {
|
||||
return fmt.Errorf("deleting cloud migration token: tokenID=%s %w", tokenID, err)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package cloudmigrationimpl
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/authapi"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/grafana/grafana/pkg/services/gcom"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
@@ -13,8 +13,8 @@ type NoopServiceImpl struct{}
|
||||
|
||||
var _ cloudmigration.Service = (*NoopServiceImpl)(nil)
|
||||
|
||||
func (s *NoopServiceImpl) GetToken(ctx context.Context) (gcom.TokenView, error) {
|
||||
return gcom.TokenView{}, cloudmigration.ErrFeatureDisabledError
|
||||
func (s *NoopServiceImpl) GetToken(ctx context.Context) (authapi.TokenView, error) {
|
||||
return authapi.TokenView{}, cloudmigration.ErrFeatureDisabledError
|
||||
}
|
||||
|
||||
func (s *NoopServiceImpl) CreateToken(ctx context.Context) (cloudmigration.CreateAccessTokenResponse, error) {
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/authapi"
|
||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||
"github.com/grafana/grafana/pkg/services/gcom"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
@@ -20,11 +20,11 @@ type FakeServiceImpl struct {
|
||||
|
||||
var _ cloudmigration.Service = (*FakeServiceImpl)(nil)
|
||||
|
||||
func (m FakeServiceImpl) GetToken(_ context.Context) (gcom.TokenView, error) {
|
||||
func (m FakeServiceImpl) GetToken(_ context.Context) (authapi.TokenView, error) {
|
||||
if m.ReturnError {
|
||||
return gcom.TokenView{}, fmt.Errorf("mock error")
|
||||
return authapi.TokenView{}, fmt.Errorf("mock error")
|
||||
}
|
||||
return gcom.TokenView{ID: "mock_id", DisplayName: "mock_name"}, nil
|
||||
return authapi.TokenView{ID: "mock_id", DisplayName: "mock_name"}, nil
|
||||
}
|
||||
|
||||
func (m FakeServiceImpl) CreateToken(_ context.Context) (cloudmigration.CreateAccessTokenResponse, error) {
|
||||
|
||||
@@ -6,16 +6,12 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/gcom"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
type gcomStub struct {
|
||||
// The cloud migration token created by this stub.
|
||||
token *gcom.TokenView
|
||||
policies map[string]gcom.AccessPolicy
|
||||
}
|
||||
|
||||
func (client *gcomStub) GetInstanceByID(ctx context.Context, requestID string, instanceID string) (gcom.Instance, error) {
|
||||
func (client *gcomStub) GetInstanceByID(_ context.Context, _ string, instanceID string) (gcom.Instance, error) {
|
||||
id, err := strconv.Atoi(instanceID)
|
||||
if err != nil {
|
||||
return gcom.Instance{}, fmt.Errorf("parsing instanceID: %w", err)
|
||||
@@ -27,55 +23,3 @@ func (client *gcomStub) GetInstanceByID(ctx context.Context, requestID string, i
|
||||
ClusterSlug: "fake-cluser",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client *gcomStub) CreateAccessPolicy(ctx context.Context, params gcom.CreateAccessPolicyParams, payload gcom.CreateAccessPolicyPayload) (gcom.AccessPolicy, error) {
|
||||
randStr := fmt.Sprintf("random-policy-%s", util.GenerateShortUID())
|
||||
policy := gcom.AccessPolicy{
|
||||
ID: randStr,
|
||||
Name: randStr,
|
||||
}
|
||||
client.policies[policy.ID] = policy
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
func (client *gcomStub) DeleteAccessPolicy(ctx context.Context, params gcom.DeleteAccessPolicyParams) (bool, error) {
|
||||
delete(client.policies, params.AccessPolicyID)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (client *gcomStub) ListAccessPolicies(ctx context.Context, params gcom.ListAccessPoliciesParams) ([]gcom.AccessPolicy, error) {
|
||||
items := make([]gcom.AccessPolicy, 0)
|
||||
for _, v := range client.policies {
|
||||
items = append(items, v)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (client *gcomStub) ListTokens(ctx context.Context, params gcom.ListTokenParams) ([]gcom.TokenView, error) {
|
||||
if client.token == nil {
|
||||
return []gcom.TokenView{}, nil
|
||||
}
|
||||
|
||||
return []gcom.TokenView{*client.token}, nil
|
||||
}
|
||||
|
||||
func (client *gcomStub) CreateToken(ctx context.Context, params gcom.CreateTokenParams, payload gcom.CreateTokenPayload) (gcom.Token, error) {
|
||||
token := gcom.Token{
|
||||
ID: fmt.Sprintf("random-token-%s", util.GenerateShortUID()),
|
||||
Name: payload.Name,
|
||||
AccessPolicyID: payload.AccessPolicyID,
|
||||
Token: fmt.Sprintf("completely_fake_token_%s", util.GenerateShortUID()),
|
||||
}
|
||||
client.token = &gcom.TokenView{
|
||||
ID: token.ID,
|
||||
Name: token.Name,
|
||||
AccessPolicyID: token.AccessPolicyID,
|
||||
DisplayName: token.Name,
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (client *gcomStub) DeleteToken(ctx context.Context, params gcom.DeleteTokenParams) error {
|
||||
client.token = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user