mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 11:20:27 -06:00
b7adf28501
This commit fixes the following golint warnings: pkg/api/avatar/avatar.go:229:12: should omit type *http.Client from declaration of var client; it will be inferred from the right-hand side pkg/login/brute_force_login_protection.go:13:26: should omit type time.Duration from declaration of var loginAttemptsWindow; it will be inferred from the right-hand side pkg/metrics/graphitebridge/graphite.go:58:26: should omit type []string from declaration of var metricCategoryPrefix; it will be inferred from the right-hand side pkg/metrics/graphitebridge/graphite.go:69:22: should omit type []string from declaration of var trimMetricPrefix; it will be inferred from the right-hand side pkg/models/alert.go:37:36: should omit type error from declaration of var ErrCannotChangeStateOnPausedAlert; it will be inferred from the right-hand side pkg/models/alert.go:38:36: should omit type error from declaration of var ErrRequiresNewState; it will be inferred from the right-hand side pkg/models/datasource.go:61:28: should omit type map[string]bool from declaration of var knownDatasourcePlugins; it will be inferred from the right-hand side pkg/plugins/update_checker.go:16:13: should omit type http.Client from declaration of var httpClient; it will be inferred from the right-hand side pkg/services/alerting/engine.go:103:24: should omit type time.Duration from declaration of var unfinishedWorkTimeout; it will be inferred from the right-hand side pkg/services/alerting/engine.go:105:19: should omit type time.Duration from declaration of var alertTimeout; it will be inferred from the right-hand side pkg/services/alerting/engine.go:106:19: should omit type int from declaration of var alertMaxAttempts; it will be inferred from the right-hand side pkg/services/alerting/notifier.go:143:23: should omit type map[string]*NotifierPlugin from declaration of var notifierFactories; it will be inferred from the right-hand side pkg/services/alerting/rule.go:136:24: should omit type map[string]ConditionFactory from declaration of var conditionFactories; it will be inferred from the right-hand side pkg/services/alerting/conditions/evaluator.go:12:15: should omit type []string from declaration of var defaultTypes; it will be inferred from the right-hand side pkg/services/alerting/conditions/evaluator.go:13:15: should omit type []string from declaration of var rangedTypes; it will be inferred from the right-hand side pkg/services/alerting/notifiers/opsgenie.go:44:19: should omit type string from declaration of var opsgenieAlertURL; it will be inferred from the right-hand side pkg/services/alerting/notifiers/pagerduty.go:43:23: should omit type string from declaration of var pagerdutyEventApiUrl; it will be inferred from the right-hand side pkg/services/alerting/notifiers/telegram.go:21:17: should omit type string from declaration of var telegramApiUrl; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/config_reader_test.go:11:24: should omit type string from declaration of var simpleDashboardConfig; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/config_reader_test.go:12:24: should omit type string from declaration of var oldVersion; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/config_reader_test.go:13:24: should omit type string from declaration of var brokenConfigs; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/file_reader.go:22:30: should omit type time.Duration from declaration of var checkDiskForChangesInterval; it will be inferred from the right-hand side pkg/services/provisioning/dashboards/file_reader.go:24:23: should omit type error from declaration of var ErrFolderNameMissing; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:15:34: should omit type string from declaration of var twoDatasourcesConfig; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:16:34: should omit type string from declaration of var twoDatasourcesConfigPurgeOthers; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:17:34: should omit type string from declaration of var doubleDatasourcesConfig; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:18:34: should omit type string from declaration of var allProperties; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:19:34: should omit type string from declaration of var versionZero; it will be inferred from the right-hand side pkg/services/provisioning/datasources/config_reader_test.go:20:34: should omit type string from declaration of var brokenYaml; it will be inferred from the right-hand side pkg/services/sqlstore/stats.go:16:25: should omit type time.Duration from declaration of var activeUserTimeLimit; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/mysql_dialect.go:69:14: should omit type bool from declaration of var hasLen1; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/mysql_dialect.go:70:14: should omit type bool from declaration of var hasLen2; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/postgres_dialect.go:95:14: should omit type bool from declaration of var hasLen1; it will be inferred from the right-hand side pkg/services/sqlstore/migrator/postgres_dialect.go:96:14: should omit type bool from declaration of var hasLen2; it will be inferred from the right-hand side pkg/setting/setting.go:42:15: should omit type string from declaration of var Env; it will be inferred from the right-hand side pkg/setting/setting.go:161:18: should omit type bool from declaration of var LdapAllowSignup; it will be inferred from the right-hand side pkg/setting/setting.go:473:30: should omit type bool from declaration of var skipStaticRootValidation; it will be inferred from the right-hand side pkg/tsdb/interval.go:14:21: should omit type time.Duration from declaration of var defaultMinInterval; it will be inferred from the right-hand side pkg/tsdb/interval.go:15:21: should omit type time.Duration from declaration of var year; it will be inferred from the right-hand side pkg/tsdb/interval.go:16:21: should omit type time.Duration from declaration of var day; it will be inferred from the right-hand side pkg/tsdb/cloudwatch/credentials.go:26:24: should omit type map[string]cache from declaration of var awsCredentialCache; it will be inferred from the right-hand side pkg/tsdb/influxdb/query.go:15:27: should omit type *regexp.Regexp from declaration of var regexpOperatorPattern; it will be inferred from the right-hand side pkg/tsdb/influxdb/query.go:16:27: should omit type *regexp.Regexp from declaration of var regexpMeasurementPattern; it will be inferred from the right-hand side pkg/tsdb/mssql/mssql_test.go:25:14: should omit type string from declaration of var serverIP; it will be inferred from the right-hand side
203 lines
5.3 KiB
Go
203 lines
5.3 KiB
Go
package cloudwatch
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
|
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
|
"github.com/aws/aws-sdk-go/aws/defaults"
|
|
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
|
"github.com/aws/aws-sdk-go/service/sts"
|
|
)
|
|
|
|
type cache struct {
|
|
credential *credentials.Credentials
|
|
expiration *time.Time
|
|
}
|
|
|
|
var awsCredentialCache = make(map[string]cache)
|
|
var credentialCacheLock sync.RWMutex
|
|
|
|
func GetCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
|
|
cacheKey := 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()
|
|
return result, nil
|
|
}
|
|
}
|
|
credentialCacheLock.RUnlock()
|
|
|
|
accessKeyId := ""
|
|
secretAccessKey := ""
|
|
sessionToken := ""
|
|
var expiration *time.Time
|
|
expiration = nil
|
|
if dsInfo.AuthType == "arn" && strings.Index(dsInfo.AssumeRoleArn, "arn:aws:iam:") == 0 {
|
|
params := &sts.AssumeRoleInput{
|
|
RoleArn: aws.String(dsInfo.AssumeRoleArn),
|
|
RoleSessionName: aws.String("GrafanaSession"),
|
|
DurationSeconds: aws.Int64(900),
|
|
}
|
|
|
|
stsSess, err := session.NewSession()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stsCreds := credentials.NewChainCredentials(
|
|
[]credentials.Provider{
|
|
&credentials.EnvProvider{},
|
|
&credentials.SharedCredentialsProvider{Filename: "", Profile: dsInfo.Profile},
|
|
remoteCredProvider(stsSess),
|
|
})
|
|
stsConfig := &aws.Config{
|
|
Region: aws.String(dsInfo.Region),
|
|
Credentials: stsCreds,
|
|
}
|
|
|
|
sess, err := session.NewSession(stsConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
svc := sts.New(sess, stsConfig)
|
|
resp, err := svc.AssumeRole(params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if resp.Credentials != nil {
|
|
accessKeyId = *resp.Credentials.AccessKeyId
|
|
secretAccessKey = *resp.Credentials.SecretAccessKey
|
|
sessionToken = *resp.Credentials.SessionToken
|
|
expiration = resp.Credentials.Expiration
|
|
}
|
|
} else {
|
|
now := time.Now()
|
|
e := now.Add(5 * time.Minute)
|
|
expiration = &e
|
|
}
|
|
|
|
sess, err := session.NewSession()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
creds := credentials.NewChainCredentials(
|
|
[]credentials.Provider{
|
|
&credentials.StaticProvider{Value: credentials.Value{
|
|
AccessKeyID: accessKeyId,
|
|
SecretAccessKey: secretAccessKey,
|
|
SessionToken: sessionToken,
|
|
}},
|
|
&credentials.EnvProvider{},
|
|
&credentials.StaticProvider{Value: credentials.Value{
|
|
AccessKeyID: dsInfo.AccessKey,
|
|
SecretAccessKey: dsInfo.SecretKey,
|
|
}},
|
|
&credentials.SharedCredentialsProvider{Filename: "", Profile: dsInfo.Profile},
|
|
remoteCredProvider(sess),
|
|
})
|
|
|
|
credentialCacheLock.Lock()
|
|
awsCredentialCache[cacheKey] = cache{
|
|
credential: creds,
|
|
expiration: expiration,
|
|
}
|
|
credentialCacheLock.Unlock()
|
|
|
|
return creds, nil
|
|
}
|
|
|
|
func remoteCredProvider(sess *session.Session) credentials.Provider {
|
|
ecsCredURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")
|
|
|
|
if len(ecsCredURI) > 0 {
|
|
return ecsCredProvider(sess, ecsCredURI)
|
|
}
|
|
return ec2RoleProvider(sess)
|
|
}
|
|
|
|
func ecsCredProvider(sess *session.Session, uri string) credentials.Provider {
|
|
const host = `169.254.170.2`
|
|
|
|
d := defaults.Get()
|
|
return endpointcreds.NewProviderClient(
|
|
*d.Config,
|
|
d.Handlers,
|
|
fmt.Sprintf("http://%s%s", host, uri),
|
|
func(p *endpointcreds.Provider) { p.ExpiryWindow = 5 * time.Minute })
|
|
}
|
|
|
|
func ec2RoleProvider(sess *session.Session) credentials.Provider {
|
|
return &ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute}
|
|
}
|
|
|
|
func (e *CloudWatchExecutor) getDsInfo(region string) *DatasourceInfo {
|
|
defaultRegion := e.DataSource.JsonData.Get("defaultRegion").MustString()
|
|
if region == "default" {
|
|
region = defaultRegion
|
|
}
|
|
|
|
authType := e.DataSource.JsonData.Get("authType").MustString()
|
|
assumeRoleArn := e.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
|
accessKey := ""
|
|
secretKey := ""
|
|
for key, value := range e.DataSource.SecureJsonData.Decrypt() {
|
|
if key == "accessKey" {
|
|
accessKey = value
|
|
}
|
|
if key == "secretKey" {
|
|
secretKey = value
|
|
}
|
|
}
|
|
|
|
datasourceInfo := &DatasourceInfo{
|
|
Region: region,
|
|
Profile: e.DataSource.Database,
|
|
AuthType: authType,
|
|
AssumeRoleArn: assumeRoleArn,
|
|
AccessKey: accessKey,
|
|
SecretKey: secretKey,
|
|
}
|
|
|
|
return datasourceInfo
|
|
}
|
|
|
|
func (e *CloudWatchExecutor) getAwsConfig(dsInfo *DatasourceInfo) (*aws.Config, error) {
|
|
creds, err := GetCredentials(dsInfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cfg := &aws.Config{
|
|
Region: aws.String(dsInfo.Region),
|
|
Credentials: creds,
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func (e *CloudWatchExecutor) getClient(region string) (*cloudwatch.CloudWatch, error) {
|
|
datasourceInfo := e.getDsInfo(region)
|
|
cfg, err := e.getAwsConfig(datasourceInfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sess, err := session.NewSession(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client := cloudwatch.New(sess, cfg)
|
|
return client, nil
|
|
}
|