Sfoglia il codice sorgente

add dimensions() to CloudWatch templating query

Mitsuhiro Tanda 10 anni fa
parent
commit
add5bb47d5

+ 49 - 15
public/app/plugins/datasource/cloudwatch/datasource.js

@@ -112,14 +112,14 @@ function (angular, _) {
       });
     };
 
-    CloudWatchDatasource.prototype.getDimensionValues = function(region, namespace, metricName, dimensions) {
+    CloudWatchDatasource.prototype.getDimensions = function(region, namespace, metricName, filterDimensions) {
       var request = {
         region: templateSrv.replace(region),
         action: 'ListMetrics',
         parameters: {
           namespace: templateSrv.replace(namespace),
           metricName: templateSrv.replace(metricName),
-          dimensions: convertDimensionFormat(dimensions, {}),
+          dimensions: convertDimensionFormat(filterDimensions, {}),
         }
       };
 
@@ -128,6 +128,17 @@ function (angular, _) {
       });
     };
 
+    CloudWatchDatasource.prototype.getDimensionValues = function(region, namespace, metricName, dimensionKey, filterDimensions) {
+      return this.getDimensions(region, namespace, metricName, filterDimensions).then(function(dimensions) {
+        return _.chain(dimensions)
+        .flatten()
+        .filter(function(dimension) {
+          return dimension.Name === dimensionKey;
+        })
+        .pluck('Value').uniq().sortBy().value();
+      });
+    };
+
     CloudWatchDatasource.prototype.performEC2DescribeInstances = function(region, filters, instanceIds) {
       return this.awsRequest({
         region: region,
@@ -140,6 +151,8 @@ function (angular, _) {
       var region;
       var namespace;
       var metricName;
+      var dimensionPart;
+      var dimensions;
 
       var transformSuggestData = function(suggestData) {
         return _.map(suggestData, function(v) {
@@ -147,6 +160,21 @@ function (angular, _) {
         });
       };
 
+      var parseDimensions = function(dimensionPart) {
+        if (_.isEmpty(dimensionPart)) {
+          return {};
+        }
+        var dimensions = {};
+        _.each(dimensionPart.split(','), function(v) {
+          var t = v.split('=');
+          if (t.length !== 2) {
+            throw new Error('Invalid query format');
+          }
+          dimensions[t[0]] = t[1];
+        });
+        return dimensions;
+      };
+
       var regionQuery = query.match(/^regions\(\)/);
       if (regionQuery) {
         return this.getRegions();
@@ -167,25 +195,31 @@ function (angular, _) {
         return this.getDimensionKeys(dimensionKeysQuery[1]);
       }
 
-      var dimensionValuesQuery = query.match(/^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?([^)]*))?\)/);
+      var dimensionValuesQuery = query.match(/^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?([^)]*))?\)/);
       if (dimensionValuesQuery) {
         region = templateSrv.replace(dimensionValuesQuery[1]);
         namespace = templateSrv.replace(dimensionValuesQuery[2]);
         metricName = templateSrv.replace(dimensionValuesQuery[3]);
-        var dimensionPart = templateSrv.replace(dimensionValuesQuery[5]);
+        var dimensionKey = templateSrv.replace(dimensionValuesQuery[4]);
+        dimensionPart = templateSrv.replace(dimensionValuesQuery[6]);
 
-        var dimensions = {};
-        if (!_.isEmpty(dimensionPart)) {
-          _.each(dimensionPart.split(','), function(v) {
-            var t = v.split('=');
-            if (t.length !== 2) {
-              throw new Error('Invalid query format');
-            }
-            dimensions[t[0]] = t[1];
+        dimensions = parseDimensions(dimensionPart);
+        return this.getDimensionValues(region, namespace, metricName, dimensionKey, dimensions).then(function(result) {
+          return _.map(result, function(dimension_value) {
+            return { text: dimension_value };
           });
-        }
+        });
+      }
+
+      var dimensionsQuery = query.match(/^dimensions\(([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?([^)]*))?\)/);
+      if (dimensionsQuery) {
+        region = templateSrv.replace(dimensionsQuery[1]);
+        namespace = templateSrv.replace(dimensionsQuery[2]);
+        metricName = templateSrv.replace(dimensionsQuery[3]);
+        dimensionPart = templateSrv.replace(dimensionsQuery[5]);
 
-        return this.getDimensionValues(region, namespace, metricName, dimensions).then(function(result) {
+        dimensions = parseDimensions(dimensionPart);
+        return this.getDimensions(region, namespace, metricName, dimensions).then(function(result) {
           return _.map(result, function(dimensions) {
             var values = _.chain(dimensions)
             .sortBy(function(dimension) {
@@ -228,7 +262,7 @@ function (angular, _) {
       var metricName = 'EstimatedCharges';
       var dimensions = {};
 
-      return this.getDimensionValues(region, namespace, metricName, dimensions).then(function () {
+      return this.getDimensions(region, namespace, metricName, dimensions).then(function () {
         return { status: 'success', message: 'Data source is working', title: 'Success' };
       });
     };

+ 3 - 17
public/app/plugins/datasource/cloudwatch/query_ctrl.js

@@ -85,25 +85,11 @@ function (angular, _) {
       if (segment.type === 'key' || segment.type === 'plus-button') {
         query = $scope.datasource.getDimensionKeys($scope.target.namespace);
       } else if (segment.type === 'value')  {
-        query = $scope.datasource.getDimensionValues(target.region, target.namespace, target.metricName, {});
+        var dimensionKey = $scope.dimSegments[$index-2].value;
+        query = $scope.datasource.getDimensionValues(target.region, target.namespace, target.metricName, dimensionKey, {});
       }
 
-      return query.then(function(results) {
-        if (segment.type === 'value') {
-          results = _.chain(results)
-          .flatten(true)
-          .filter(function(dimension) {
-            return dimension.Name === templateSrv.replace($scope.dimSegments[$index-2].value);
-          })
-          .pluck('Value')
-          .uniq()
-          .map(function(value) {
-            return {value: value, text: value};
-          })
-          .value();
-        }
-        return $scope.transformToSegments(true)(results);
-      }).then(function(results) {
+      return query.then($scope.transformToSegments(true)).then(function(results) {
         if (segment.type === 'key') {
           results.splice(0, 0, angular.copy($scope.removeDimSegment));
         }

+ 25 - 1
public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts

@@ -146,7 +146,7 @@ describe('CloudWatchDatasource', function() {
     });
   });
 
-  describeMetricFindQuery('dimension_values(us-east-1,AWS/EC2,CPUUtilization)', scenario => {
+  describeMetricFindQuery('dimensions(us-east-1,AWS/EC2,CPUUtilization)', scenario => {
     scenario.setup(() => {
       scenario.requestResponse = {
         Metrics: [
@@ -170,4 +170,28 @@ describe('CloudWatchDatasource', function() {
     });
   });
 
+  describeMetricFindQuery('dimension_values(us-east-1,AWS/EC2,CPUUtilization,InstanceId)', scenario => {
+    scenario.setup(() => {
+      scenario.requestResponse = {
+        Metrics: [
+          {
+            Namespace: 'AWS/EC2',
+            MetricName: 'CPUUtilization',
+            Dimensions: [
+              {
+                Name: 'InstanceId',
+                Value: 'i-12345678'
+              }
+            ]
+          }
+        ]
+      };
+    });
+
+    it('should call __ListMetrics and return result', () => {
+      expect(scenario.result[0].text).to.be('i-12345678');
+      expect(scenario.request.data.action).to.be('ListMetrics');
+    });
+  });
+
 });