mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
(cloudwatch) assume role support (#5065)
* (cloudwatch) assume role support * save godep * (cloudwatch) add assumeRoleArn field * (cloudwatch) set cred provider for sts * (cloudwatch) fix test
This commit is contained in:
committed by
Torkel Ödegaard
parent
fc1891320e
commit
07d355851e
5
Godeps/Godeps.json
generated
5
Godeps/Godeps.json
generated
@@ -124,6 +124,11 @@
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/sts",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bmizerany/assert",
|
||||
"Comment": "release.r60-6-ge17e998",
|
||||
|
||||
1127
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/api.go
generated
vendored
Normal file
1127
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/api.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations.go
generated
vendored
Normal file
12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
package sts
|
||||
|
||||
import "github.com/aws/aws-sdk-go/aws/request"
|
||||
|
||||
func init() {
|
||||
initRequest = func(r *request.Request) {
|
||||
switch r.Operation.Name {
|
||||
case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity:
|
||||
r.Handlers.Sign.Clear() // these operations are unsigned
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations_test.go
generated
vendored
Normal file
39
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations_test.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package sts_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
var svc = sts.New(unit.Session, &aws.Config{
|
||||
Region: aws.String("mock-region"),
|
||||
})
|
||||
|
||||
func TestUnsignedRequest_AssumeRoleWithSAML(t *testing.T) {
|
||||
req, _ := svc.AssumeRoleWithSAMLRequest(&sts.AssumeRoleWithSAMLInput{
|
||||
PrincipalArn: aws.String("ARN01234567890123456789"),
|
||||
RoleArn: aws.String("ARN01234567890123456789"),
|
||||
SAMLAssertion: aws.String("ASSERT"),
|
||||
})
|
||||
|
||||
err := req.Sign()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "", req.HTTPRequest.Header.Get("Authorization"))
|
||||
}
|
||||
|
||||
func TestUnsignedRequest_AssumeRoleWithWebIdentity(t *testing.T) {
|
||||
req, _ := svc.AssumeRoleWithWebIdentityRequest(&sts.AssumeRoleWithWebIdentityInput{
|
||||
RoleArn: aws.String("ARN01234567890123456789"),
|
||||
RoleSessionName: aws.String("SESSION"),
|
||||
WebIdentityToken: aws.String("TOKEN"),
|
||||
})
|
||||
|
||||
err := req.Sign()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "", req.HTTPRequest.Header.Get("Authorization"))
|
||||
}
|
||||
149
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/examples_test.go
generated
vendored
Normal file
149
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/examples_test.go
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
|
||||
package sts_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
var _ time.Duration
|
||||
var _ bytes.Buffer
|
||||
|
||||
func ExampleSTS_AssumeRole() {
|
||||
svc := sts.New(session.New())
|
||||
|
||||
params := &sts.AssumeRoleInput{
|
||||
RoleArn: aws.String("arnType"), // Required
|
||||
RoleSessionName: aws.String("roleSessionNameType"), // Required
|
||||
DurationSeconds: aws.Int64(1),
|
||||
ExternalId: aws.String("externalIdType"),
|
||||
Policy: aws.String("sessionPolicyDocumentType"),
|
||||
SerialNumber: aws.String("serialNumberType"),
|
||||
TokenCode: aws.String("tokenCodeType"),
|
||||
}
|
||||
resp, err := svc.AssumeRole(params)
|
||||
|
||||
if err != nil {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Pretty-print the response data.
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
func ExampleSTS_AssumeRoleWithSAML() {
|
||||
svc := sts.New(session.New())
|
||||
|
||||
params := &sts.AssumeRoleWithSAMLInput{
|
||||
PrincipalArn: aws.String("arnType"), // Required
|
||||
RoleArn: aws.String("arnType"), // Required
|
||||
SAMLAssertion: aws.String("SAMLAssertionType"), // Required
|
||||
DurationSeconds: aws.Int64(1),
|
||||
Policy: aws.String("sessionPolicyDocumentType"),
|
||||
}
|
||||
resp, err := svc.AssumeRoleWithSAML(params)
|
||||
|
||||
if err != nil {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Pretty-print the response data.
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
func ExampleSTS_AssumeRoleWithWebIdentity() {
|
||||
svc := sts.New(session.New())
|
||||
|
||||
params := &sts.AssumeRoleWithWebIdentityInput{
|
||||
RoleArn: aws.String("arnType"), // Required
|
||||
RoleSessionName: aws.String("roleSessionNameType"), // Required
|
||||
WebIdentityToken: aws.String("clientTokenType"), // Required
|
||||
DurationSeconds: aws.Int64(1),
|
||||
Policy: aws.String("sessionPolicyDocumentType"),
|
||||
ProviderId: aws.String("urlType"),
|
||||
}
|
||||
resp, err := svc.AssumeRoleWithWebIdentity(params)
|
||||
|
||||
if err != nil {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Pretty-print the response data.
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
func ExampleSTS_DecodeAuthorizationMessage() {
|
||||
svc := sts.New(session.New())
|
||||
|
||||
params := &sts.DecodeAuthorizationMessageInput{
|
||||
EncodedMessage: aws.String("encodedMessageType"), // Required
|
||||
}
|
||||
resp, err := svc.DecodeAuthorizationMessage(params)
|
||||
|
||||
if err != nil {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Pretty-print the response data.
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
func ExampleSTS_GetFederationToken() {
|
||||
svc := sts.New(session.New())
|
||||
|
||||
params := &sts.GetFederationTokenInput{
|
||||
Name: aws.String("userNameType"), // Required
|
||||
DurationSeconds: aws.Int64(1),
|
||||
Policy: aws.String("sessionPolicyDocumentType"),
|
||||
}
|
||||
resp, err := svc.GetFederationToken(params)
|
||||
|
||||
if err != nil {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Pretty-print the response data.
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
func ExampleSTS_GetSessionToken() {
|
||||
svc := sts.New(session.New())
|
||||
|
||||
params := &sts.GetSessionTokenInput{
|
||||
DurationSeconds: aws.Int64(1),
|
||||
SerialNumber: aws.String("serialNumberType"),
|
||||
TokenCode: aws.String("tokenCodeType"),
|
||||
}
|
||||
resp, err := svc.GetSessionToken(params)
|
||||
|
||||
if err != nil {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Pretty-print the response data.
|
||||
fmt.Println(resp)
|
||||
}
|
||||
130
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/service.go
generated
vendored
Normal file
130
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/service.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
|
||||
package sts
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/query"
|
||||
"github.com/aws/aws-sdk-go/private/signer/v4"
|
||||
)
|
||||
|
||||
// The AWS Security Token Service (STS) is a web service that enables you to
|
||||
// request temporary, limited-privilege credentials for AWS Identity and Access
|
||||
// Management (IAM) users or for users that you authenticate (federated users).
|
||||
// This guide provides descriptions of the STS API. For more detailed information
|
||||
// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
|
||||
//
|
||||
// As an alternative to using the API, you can use one of the AWS SDKs, which
|
||||
// consist of libraries and sample code for various programming languages and
|
||||
// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient
|
||||
// way to create programmatic access to STS. For example, the SDKs take care
|
||||
// of cryptographically signing requests, managing errors, and retrying requests
|
||||
// automatically. For information about the AWS SDKs, including how to download
|
||||
// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/).
|
||||
// For information about setting up signatures and authorization through the
|
||||
// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html"
|
||||
// target="_blank) in the AWS General Reference. For general information about
|
||||
// the Query API, go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html"
|
||||
// target="_blank) in Using IAM. For information about using security tokens
|
||||
// with other AWS products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html)
|
||||
// in the Using IAM.
|
||||
//
|
||||
// If you're new to AWS and need additional technical information about a specific
|
||||
// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/
|
||||
// (http://aws.amazon.com/documentation/" target="_blank).
|
||||
//
|
||||
// Endpoints
|
||||
//
|
||||
// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com
|
||||
// that maps to the US East (N. Virginia) region. Additional regions are available,
|
||||
// but must first be activated in the AWS Management Console before you can
|
||||
// use a different region's endpoint. For more information about activating
|
||||
// a region for STS see Activating STS in a New Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the Using IAM.
|
||||
//
|
||||
// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region)
|
||||
// in the AWS General Reference.
|
||||
//
|
||||
// Recording API requests
|
||||
//
|
||||
// STS supports AWS CloudTrail, which is a service that records AWS calls for
|
||||
// your AWS account and delivers log files to an Amazon S3 bucket. By using
|
||||
// information collected by CloudTrail, you can determine what requests were
|
||||
// successfully made to STS, who made the request, when it was made, and so
|
||||
// on. To learn more about CloudTrail, including how to turn it on and find
|
||||
// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html).
|
||||
//The service client's operations are safe to be used concurrently.
|
||||
// It is not safe to mutate any of the client's properties though.
|
||||
type STS struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// A ServiceName is the name of the service the client will make API calls to.
|
||||
const ServiceName = "sts"
|
||||
|
||||
// New creates a new instance of the STS client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a STS client from just a session.
|
||||
// svc := sts.New(mySession)
|
||||
//
|
||||
// // Create a STS client with additional configuration
|
||||
// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS {
|
||||
c := p.ClientConfig(ServiceName, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *STS {
|
||||
svc := &STS{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2011-06-15",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBack(v4.Sign)
|
||||
svc.Handlers.Build.PushBack(query.Build)
|
||||
svc.Handlers.Unmarshal.PushBack(query.Unmarshal)
|
||||
svc.Handlers.UnmarshalMeta.PushBack(query.UnmarshalMeta)
|
||||
svc.Handlers.UnmarshalError.PushBack(query.UnmarshalError)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a STS operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
38
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go
generated
vendored
Normal file
38
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
|
||||
// Package stsiface provides an interface for the AWS Security Token Service.
|
||||
package stsiface
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
// STSAPI is the interface type for sts.STS.
|
||||
type STSAPI interface {
|
||||
AssumeRoleRequest(*sts.AssumeRoleInput) (*request.Request, *sts.AssumeRoleOutput)
|
||||
|
||||
AssumeRole(*sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
||||
|
||||
AssumeRoleWithSAMLRequest(*sts.AssumeRoleWithSAMLInput) (*request.Request, *sts.AssumeRoleWithSAMLOutput)
|
||||
|
||||
AssumeRoleWithSAML(*sts.AssumeRoleWithSAMLInput) (*sts.AssumeRoleWithSAMLOutput, error)
|
||||
|
||||
AssumeRoleWithWebIdentityRequest(*sts.AssumeRoleWithWebIdentityInput) (*request.Request, *sts.AssumeRoleWithWebIdentityOutput)
|
||||
|
||||
AssumeRoleWithWebIdentity(*sts.AssumeRoleWithWebIdentityInput) (*sts.AssumeRoleWithWebIdentityOutput, error)
|
||||
|
||||
DecodeAuthorizationMessageRequest(*sts.DecodeAuthorizationMessageInput) (*request.Request, *sts.DecodeAuthorizationMessageOutput)
|
||||
|
||||
DecodeAuthorizationMessage(*sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error)
|
||||
|
||||
GetFederationTokenRequest(*sts.GetFederationTokenInput) (*request.Request, *sts.GetFederationTokenOutput)
|
||||
|
||||
GetFederationToken(*sts.GetFederationTokenInput) (*sts.GetFederationTokenOutput, error)
|
||||
|
||||
GetSessionTokenRequest(*sts.GetSessionTokenInput) (*request.Request, *sts.GetSessionTokenOutput)
|
||||
|
||||
GetSessionToken(*sts.GetSessionTokenInput) (*sts.GetSessionTokenOutput, error)
|
||||
}
|
||||
|
||||
var _ STSAPI = (*sts.STS)(nil)
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
@@ -14,6 +16,8 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
@@ -44,31 +48,96 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
var awsCredentials map[string]*credentials.Credentials = make(map[string]*credentials.Credentials)
|
||||
type cache struct {
|
||||
credential *credentials.Credentials
|
||||
expiration *time.Time
|
||||
}
|
||||
|
||||
func getCredentials(profile string) *credentials.Credentials {
|
||||
if _, ok := awsCredentials[profile]; ok {
|
||||
return awsCredentials[profile]
|
||||
var awsCredentialCache map[string]cache = make(map[string]cache)
|
||||
var credentialCacheLock sync.RWMutex
|
||||
|
||||
func getCredentials(profile string, region string, assumeRoleArn string) *credentials.Credentials {
|
||||
credentialCacheLock.RLock()
|
||||
if _, ok := awsCredentialCache[profile]; ok {
|
||||
if awsCredentialCache[profile].expiration != nil &&
|
||||
(*awsCredentialCache[profile].expiration).After(time.Now().UTC()) {
|
||||
result := awsCredentialCache[profile].credential
|
||||
credentialCacheLock.RUnlock()
|
||||
return result
|
||||
}
|
||||
}
|
||||
credentialCacheLock.RUnlock()
|
||||
|
||||
accessKeyId := ""
|
||||
secretAccessKey := ""
|
||||
sessionToken := ""
|
||||
var expiration *time.Time
|
||||
expiration = nil
|
||||
if strings.Index(assumeRoleArn, "arn:aws:iam:") == 0 {
|
||||
params := &sts.AssumeRoleInput{
|
||||
RoleArn: aws.String(assumeRoleArn),
|
||||
RoleSessionName: aws.String("GrafanaSession"),
|
||||
DurationSeconds: aws.Int64(900),
|
||||
}
|
||||
|
||||
stsSess := session.New()
|
||||
stsCreds := credentials.NewChainCredentials(
|
||||
[]credentials.Provider{
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: profile},
|
||||
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(stsSess), ExpiryWindow: 5 * time.Minute},
|
||||
})
|
||||
stsConfig := &aws.Config{
|
||||
Region: aws.String(region),
|
||||
Credentials: stsCreds,
|
||||
}
|
||||
svc := sts.New(session.New(stsConfig), stsConfig)
|
||||
resp, err := svc.AssumeRole(params)
|
||||
if err != nil {
|
||||
// ignore
|
||||
log.Error(3, "CloudWatch: Failed to assume role", err)
|
||||
}
|
||||
if resp.Credentials != nil {
|
||||
accessKeyId = *resp.Credentials.AccessKeyId
|
||||
secretAccessKey = *resp.Credentials.SecretAccessKey
|
||||
sessionToken = *resp.Credentials.SessionToken
|
||||
expiration = resp.Credentials.Expiration
|
||||
}
|
||||
}
|
||||
|
||||
sess := session.New()
|
||||
creds := credentials.NewChainCredentials(
|
||||
[]credentials.Provider{
|
||||
&credentials.StaticProvider{Value: credentials.Value{
|
||||
AccessKeyID: accessKeyId,
|
||||
SecretAccessKey: secretAccessKey,
|
||||
SessionToken: sessionToken,
|
||||
}},
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: profile},
|
||||
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
|
||||
})
|
||||
awsCredentials[profile] = creds
|
||||
credentialCacheLock.Lock()
|
||||
awsCredentialCache[profile] = cache{
|
||||
credential: creds,
|
||||
expiration: expiration,
|
||||
}
|
||||
credentialCacheLock.Unlock()
|
||||
|
||||
return creds
|
||||
}
|
||||
|
||||
func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
|
||||
func getAwsConfig(req *cwRequest) *aws.Config {
|
||||
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(req.Region),
|
||||
Credentials: getCredentials(req.DataSource.Database),
|
||||
Credentials: getCredentials(req.DataSource.Database, req.Region, assumeRoleArn),
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
|
||||
cfg := getAwsConfig(req)
|
||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||
|
||||
reqParam := &struct {
|
||||
@@ -104,11 +173,7 @@ func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
|
||||
func handleListMetrics(req *cwRequest, c *middleware.Context) {
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(req.Region),
|
||||
Credentials: getCredentials(req.DataSource.Database),
|
||||
}
|
||||
|
||||
cfg := getAwsConfig(req)
|
||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||
|
||||
reqParam := &struct {
|
||||
@@ -144,11 +209,7 @@ func handleListMetrics(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
|
||||
func handleDescribeAlarms(req *cwRequest, c *middleware.Context) {
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(req.Region),
|
||||
Credentials: getCredentials(req.DataSource.Database),
|
||||
}
|
||||
|
||||
cfg := getAwsConfig(req)
|
||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||
|
||||
reqParam := &struct {
|
||||
@@ -187,11 +248,7 @@ func handleDescribeAlarms(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
|
||||
func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(req.Region),
|
||||
Credentials: getCredentials(req.DataSource.Database),
|
||||
}
|
||||
|
||||
cfg := getAwsConfig(req)
|
||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||
|
||||
reqParam := &struct {
|
||||
@@ -227,11 +284,7 @@ func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
|
||||
func handleDescribeAlarmHistory(req *cwRequest, c *middleware.Context) {
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(req.Region),
|
||||
Credentials: getCredentials(req.DataSource.Database),
|
||||
}
|
||||
|
||||
cfg := getAwsConfig(req)
|
||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||
|
||||
reqParam := &struct {
|
||||
@@ -263,11 +316,7 @@ func handleDescribeAlarmHistory(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
|
||||
func handleDescribeInstances(req *cwRequest, c *middleware.Context) {
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(req.Region),
|
||||
Credentials: getCredentials(req.DataSource.Database),
|
||||
}
|
||||
|
||||
cfg := getAwsConfig(req)
|
||||
svc := ec2.New(session.New(cfg), cfg)
|
||||
|
||||
reqParam := &struct {
|
||||
|
||||
@@ -166,7 +166,8 @@ func handleGetMetrics(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
if namespaceMetrics, err = getMetricsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, getAllMetrics); err != nil {
|
||||
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
||||
if namespaceMetrics, err = getMetricsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, assumeRoleArn, getAllMetrics); err != nil {
|
||||
c.JsonApiErr(500, "Unable to call AWS API", err)
|
||||
return
|
||||
}
|
||||
@@ -199,7 +200,8 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
if dimensionValues, err = getDimensionsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, getAllMetrics); err != nil {
|
||||
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
||||
if dimensionValues, err = getDimensionsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, assumeRoleArn, getAllMetrics); err != nil {
|
||||
c.JsonApiErr(500, "Unable to call AWS API", err)
|
||||
return
|
||||
}
|
||||
@@ -214,10 +216,10 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
|
||||
c.JSON(200, result)
|
||||
}
|
||||
|
||||
func getAllMetrics(region string, namespace string, database string) (cloudwatch.ListMetricsOutput, error) {
|
||||
func getAllMetrics(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
|
||||
cfg := &aws.Config{
|
||||
Region: aws.String(region),
|
||||
Credentials: getCredentials(database),
|
||||
Credentials: getCredentials(database, region, assumeRoleArn),
|
||||
}
|
||||
|
||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||
@@ -244,8 +246,8 @@ func getAllMetrics(region string, namespace string, database string) (cloudwatch
|
||||
|
||||
var metricsCacheLock sync.Mutex
|
||||
|
||||
func getMetricsForCustomMetrics(region string, namespace string, database string, getAllMetrics func(string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
||||
result, err := getAllMetrics(region, namespace, database)
|
||||
func getMetricsForCustomMetrics(region string, namespace string, database string, assumeRoleArn string, getAllMetrics func(string, string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
||||
result, err := getAllMetrics(region, namespace, database, assumeRoleArn)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
@@ -282,8 +284,8 @@ func getMetricsForCustomMetrics(region string, namespace string, database string
|
||||
|
||||
var dimensionsCacheLock sync.Mutex
|
||||
|
||||
func getDimensionsForCustomMetrics(region string, namespace string, database string, getAllMetrics func(string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
||||
result, err := getAllMetrics(region, namespace, database)
|
||||
func getDimensionsForCustomMetrics(region string, namespace string, database string, assumeRoleArn string, getAllMetrics func(string, string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
||||
result, err := getAllMetrics(region, namespace, database, assumeRoleArn)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ func TestCloudWatchMetrics(t *testing.T) {
|
||||
region := "us-east-1"
|
||||
namespace := "Foo"
|
||||
database := "default"
|
||||
f := func(region string, namespace string, database string) (cloudwatch.ListMetricsOutput, error) {
|
||||
assumeRoleArn := ""
|
||||
f := func(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
|
||||
return cloudwatch.ListMetricsOutput{
|
||||
Metrics: []*cloudwatch.Metric{
|
||||
{
|
||||
@@ -28,7 +29,7 @@ func TestCloudWatchMetrics(t *testing.T) {
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
metrics, _ := getMetricsForCustomMetrics(region, namespace, database, f)
|
||||
metrics, _ := getMetricsForCustomMetrics(region, namespace, database, assumeRoleArn, f)
|
||||
|
||||
Convey("Should contain Test_MetricName", func() {
|
||||
So(metrics, ShouldContain, "Test_MetricName")
|
||||
@@ -39,7 +40,8 @@ func TestCloudWatchMetrics(t *testing.T) {
|
||||
region := "us-east-1"
|
||||
namespace := "Foo"
|
||||
database := "default"
|
||||
f := func(region string, namespace string, database string) (cloudwatch.ListMetricsOutput, error) {
|
||||
assumeRoleArn := ""
|
||||
f := func(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
|
||||
return cloudwatch.ListMetricsOutput{
|
||||
Metrics: []*cloudwatch.Metric{
|
||||
{
|
||||
@@ -53,7 +55,7 @@ func TestCloudWatchMetrics(t *testing.T) {
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
dimensionKeys, _ := getDimensionsForCustomMetrics(region, namespace, database, f)
|
||||
dimensionKeys, _ := getDimensionsForCustomMetrics(region, namespace, database, assumeRoleArn, f)
|
||||
|
||||
Convey("Should contain Test_DimensionName", func() {
|
||||
So(dimensionKeys, ShouldContain, "Test_DimensionName")
|
||||
|
||||
@@ -24,4 +24,11 @@
|
||||
Namespaces of Custom Metrics
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-13">Assume Role ARN</label>
|
||||
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.jsonData.assumeRoleArn' placeholder="arn:aws:iam:*"></input>
|
||||
<info-popover mode="right-absolute">
|
||||
ARN of Assume Role
|
||||
</info-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user