Procházet zdrojové kódy

Merge pull request #12337 from mtanda/cw_regions

show all CloudWatch regions (avoid hard coding)
Marcus Efraimsson před 7 roky
rodič
revize
62f21a254a

+ 4 - 3
docs/sources/features/datasources/cloudwatch.md

@@ -46,7 +46,7 @@ Checkout AWS docs on [IAM Roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGu
 ## IAM Policies
 
 Grafana needs permissions granted via IAM to be able to read CloudWatch metrics
-and EC2 tags/instances. You can attach these permissions to IAM roles and
+and EC2 tags/instances/regions. You can attach these permissions to IAM roles and
 utilize Grafana's built-in support for assuming roles.
 
 Here is a minimal policy example:
@@ -65,11 +65,12 @@ Here is a minimal policy example:
             "Resource": "*"
         },
         {
-            "Sid": "AllowReadingTagsFromEC2",
+            "Sid": "AllowReadingTagsInstancesRegionsFromEC2",
             "Effect": "Allow",
             "Action": [
                 "ec2:DescribeTags",
-                "ec2:DescribeInstances"
+                "ec2:DescribeInstances",
+                "ec2:DescribeRegions"
             ],
             "Resource": "*"
         }

+ 29 - 2
pkg/tsdb/cloudwatch/metric_find_query.go

@@ -234,10 +234,37 @@ func parseMultiSelectValue(input string) []string {
 // Please update the region list in public/app/plugins/datasource/cloudwatch/partials/config.html
 func (e *CloudWatchExecutor) handleGetRegions(ctx context.Context, parameters *simplejson.Json, queryContext *tsdb.TsdbQuery) ([]suggestData, error) {
 	regions := []string{
-		"ap-northeast-1", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-south-1", "ca-central-1", "cn-north-1", "cn-northwest-1",
-		"eu-central-1", "eu-west-1", "eu-west-2", "eu-west-3", "sa-east-1", "us-east-1", "us-east-2", "us-gov-west-1", "us-west-1", "us-west-2", "us-isob-east-1", "us-iso-east-1",
+		"ap-northeast-1", "ap-northeast-2", "ap-northeast-3", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "ca-central-1",
+		"eu-central-1", "eu-north-1", "eu-west-1", "eu-west-2", "eu-west-3", "me-south-1", "sa-east-1", "us-east-1", "us-east-2", "us-west-1", "us-west-2",
+		"cn-north-1", "cn-northwest-1", "us-gov-east-1", "us-gov-west-1", "us-isob-east-1", "us-iso-east-1",
 	}
 
+	err := e.ensureClientSession("us-east-1")
+	if err != nil {
+		return nil, err
+	}
+	r, err := e.ec2Svc.DescribeRegions(&ec2.DescribeRegionsInput{})
+	if err != nil {
+		// ignore error for backward compatibility
+		plog.Error("Failed to get regions", "error", err)
+	} else {
+		for _, region := range r.Regions {
+			exists := false
+
+			for _, existingRegion := range regions {
+				if existingRegion == *region.RegionName {
+					exists = true
+					break
+				}
+			}
+
+			if !exists {
+				regions = append(regions, *region.RegionName)
+			}
+		}
+	}
+	sort.Strings(regions)
+
 	result := make([]suggestData, 0)
 	for _, region := range regions {
 		result = append(result, suggestData{Text: region, Value: region})

+ 48 - 1
public/app/plugins/datasource/cloudwatch/config_ctrl.ts

@@ -1,17 +1,21 @@
+import _ from 'lodash';
 export class CloudWatchConfigCtrl {
   static templateUrl = 'partials/config.html';
   current: any;
+  datasourceSrv: any;
 
   accessKeyExist = false;
   secretKeyExist = false;
 
   /** @ngInject */
-  constructor($scope) {
+  constructor($scope, datasourceSrv) {
     this.current.jsonData.timeField = this.current.jsonData.timeField || '@timestamp';
     this.current.jsonData.authType = this.current.jsonData.authType || 'credentials';
 
     this.accessKeyExist = this.current.secureJsonFields.accessKey;
     this.secretKeyExist = this.current.secureJsonFields.secretKey;
+    this.datasourceSrv = datasourceSrv;
+    this.getRegions();
   }
 
   resetAccessKey() {
@@ -36,4 +40,47 @@ export class CloudWatchConfigCtrl {
     { name: 'Monthly', value: 'Monthly', example: '[logstash-]YYYY.MM' },
     { name: 'Yearly', value: 'Yearly', example: '[logstash-]YYYY' },
   ];
+
+  regions = [
+    'ap-northeast-1',
+    'ap-northeast-2',
+    'ap-northeast-3',
+    'ap-south-1',
+    'ap-southeast-1',
+    'ap-southeast-2',
+    'ca-central-1',
+    'cn-north-1',
+    'cn-northwest-1',
+    'eu-central-1',
+    'eu-north-1',
+    'eu-west-1',
+    'eu-west-2',
+    'eu-west-3',
+    'me-south-1',
+    'sa-east-1',
+    'us-east-1',
+    'us-east-2',
+    'us-gov-east-1',
+    'us-gov-west-1',
+    'us-iso-east-1',
+    'us-isob-east-1',
+    'us-west-1',
+    'us-west-2',
+  ];
+
+  getRegions() {
+    this.datasourceSrv
+      .loadDatasource(this.current.name)
+      .then(ds => {
+        return ds.getRegions();
+      })
+      .then(
+        regions => {
+          this.regions = _.map(regions, 'value');
+        },
+        err => {
+          console.error('failed to get latest regions');
+        }
+      );
+  }
 }

+ 1 - 1
public/app/plugins/datasource/cloudwatch/partials/config.html

@@ -39,7 +39,7 @@
   <div class="gf-form">
     <label class="gf-form-label width-13">Default Region</label>
     <div class="gf-form-select-wrapper max-width-18 gf-form-select-wrapper--has-help-icon">
-      <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', 'ca-central-1', 'cn-north-1', 'cn-northwest-1', 'eu-central-1', 'eu-west-1', 'eu-west-2', 'eu-west-3', 'sa-east-1', 'us-east-1', 'us-east-2', 'us-gov-west-1', 'us-west-1', 'us-west-2', 'us-isob-east-1', 'us-iso-east-1']"></select>
+      <select class="gf-form-input" ng-model="ctrl.current.jsonData.defaultRegion" ng-options="region for region in ctrl.regions"></select>
       <info-popover mode="right-absolute">
         Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.
       </info-popover>