The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/tsdb/azuremonitor/azmoncredentials/builder.go

142 lines
3.9 KiB

package azmoncredentials
import (
"errors"
"fmt"
"github.com/grafana/grafana-azure-sdk-go/v2/azcredentials"
"github.com/grafana/grafana-azure-sdk-go/v2/azsettings"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data/utils/maputil"
)
func FromDatasourceData(data map[string]interface{}, secureData map[string]string) (azcredentials.AzureCredentials, error) {
var credentials azcredentials.AzureCredentials
var err error
credentials, err = azcredentials.FromDatasourceData(data, secureData)
if err != nil {
return nil, err
}
// Fallback to legacy credentials format
if credentials == nil {
credentials, err = getFromLegacy(data, secureData)
if err != nil {
return nil, err
}
}
return credentials, err
}
func getFromLegacy(data map[string]interface{}, secureData map[string]string) (azcredentials.AzureCredentials, error) {
authType, err := maputil.GetStringOptional(data, "azureAuthType")
if err != nil {
return nil, err
}
tenantId, err := maputil.GetStringOptional(data, "tenantId")
if err != nil {
return nil, err
}
clientId, err := maputil.GetStringOptional(data, "clientId")
if err != nil {
return nil, err
}
if authType == "" {
// Some very old legacy datasources may not have explicit auth type specified,
// but they imply App Registration authentication
if tenantId != "" && clientId != "" {
authType = azcredentials.AzureAuthClientSecret
} else {
// No configuration present
return nil, nil
}
}
switch authType {
case azcredentials.AzureAuthManagedIdentity:
credentials := &azcredentials.AzureManagedIdentityCredentials{}
return credentials, nil
case azcredentials.AzureAuthWorkloadIdentity:
credentials := &azcredentials.AzureWorkloadIdentityCredentials{}
return credentials, nil
case azcredentials.AzureAuthCurrentUserIdentity:
legacyCloud, err := maputil.GetStringOptional(data, "cloudName")
if err != nil {
return nil, err
}
cloud, err := resolveLegacyCloudName(legacyCloud)
if err != nil {
return nil, err
}
clientSecret := secureData["clientSecret"]
credentials := &azcredentials.AadCurrentUserCredentials{
ServiceCredentials: &azcredentials.AzureClientSecretCredentials{
AzureCloud: cloud,
TenantId: tenantId,
ClientId: clientId,
ClientSecret: clientSecret,
},
}
return credentials, nil
case azcredentials.AzureAuthClientSecret:
legacyCloud, err := maputil.GetStringOptional(data, "cloudName")
if err != nil {
return nil, err
}
cloud, err := resolveLegacyCloudName(legacyCloud)
if err != nil {
return nil, err
}
clientSecret := secureData["clientSecret"]
if secureData["clientSecret"] == "" {
return nil, backend.DownstreamError(errors.New("unable to instantiate credentials, clientSecret must be set"))
}
credentials := &azcredentials.AzureClientSecretCredentials{
AzureCloud: cloud,
TenantId: tenantId,
ClientId: clientId,
ClientSecret: clientSecret,
}
return credentials, nil
default:
err := fmt.Errorf("the authentication type '%s' not supported", authType)
return nil, err
}
}
// Legacy Azure cloud names used by the Azure Monitor datasource
const (
azureMonitorPublic = "azuremonitor"
azureMonitorChina = "chinaazuremonitor"
azureMonitorUSGovernment = "govazuremonitor"
azureMonitorCustomized = "customizedazuremonitor"
)
func resolveLegacyCloudName(cloudName string) (string, error) {
switch cloudName {
case azureMonitorPublic:
return azsettings.AzurePublic, nil
case azureMonitorChina:
return azsettings.AzureChina, nil
case azureMonitorUSGovernment:
return azsettings.AzureUSGovernment, nil
case azureMonitorCustomized:
return azsettings.AzureCustomized, nil
case "":
return azsettings.AzurePublic, nil
default:
err := fmt.Errorf("the Azure cloud '%s' not supported by Azure Monitor datasource", cloudName)
return "", err
}
}