mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(cloudwatch): adds access and secret key to edit config page
This commit is contained in:
parent
c3075a9bd1
commit
64784db870
@ -53,11 +53,21 @@ type cache struct {
|
|||||||
expiration *time.Time
|
expiration *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CloudwatchDatasource struct {
|
||||||
|
Profile string
|
||||||
|
Region string
|
||||||
|
AssumeRoleArn string
|
||||||
|
Namespace string
|
||||||
|
|
||||||
|
AccessKey string
|
||||||
|
SecretKey string
|
||||||
|
}
|
||||||
|
|
||||||
var awsCredentialCache map[string]cache = make(map[string]cache)
|
var awsCredentialCache map[string]cache = make(map[string]cache)
|
||||||
var credentialCacheLock sync.RWMutex
|
var credentialCacheLock sync.RWMutex
|
||||||
|
|
||||||
func getCredentials(profile string, region string, assumeRoleArn string) *credentials.Credentials {
|
func getCredentials(cwDatasource *CloudwatchDatasource) *credentials.Credentials {
|
||||||
cacheKey := profile + ":" + assumeRoleArn
|
cacheKey := cwDatasource.Profile + ":" + cwDatasource.AssumeRoleArn
|
||||||
credentialCacheLock.RLock()
|
credentialCacheLock.RLock()
|
||||||
if _, ok := awsCredentialCache[cacheKey]; ok {
|
if _, ok := awsCredentialCache[cacheKey]; ok {
|
||||||
if awsCredentialCache[cacheKey].expiration != nil &&
|
if awsCredentialCache[cacheKey].expiration != nil &&
|
||||||
@ -74,9 +84,9 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
|
|||||||
sessionToken := ""
|
sessionToken := ""
|
||||||
var expiration *time.Time
|
var expiration *time.Time
|
||||||
expiration = nil
|
expiration = nil
|
||||||
if strings.Index(assumeRoleArn, "arn:aws:iam:") == 0 {
|
if strings.Index(cwDatasource.AssumeRoleArn, "arn:aws:iam:") == 0 {
|
||||||
params := &sts.AssumeRoleInput{
|
params := &sts.AssumeRoleInput{
|
||||||
RoleArn: aws.String(assumeRoleArn),
|
RoleArn: aws.String(cwDatasource.AssumeRoleArn),
|
||||||
RoleSessionName: aws.String("GrafanaSession"),
|
RoleSessionName: aws.String("GrafanaSession"),
|
||||||
DurationSeconds: aws.Int64(900),
|
DurationSeconds: aws.Int64(900),
|
||||||
}
|
}
|
||||||
@ -85,13 +95,14 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
|
|||||||
stsCreds := credentials.NewChainCredentials(
|
stsCreds := credentials.NewChainCredentials(
|
||||||
[]credentials.Provider{
|
[]credentials.Provider{
|
||||||
&credentials.EnvProvider{},
|
&credentials.EnvProvider{},
|
||||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: profile},
|
&credentials.SharedCredentialsProvider{Filename: "", Profile: cwDatasource.Profile},
|
||||||
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(stsSess), ExpiryWindow: 5 * time.Minute},
|
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(stsSess), ExpiryWindow: 5 * time.Minute},
|
||||||
})
|
})
|
||||||
stsConfig := &aws.Config{
|
stsConfig := &aws.Config{
|
||||||
Region: aws.String(region),
|
Region: aws.String(cwDatasource.Region),
|
||||||
Credentials: stsCreds,
|
Credentials: stsCreds,
|
||||||
}
|
}
|
||||||
|
|
||||||
svc := sts.New(session.New(stsConfig), stsConfig)
|
svc := sts.New(session.New(stsConfig), stsConfig)
|
||||||
resp, err := svc.AssumeRole(params)
|
resp, err := svc.AssumeRole(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -115,9 +126,14 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
|
|||||||
SessionToken: sessionToken,
|
SessionToken: sessionToken,
|
||||||
}},
|
}},
|
||||||
&credentials.EnvProvider{},
|
&credentials.EnvProvider{},
|
||||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: profile},
|
&credentials.StaticProvider{Value: credentials.Value{
|
||||||
|
AccessKeyID: cwDatasource.AccessKey,
|
||||||
|
SecretAccessKey: cwDatasource.SecretKey,
|
||||||
|
}},
|
||||||
|
&credentials.SharedCredentialsProvider{Filename: "", Profile: cwDatasource.Profile},
|
||||||
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
|
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
|
||||||
})
|
})
|
||||||
|
|
||||||
credentialCacheLock.Lock()
|
credentialCacheLock.Lock()
|
||||||
awsCredentialCache[cacheKey] = cache{
|
awsCredentialCache[cacheKey] = cache{
|
||||||
credential: creds,
|
credential: creds,
|
||||||
@ -130,9 +146,18 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
|
|||||||
|
|
||||||
func getAwsConfig(req *cwRequest) *aws.Config {
|
func getAwsConfig(req *cwRequest) *aws.Config {
|
||||||
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
||||||
|
accessKey := req.DataSource.JsonData.Get("accessKey").MustString()
|
||||||
|
secretKey := req.DataSource.JsonData.Get("secretKey").MustString()
|
||||||
|
|
||||||
cfg := &aws.Config{
|
cfg := &aws.Config{
|
||||||
Region: aws.String(req.Region),
|
Region: aws.String(req.Region),
|
||||||
Credentials: getCredentials(req.DataSource.Database, req.Region, assumeRoleArn),
|
Credentials: getCredentials(&CloudwatchDatasource{
|
||||||
|
AccessKey: accessKey,
|
||||||
|
SecretKey: secretKey,
|
||||||
|
Region: req.Region,
|
||||||
|
Profile: req.DataSource.Database,
|
||||||
|
AssumeRoleArn: assumeRoleArn,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,19 @@ func handleGetMetrics(req *cwRequest, c *middleware.Context) {
|
|||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
||||||
if namespaceMetrics, err = getMetricsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, assumeRoleArn, getAllMetrics); err != nil {
|
accessKey := req.DataSource.JsonData.Get("accessKey").MustString()
|
||||||
|
secretKey := req.DataSource.JsonData.Get("secretKey").MustString()
|
||||||
|
|
||||||
|
cwData := &CloudwatchDatasource{
|
||||||
|
AssumeRoleArn: assumeRoleArn,
|
||||||
|
Region: req.Region,
|
||||||
|
Namespace: reqParam.Parameters.Namespace,
|
||||||
|
Profile: req.DataSource.Database,
|
||||||
|
AccessKey: accessKey,
|
||||||
|
SecretKey: secretKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
if namespaceMetrics, err = getMetricsForCustomMetrics(cwData, getAllMetrics); err != nil {
|
||||||
c.JsonApiErr(500, "Unable to call AWS API", err)
|
c.JsonApiErr(500, "Unable to call AWS API", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -227,7 +239,18 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
|
|||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
|
||||||
if dimensionValues, err = getDimensionsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, assumeRoleArn, getAllMetrics); err != nil {
|
accessKey := req.DataSource.JsonData.Get("accessKey").MustString()
|
||||||
|
secretKey := req.DataSource.JsonData.Get("secretKey").MustString()
|
||||||
|
|
||||||
|
cwDatasource := &CloudwatchDatasource{
|
||||||
|
Region: req.Region,
|
||||||
|
Namespace: reqParam.Parameters.Namespace,
|
||||||
|
Profile: req.DataSource.Database,
|
||||||
|
AssumeRoleArn: assumeRoleArn,
|
||||||
|
AccessKey: accessKey,
|
||||||
|
SecretKey: secretKey,
|
||||||
|
}
|
||||||
|
if dimensionValues, err = getDimensionsForCustomMetrics(cwDatasource, getAllMetrics); err != nil {
|
||||||
c.JsonApiErr(500, "Unable to call AWS API", err)
|
c.JsonApiErr(500, "Unable to call AWS API", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -242,16 +265,16 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
|
|||||||
c.JSON(200, result)
|
c.JSON(200, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAllMetrics(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
|
func getAllMetrics(cwData *CloudwatchDatasource) (cloudwatch.ListMetricsOutput, error) {
|
||||||
cfg := &aws.Config{
|
cfg := &aws.Config{
|
||||||
Region: aws.String(region),
|
Region: aws.String(cwData.Region),
|
||||||
Credentials: getCredentials(database, region, assumeRoleArn),
|
Credentials: getCredentials(cwData),
|
||||||
}
|
}
|
||||||
|
|
||||||
svc := cloudwatch.New(session.New(cfg), cfg)
|
svc := cloudwatch.New(session.New(cfg), cfg)
|
||||||
|
|
||||||
params := &cloudwatch.ListMetricsInput{
|
params := &cloudwatch.ListMetricsInput{
|
||||||
Namespace: aws.String(namespace),
|
Namespace: aws.String(cwData.Namespace),
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp cloudwatch.ListMetricsOutput
|
var resp cloudwatch.ListMetricsOutput
|
||||||
@ -272,8 +295,8 @@ func getAllMetrics(region string, namespace string, database string, assumeRoleA
|
|||||||
|
|
||||||
var metricsCacheLock sync.Mutex
|
var metricsCacheLock sync.Mutex
|
||||||
|
|
||||||
func getMetricsForCustomMetrics(region string, namespace string, database string, assumeRoleArn string, getAllMetrics func(string, string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
func getMetricsForCustomMetrics(cwDatasource *CloudwatchDatasource, getAllMetrics func(*CloudwatchDatasource) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
||||||
result, err := getAllMetrics(region, namespace, database, assumeRoleArn)
|
result, err := getAllMetrics(cwDatasource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, err
|
return []string{}, err
|
||||||
}
|
}
|
||||||
@ -281,37 +304,37 @@ func getMetricsForCustomMetrics(region string, namespace string, database string
|
|||||||
metricsCacheLock.Lock()
|
metricsCacheLock.Lock()
|
||||||
defer metricsCacheLock.Unlock()
|
defer metricsCacheLock.Unlock()
|
||||||
|
|
||||||
if _, ok := customMetricsMetricsMap[database]; !ok {
|
if _, ok := customMetricsMetricsMap[cwDatasource.Profile]; !ok {
|
||||||
customMetricsMetricsMap[database] = make(map[string]map[string]*CustomMetricsCache)
|
customMetricsMetricsMap[cwDatasource.Profile] = make(map[string]map[string]*CustomMetricsCache)
|
||||||
}
|
}
|
||||||
if _, ok := customMetricsMetricsMap[database][region]; !ok {
|
if _, ok := customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region]; !ok {
|
||||||
customMetricsMetricsMap[database][region] = make(map[string]*CustomMetricsCache)
|
customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region] = make(map[string]*CustomMetricsCache)
|
||||||
}
|
}
|
||||||
if _, ok := customMetricsMetricsMap[database][region][namespace]; !ok {
|
if _, ok := customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace]; !ok {
|
||||||
customMetricsMetricsMap[database][region][namespace] = &CustomMetricsCache{}
|
customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace] = &CustomMetricsCache{}
|
||||||
customMetricsMetricsMap[database][region][namespace].Cache = make([]string, 0)
|
customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache = make([]string, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if customMetricsMetricsMap[database][region][namespace].Expire.After(time.Now()) {
|
if customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Expire.After(time.Now()) {
|
||||||
return customMetricsMetricsMap[database][region][namespace].Cache, nil
|
return customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, nil
|
||||||
}
|
}
|
||||||
customMetricsMetricsMap[database][region][namespace].Cache = make([]string, 0)
|
customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache = make([]string, 0)
|
||||||
customMetricsMetricsMap[database][region][namespace].Expire = time.Now().Add(5 * time.Minute)
|
customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Expire = time.Now().Add(5 * time.Minute)
|
||||||
|
|
||||||
for _, metric := range result.Metrics {
|
for _, metric := range result.Metrics {
|
||||||
if isDuplicate(customMetricsMetricsMap[database][region][namespace].Cache, *metric.MetricName) {
|
if isDuplicate(customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, *metric.MetricName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
customMetricsMetricsMap[database][region][namespace].Cache = append(customMetricsMetricsMap[database][region][namespace].Cache, *metric.MetricName)
|
customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache = append(customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, *metric.MetricName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return customMetricsMetricsMap[database][region][namespace].Cache, nil
|
return customMetricsMetricsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var dimensionsCacheLock sync.Mutex
|
var dimensionsCacheLock sync.Mutex
|
||||||
|
|
||||||
func getDimensionsForCustomMetrics(region string, namespace string, database string, assumeRoleArn string, getAllMetrics func(string, string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
func getDimensionsForCustomMetrics(cwDatasource *CloudwatchDatasource, getAllMetrics func(*CloudwatchDatasource) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
|
||||||
result, err := getAllMetrics(region, namespace, database, assumeRoleArn)
|
result, err := getAllMetrics(cwDatasource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, err
|
return []string{}, err
|
||||||
}
|
}
|
||||||
@ -319,33 +342,33 @@ func getDimensionsForCustomMetrics(region string, namespace string, database str
|
|||||||
dimensionsCacheLock.Lock()
|
dimensionsCacheLock.Lock()
|
||||||
defer dimensionsCacheLock.Unlock()
|
defer dimensionsCacheLock.Unlock()
|
||||||
|
|
||||||
if _, ok := customMetricsDimensionsMap[database]; !ok {
|
if _, ok := customMetricsDimensionsMap[cwDatasource.Profile]; !ok {
|
||||||
customMetricsDimensionsMap[database] = make(map[string]map[string]*CustomMetricsCache)
|
customMetricsDimensionsMap[cwDatasource.Profile] = make(map[string]map[string]*CustomMetricsCache)
|
||||||
}
|
}
|
||||||
if _, ok := customMetricsDimensionsMap[database][region]; !ok {
|
if _, ok := customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region]; !ok {
|
||||||
customMetricsDimensionsMap[database][region] = make(map[string]*CustomMetricsCache)
|
customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region] = make(map[string]*CustomMetricsCache)
|
||||||
}
|
}
|
||||||
if _, ok := customMetricsDimensionsMap[database][region][namespace]; !ok {
|
if _, ok := customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace]; !ok {
|
||||||
customMetricsDimensionsMap[database][region][namespace] = &CustomMetricsCache{}
|
customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace] = &CustomMetricsCache{}
|
||||||
customMetricsDimensionsMap[database][region][namespace].Cache = make([]string, 0)
|
customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache = make([]string, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if customMetricsDimensionsMap[database][region][namespace].Expire.After(time.Now()) {
|
if customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Expire.After(time.Now()) {
|
||||||
return customMetricsDimensionsMap[database][region][namespace].Cache, nil
|
return customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, nil
|
||||||
}
|
}
|
||||||
customMetricsDimensionsMap[database][region][namespace].Cache = make([]string, 0)
|
customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache = make([]string, 0)
|
||||||
customMetricsDimensionsMap[database][region][namespace].Expire = time.Now().Add(5 * time.Minute)
|
customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Expire = time.Now().Add(5 * time.Minute)
|
||||||
|
|
||||||
for _, metric := range result.Metrics {
|
for _, metric := range result.Metrics {
|
||||||
for _, dimension := range metric.Dimensions {
|
for _, dimension := range metric.Dimensions {
|
||||||
if isDuplicate(customMetricsDimensionsMap[database][region][namespace].Cache, *dimension.Name) {
|
if isDuplicate(customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, *dimension.Name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
customMetricsDimensionsMap[database][region][namespace].Cache = append(customMetricsDimensionsMap[database][region][namespace].Cache, *dimension.Name)
|
customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache = append(customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, *dimension.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return customMetricsDimensionsMap[database][region][namespace].Cache, nil
|
return customMetricsDimensionsMap[cwDatasource.Profile][cwDatasource.Region][cwDatasource.Namespace].Cache, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func isDuplicate(nameList []string, target string) bool {
|
func isDuplicate(nameList []string, target string) bool {
|
||||||
|
@ -1,34 +1,48 @@
|
|||||||
<h3 class="page-heading">CloudWatch details</h3>
|
<h3 class="page-heading">CloudWatch details</h3>
|
||||||
|
|
||||||
<div class="gf-form-group max-width-30">
|
<div class="gf-form-group max-width-30">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label width-13">Credentials profile name</label>
|
<label class="gf-form-label width-13">Credentials profile name</label>
|
||||||
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.database' placeholder="default"></input>
|
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.database' placeholder="default"></input>
|
||||||
<info-popover mode="right-absolute">
|
<info-popover mode="right-absolute">
|
||||||
Credentials profile name, as specified in ~/.aws/credentials, leave blank for default
|
Credentials profile name, as specified in ~/.aws/credentials, leave blank for default
|
||||||
</info-popover>
|
</info-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label width-13">Default Region</label>
|
<label class="gf-form-label width-13">Credentials Access key</label>
|
||||||
<div class="gf-form-select-wrapper max-width-18 gf-form-select-wrapper--has-help-icon">
|
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.jsonData.accessKey' placeholder="default"></input>
|
||||||
<select class="gf-form-input" ng-model="ctrl.current.jsonData.defaultRegion" ng-options="region for region in ['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'ap-south-1', 'cn-north-1', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-east-2', 'us-gov-west-1', 'us-west-1', 'us-west-2']"></select>
|
<info-popover mode="right-absolute">
|
||||||
<info-popover mode="right-absolute">
|
Accesskey
|
||||||
Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.
|
</info-popover>
|
||||||
</info-popover>
|
</div>
|
||||||
</div>
|
<div class="gf-form">
|
||||||
</div>
|
<label class="gf-form-label width-13">Credentials Secret key</label>
|
||||||
<div class="gf-form">
|
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.jsonData.secretKey' placeholder="default"></input>
|
||||||
<label class="gf-form-label width-13">Custom Metrics namespace</label>
|
<info-popover mode="right-absolute">
|
||||||
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.jsonData.customMetricsNamespaces' placeholder="Namespace1,Namespace2"></input>
|
Secret key
|
||||||
<info-popover mode="right-absolute">
|
</info-popover>
|
||||||
Namespaces of Custom Metrics
|
</div>
|
||||||
</info-popover>
|
<div class="gf-form">
|
||||||
</div>
|
<label class="gf-form-label width-13">Default Region</label>
|
||||||
<div class="gf-form">
|
<div class="gf-form-select-wrapper max-width-18 gf-form-select-wrapper--has-help-icon">
|
||||||
<label class="gf-form-label width-13">Assume Role ARN</label>
|
<select class="gf-form-input" ng-model="ctrl.current.jsonData.defaultRegion" ng-options="region for region in ['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'ap-south-1', 'cn-north-1', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-east-2', 'us-gov-west-1', 'us-west-1', 'us-west-2']"></select>
|
||||||
<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">
|
||||||
<info-popover mode="right-absolute">
|
Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.
|
||||||
ARN of Assume Role
|
</info-popover>
|
||||||
</info-popover>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label width-13">Custom Metrics namespace</label>
|
||||||
|
<input type="text" class="gf-form-input max-width-18" ng-model='ctrl.current.jsonData.customMetricsNamespaces' placeholder="Namespace1,Namespace2"></input>
|
||||||
|
<info-popover mode="right-absolute">
|
||||||
|
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>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user