Prometheus: Remove Azure code from datasource service (#50737)

Ref #35857
This commit is contained in:
Sergey Kostrukov 2022-06-14 01:47:06 -07:00 committed by GitHub
parent 701edcdc46
commit 2d3cc26aa8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 8 additions and 200 deletions

View File

@ -11,8 +11,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/grafana/grafana-azure-sdk-go/azcredentials"
"github.com/grafana/grafana-azure-sdk-go/azhttpclient"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
@ -25,7 +23,6 @@ import (
"github.com/grafana/grafana/pkg/services/secrets/kvstore" "github.com/grafana/grafana/pkg/services/secrets/kvstore"
"github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/prometheus/buffered/promclient"
) )
type Service struct { type Service struct {
@ -410,31 +407,6 @@ func (s *Service) httpClientOptions(ctx context.Context, ds *models.DataSource)
} }
} }
// TODO: #35857 Required for templating queries in Prometheus datasource when Azure authentication enabled
if ds.JsonData != nil && s.features.IsEnabled(featuremgmt.FlagPrometheusAzureAuth) {
credentials, err := azcredentials.FromDatasourceData(ds.JsonData.MustMap(), decryptedValues)
if err != nil {
err = fmt.Errorf("invalid Azure credentials: %s", err)
return nil, err
}
if credentials != nil {
var scopes []string
if scopes, err = promclient.GetOverriddenScopes(ds.JsonData.MustMap()); err != nil {
return nil, err
}
if scopes == nil {
if scopes, err = promclient.GetPrometheusScopes(s.cfg.Azure, credentials); err != nil {
return nil, err
}
}
azhttpclient.AddAzureAuthentication(opts, s.cfg.Azure, credentials, scopes)
}
}
if ds.JsonData != nil && ds.JsonData.Get("sigV4Auth").MustBool(false) && setting.SigV4AuthEnabled { if ds.JsonData != nil && ds.JsonData.Get("sigV4Auth").MustBool(false) && setting.SigV4AuthEnabled {
opts.SigV4 = &sdkhttpclient.SigV4Config{ opts.SigV4 = &sdkhttpclient.SigV4Config{
Service: awsServiceNamespace(ds.Type), Service: awsServiceNamespace(ds.Type),

View File

@ -9,7 +9,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/grafana/grafana-azure-sdk-go/azsettings"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/secrets"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
@ -545,169 +544,6 @@ func TestService_getTimeout(t *testing.T) {
} }
} }
func TestService_HTTPClientOptions(t *testing.T) {
cfg := &setting.Cfg{
Azure: &azsettings.AzureSettings{},
}
emptyJsonData := simplejson.New()
emptySecureJsonData := map[string][]byte{}
ds := models.DataSource{
Id: 1,
Url: "https://api.example.com",
Type: "prometheus",
}
t.Run("Azure authentication", func(t *testing.T) {
t.Run("given feature flag enabled", func(t *testing.T) {
features := featuremgmt.WithFeatures(featuremgmt.FlagPrometheusAzureAuth)
t.Run("should set Azure middleware when JsonData contains valid credentials", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
"azureCredentials": map[string]interface{}{
"authType": "msi",
},
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
require.NotNil(t, opts.Middlewares)
assert.Len(t, opts.Middlewares, 1)
})
t.Run("should not set Azure middleware when JsonData doesn't contain valid credentials", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
if opts.Middlewares != nil {
assert.Len(t, opts.Middlewares, 0)
}
})
t.Run("should return error when JsonData contains invalid credentials", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
"azureCredentials": "invalid",
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
_, err := dsService.httpClientOptions(context.Background(), &ds)
assert.Error(t, err)
})
t.Run("should set Azure middleware when JsonData contains credentials and valid audience", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
"azureCredentials": map[string]interface{}{
"authType": "msi",
},
"azureEndpointResourceId": "https://api.example.com/abd5c4ce-ca73-41e9-9cb2-bed39aa2adb5",
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
require.NotNil(t, opts.Middlewares)
assert.Len(t, opts.Middlewares, 1)
})
t.Run("should not set Azure middleware when JsonData doesn't contain credentials", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
"azureEndpointResourceId": "https://api.example.com/abd5c4ce-ca73-41e9-9cb2-bed39aa2adb5",
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
if opts.Middlewares != nil {
assert.Len(t, opts.Middlewares, 0)
}
})
t.Run("should return error when JsonData contains invalid audience", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
"azureCredentials": map[string]interface{}{
"authType": "msi",
},
"azureEndpointResourceId": "invalid",
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService())
_, err := dsService.httpClientOptions(context.Background(), &ds)
assert.Error(t, err)
})
})
t.Run("given feature flag not enabled", func(t *testing.T) {
t.Run("should not set Azure middleware even when JsonData contains credentials", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"httpMethod": "POST",
"azureCredentials": map[string]interface{}{
"authType": "msi",
},
"azureEndpointResourceId": "https://api.example.com/abd5c4ce-ca73-41e9-9cb2-bed39aa2adb5",
})
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
opts, err := dsService.httpClientOptions(context.Background(), &ds)
require.NoError(t, err)
if opts.Middlewares != nil {
assert.Len(t, opts.Middlewares, 0)
}
})
})
})
}
func TestService_GetDecryptedValues(t *testing.T) { func TestService_GetDecryptedValues(t *testing.T) {
t.Run("should migrate and retrieve values from secure json data", func(t *testing.T) { t.Run("should migrate and retrieve values from secure json data", func(t *testing.T) {
ds := &models.DataSource{ ds := &models.DataSource{

View File

@ -37,12 +37,12 @@ func (p *Provider) configureAzureAuthentication(opts *sdkhttpclient.Options) err
if credentials != nil { if credentials != nil {
var scopes []string var scopes []string
if scopes, err = GetOverriddenScopes(p.jsonData); err != nil { if scopes, err = getOverriddenScopes(p.jsonData); err != nil {
return err return err
} }
if scopes == nil { if scopes == nil {
if scopes, err = GetPrometheusScopes(p.cfg.Azure, credentials); err != nil { if scopes, err = getPrometheusScopes(p.cfg.Azure, credentials); err != nil {
return err return err
} }
} }
@ -53,7 +53,7 @@ func (p *Provider) configureAzureAuthentication(opts *sdkhttpclient.Options) err
return nil return nil
} }
func GetOverriddenScopes(jsonData map[string]interface{}) ([]string, error) { func getOverriddenScopes(jsonData map[string]interface{}) ([]string, error) {
resourceIdStr, err := maputil.GetStringOptional(jsonData, "azureEndpointResourceId") resourceIdStr, err := maputil.GetStringOptional(jsonData, "azureEndpointResourceId")
if err != nil { if err != nil {
err = fmt.Errorf("overridden resource ID (audience) invalid") err = fmt.Errorf("overridden resource ID (audience) invalid")
@ -73,7 +73,7 @@ func GetOverriddenScopes(jsonData map[string]interface{}) ([]string, error) {
return scopes, nil return scopes, nil
} }
func GetPrometheusScopes(settings *azsettings.AzureSettings, credentials azcredentials.AzureCredentials) ([]string, error) { func getPrometheusScopes(settings *azsettings.AzureSettings, credentials azcredentials.AzureCredentials) ([]string, error) {
// Extract cloud from credentials // Extract cloud from credentials
azureCloud, err := getAzureCloudFromCredentials(settings, credentials) azureCloud, err := getAzureCloudFromCredentials(settings, credentials)
if err != nil { if err != nil {

View File

@ -37,12 +37,12 @@ func (p *Provider) configureAzureAuthentication(opts *sdkhttpclient.Options) err
if credentials != nil { if credentials != nil {
var scopes []string var scopes []string
if scopes, err = GetOverriddenScopes(p.jsonData); err != nil { if scopes, err = getOverriddenScopes(p.jsonData); err != nil {
return err return err
} }
if scopes == nil { if scopes == nil {
if scopes, err = GetPrometheusScopes(p.cfg.Azure, credentials); err != nil { if scopes, err = getPrometheusScopes(p.cfg.Azure, credentials); err != nil {
return err return err
} }
} }
@ -53,7 +53,7 @@ func (p *Provider) configureAzureAuthentication(opts *sdkhttpclient.Options) err
return nil return nil
} }
func GetOverriddenScopes(jsonData map[string]interface{}) ([]string, error) { func getOverriddenScopes(jsonData map[string]interface{}) ([]string, error) {
resourceIdStr, err := maputil.GetStringOptional(jsonData, "azureEndpointResourceId") resourceIdStr, err := maputil.GetStringOptional(jsonData, "azureEndpointResourceId")
if err != nil { if err != nil {
err = fmt.Errorf("overridden resource ID (audience) invalid") err = fmt.Errorf("overridden resource ID (audience) invalid")
@ -73,7 +73,7 @@ func GetOverriddenScopes(jsonData map[string]interface{}) ([]string, error) {
return scopes, nil return scopes, nil
} }
func GetPrometheusScopes(settings *azsettings.AzureSettings, credentials azcredentials.AzureCredentials) ([]string, error) { func getPrometheusScopes(settings *azsettings.AzureSettings, credentials azcredentials.AzureCredentials) ([]string, error) {
// Extract cloud from credentials // Extract cloud from credentials
azureCloud, err := getAzureCloudFromCredentials(settings, credentials) azureCloud, err := getAzureCloudFromCredentials(settings, credentials)
if err != nil { if err != nil {