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:
co-authored by
Marcus Efraimsson
parent
58b8d84085
commit
cb09162cde
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user