@@ -14,23 +14,18 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
"github.com/aws/aws-sdk-go/service/sts/stsiface"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
credential *credentials.Credentials
|
||||
expiration *time.Time
|
||||
type envelope struct {
|
||||
credentials *credentials.Credentials
|
||||
expiration *time.Time
|
||||
}
|
||||
|
||||
var awsCredentialCache = make(map[string]cache)
|
||||
var credentialCacheLock sync.RWMutex
|
||||
var awsCredsCache = map[string]envelope{}
|
||||
var credsCacheLock sync.RWMutex
|
||||
|
||||
// Session factory.
|
||||
// Stubbable by tests.
|
||||
@@ -50,18 +45,17 @@ var newEC2Metadata = func(p client.ConfigProvider, cfgs ...*aws.Config) *ec2meta
|
||||
return ec2metadata.New(p, cfgs...)
|
||||
}
|
||||
|
||||
func getCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
|
||||
func getCredentials(dsInfo *datasourceInfo) (*credentials.Credentials, error) {
|
||||
cacheKey := fmt.Sprintf("%s:%s:%s:%s", dsInfo.AuthType, dsInfo.AccessKey, dsInfo.Profile, dsInfo.AssumeRoleArn)
|
||||
credentialCacheLock.RLock()
|
||||
if _, ok := awsCredentialCache[cacheKey]; ok {
|
||||
if awsCredentialCache[cacheKey].expiration != nil &&
|
||||
awsCredentialCache[cacheKey].expiration.After(time.Now().UTC()) {
|
||||
result := awsCredentialCache[cacheKey].credential
|
||||
credentialCacheLock.RUnlock()
|
||||
credsCacheLock.RLock()
|
||||
if env, ok := awsCredsCache[cacheKey]; ok {
|
||||
if env.expiration != nil && env.expiration.After(time.Now().UTC()) {
|
||||
result := env.credentials
|
||||
credsCacheLock.RUnlock()
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
credentialCacheLock.RUnlock()
|
||||
credsCacheLock.RUnlock()
|
||||
|
||||
accessKeyID := ""
|
||||
secretAccessKey := ""
|
||||
@@ -135,12 +129,12 @@ func getCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
|
||||
remoteCredProvider(sess),
|
||||
})
|
||||
|
||||
credentialCacheLock.Lock()
|
||||
awsCredentialCache[cacheKey] = cache{
|
||||
credential: creds,
|
||||
expiration: expiration,
|
||||
credsCacheLock.Lock()
|
||||
awsCredsCache[cacheKey] = envelope{
|
||||
credentials: creds,
|
||||
expiration: expiration,
|
||||
}
|
||||
credentialCacheLock.Unlock()
|
||||
credsCacheLock.Unlock()
|
||||
|
||||
return creds, nil
|
||||
}
|
||||
@@ -178,37 +172,7 @@ func ec2RoleProvider(sess *session.Session) credentials.Provider {
|
||||
return &ec2rolecreds.EC2RoleProvider{Client: newEC2Metadata(sess), ExpiryWindow: 5 * time.Minute}
|
||||
}
|
||||
|
||||
func (e *CloudWatchExecutor) getDsInfo(region string) *DatasourceInfo {
|
||||
return retrieveDsInfo(e.DataSource, region)
|
||||
}
|
||||
|
||||
func retrieveDsInfo(datasource *models.DataSource, region string) *DatasourceInfo {
|
||||
defaultRegion := datasource.JsonData.Get("defaultRegion").MustString()
|
||||
if region == "default" {
|
||||
region = defaultRegion
|
||||
}
|
||||
|
||||
authType := datasource.JsonData.Get("authType").MustString()
|
||||
assumeRoleArn := datasource.JsonData.Get("assumeRoleArn").MustString()
|
||||
externalID := datasource.JsonData.Get("externalId").MustString()
|
||||
decrypted := datasource.DecryptedValues()
|
||||
accessKey := decrypted["accessKey"]
|
||||
secretKey := decrypted["secretKey"]
|
||||
|
||||
datasourceInfo := &DatasourceInfo{
|
||||
Region: region,
|
||||
Profile: datasource.Database,
|
||||
AuthType: authType,
|
||||
AssumeRoleArn: assumeRoleArn,
|
||||
ExternalID: externalID,
|
||||
AccessKey: accessKey,
|
||||
SecretKey: secretKey,
|
||||
}
|
||||
|
||||
return datasourceInfo
|
||||
}
|
||||
|
||||
func getAwsConfig(dsInfo *DatasourceInfo) (*aws.Config, error) {
|
||||
func getAwsConfig(dsInfo *datasourceInfo) (*aws.Config, error) {
|
||||
creds, err := getCredentials(dsInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -221,44 +185,3 @@ func getAwsConfig(dsInfo *DatasourceInfo) (*aws.Config, error) {
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (e *CloudWatchExecutor) getClient(region string) (*cloudwatch.CloudWatch, error) {
|
||||
datasourceInfo := e.getDsInfo(region)
|
||||
cfg, err := getAwsConfig(datasourceInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sess, err := newSession(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := cloudwatch.New(sess, cfg)
|
||||
|
||||
client.Handlers.Send.PushFront(func(r *request.Request) {
|
||||
r.HTTPRequest.Header.Set("User-Agent", fmt.Sprintf("Grafana/%s", setting.BuildVersion))
|
||||
})
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func retrieveLogsClient(datasourceInfo *DatasourceInfo) (*cloudwatchlogs.CloudWatchLogs, error) {
|
||||
cfg, err := getAwsConfig(datasourceInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sess, err := newSession(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := cloudwatchlogs.New(sess, cfg)
|
||||
|
||||
client.Handlers.Send.PushFront(func(r *request.Request) {
|
||||
r.HTTPRequest.Header.Set("User-Agent", fmt.Sprintf("Grafana/%s", setting.BuildVersion))
|
||||
})
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user