Datasources: Simplify the AzureCredentials structure in datasource config (#39209)

Related #35857

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
Sergey Kostrukov
2022-01-25 14:23:32 +01:00
committed by GitHub
co-authored by Marcus Efraimsson
parent 58b8d84085
commit cb09162cde
7 changed files with 68 additions and 92 deletions
@@ -16,17 +16,11 @@ const azureMiddlewareName = "AzureAuthentication.Provider"
func AzureMiddleware(cfg *setting.Cfg) httpclient.Middleware {
return httpclient.NamedMiddlewareFunc(azureMiddlewareName, func(opts httpclient.Options, next http.RoundTripper) http.RoundTripper {
if enabled, err := isAzureAuthenticationEnabled(opts.CustomOptions); err != nil {
return errorResponse(err)
} else if !enabled {
return next
}
credentials, err := getAzureCredentials(opts.CustomOptions)
if err != nil {
return errorResponse(err)
} else if credentials == nil {
credentials = getDefaultAzureCredentials(cfg)
return next
}
tokenProvider, err := aztokenprovider.NewAzureAccessTokenProvider(cfg, credentials)
@@ -49,17 +43,6 @@ func errorResponse(err error) http.RoundTripper {
})
}
func isAzureAuthenticationEnabled(customOptions map[string]interface{}) (bool, error) {
if untypedValue, ok := customOptions["_azureAuth"]; !ok {
return false, nil
} else if value, ok := untypedValue.(bool); !ok {
err := fmt.Errorf("the field 'azureAuth' should be a bool")
return false, err
} else {
return value, nil
}
}
func getAzureCredentials(customOptions map[string]interface{}) (azcredentials.AzureCredentials, error) {
if untypedValue, ok := customOptions["_azureCredentials"]; !ok {
return nil, nil
@@ -71,16 +54,6 @@ func getAzureCredentials(customOptions map[string]interface{}) (azcredentials.Az
}
}
func getDefaultAzureCredentials(cfg *setting.Cfg) azcredentials.AzureCredentials {
if cfg.Azure.ManagedIdentityEnabled {
return &azcredentials.AzureManagedIdentityCredentials{}
} else {
return &azcredentials.AzureClientSecretCredentials{
AzureCloud: cfg.Azure.Cloud,
}
}
}
func getAzureEndpointResourceId(customOptions map[string]interface{}) (*url.URL, error) {
var value string
if untypedValue, ok := customOptions["azureEndpointResourceId"]; !ok {
+1 -2
View File
@@ -277,14 +277,13 @@ func (s *Service) httpClientOptions(ds *models.DataSource) (*sdkhttpclient.Optio
}
}
if ds.JsonData != nil && ds.JsonData.Get("azureAuth").MustBool() {
if ds.JsonData != nil {
credentials, err := azcredentials.FromDatasourceData(ds.JsonData.MustMap(), s.DecryptedValues(ds))
if err != nil {
err = fmt.Errorf("invalid Azure credentials: %s", err)
return nil, err
}
opts.CustomOptions["_azureAuth"] = true
if credentials != nil {
opts.CustomOptions["_azureCredentials"] = credentials
}
+2 -44
View File
@@ -570,7 +570,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
}
t.Run("Azure authentication", func(t *testing.T) {
t.Run("should be disabled if not enabled in JsonData", func(t *testing.T) {
t.Run("should be disabled if no Azure credentials configured", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
@@ -579,32 +579,13 @@ func TestService_HTTPClientOptions(t *testing.T) {
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)
assert.NotEqual(t, true, opts.CustomOptions["_azureAuth"])
assert.NotContains(t, opts.CustomOptions, "_azureCredentials")
})
t.Run("should be enabled if enabled in JsonData without credentials configured", func(t *testing.T) {
t.Run("should be enabled if Azure credentials configured", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"azureAuth": true,
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, &acmock.Mock{})
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)
assert.Equal(t, true, opts.CustomOptions["_azureAuth"])
assert.NotContains(t, opts.CustomOptions, "_azureCredentials")
})
t.Run("should be enabled if enabled in JsonData with credentials configured", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"azureAuth": true,
"azureCredentials": map[string]interface{}{
"authType": "msi",
},
@@ -616,39 +597,16 @@ func TestService_HTTPClientOptions(t *testing.T) {
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)
assert.Equal(t, true, opts.CustomOptions["_azureAuth"])
require.Contains(t, opts.CustomOptions, "_azureCredentials")
credentials := opts.CustomOptions["_azureCredentials"]
assert.IsType(t, &azcredentials.AzureManagedIdentityCredentials{}, credentials)
})
t.Run("should be disabled if disabled in JsonData even with credentials configured", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"azureAuth": false,
"azureCredentials": map[string]interface{}{
"authType": "msi",
},
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, &acmock.Mock{})
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)
assert.NotEqual(t, true, opts.CustomOptions["_azureAuth"])
assert.NotContains(t, opts.CustomOptions, "_azureCredentials")
})
t.Run("should fail if credentials are invalid", func(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
ds.JsonData = simplejson.NewFromAny(map[string]interface{}{
"azureAuth": true,
"azureCredentials": "invalid",
})