Skip to content

Commit 180ba33

Browse files
committed
feat(cloudwatch): refactoring and cleanup of backend code, started moving hard coded stuff in the frontend to the backend, changed name of metricFind queries region() -> regions() , and namespace() -> namespaces() to be more consistent with the others, grafana#684
1 parent 04f4454 commit 180ba33

File tree

6 files changed

+174
-144
lines changed

6 files changed

+174
-144
lines changed

pkg/api/cloudwatch/cloudwatch.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package cloudwatch
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"io/ioutil"
7+
"time"
8+
9+
"github.com/aws/aws-sdk-go/aws"
10+
"github.com/aws/aws-sdk-go/service/cloudwatch"
11+
"github.com/aws/aws-sdk-go/service/ec2"
12+
"github.com/grafana/grafana/pkg/middleware"
13+
"github.com/grafana/grafana/pkg/util"
14+
)
15+
16+
type actionHandler func(*cwRequest, *middleware.Context)
17+
18+
var actionHandlers map[string]actionHandler
19+
20+
type cwRequest struct {
21+
Region string `json:"region"`
22+
Action string `json:"action"`
23+
Body []byte `json:"-"`
24+
}
25+
26+
func init() {
27+
actionHandlers = map[string]actionHandler{
28+
"GetMetricStatistics": handleGetMetricStatistics,
29+
"ListMetrics": handleListMetrics,
30+
"DescribeInstances": handleDescribeInstances,
31+
"__GetRegions": handleGetRegions,
32+
}
33+
}
34+
35+
func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
36+
svc := cloudwatch.New(&aws.Config{Region: aws.String(req.Region)})
37+
38+
reqParam := &struct {
39+
Parameters struct {
40+
Namespace string `json:"namespace"`
41+
MetricName string `json:"metricName"`
42+
Dimensions []*cloudwatch.Dimension `json:"dimensions"`
43+
Statistics []*string `json:"statistics"`
44+
StartTime int64 `json:"startTime"`
45+
EndTime int64 `json:"endTime"`
46+
Period int64 `json:"period"`
47+
} `json:"parameters"`
48+
}{}
49+
json.Unmarshal(req.Body, reqParam)
50+
51+
params := &cloudwatch.GetMetricStatisticsInput{
52+
Namespace: aws.String(reqParam.Parameters.Namespace),
53+
MetricName: aws.String(reqParam.Parameters.MetricName),
54+
Dimensions: reqParam.Parameters.Dimensions,
55+
Statistics: reqParam.Parameters.Statistics,
56+
StartTime: aws.Time(time.Unix(reqParam.Parameters.StartTime, 0)),
57+
EndTime: aws.Time(time.Unix(reqParam.Parameters.EndTime, 0)),
58+
Period: aws.Int64(reqParam.Parameters.Period),
59+
}
60+
61+
resp, err := svc.GetMetricStatistics(params)
62+
if err != nil {
63+
c.JsonApiErr(500, "Unable to call AWS API", err)
64+
return
65+
}
66+
67+
c.JSON(200, resp)
68+
}
69+
70+
func handleListMetrics(req *cwRequest, c *middleware.Context) {
71+
svc := cloudwatch.New(&aws.Config{Region: aws.String(req.Region)})
72+
reqParam := &struct {
73+
Parameters struct {
74+
Namespace string `json:"namespace"`
75+
MetricName string `json:"metricName"`
76+
Dimensions []*cloudwatch.DimensionFilter `json:"dimensions"`
77+
} `json:"parameters"`
78+
}{}
79+
80+
json.Unmarshal(req.Body, reqParam)
81+
82+
params := &cloudwatch.ListMetricsInput{
83+
Namespace: aws.String(reqParam.Parameters.Namespace),
84+
MetricName: aws.String(reqParam.Parameters.MetricName),
85+
Dimensions: reqParam.Parameters.Dimensions,
86+
}
87+
88+
resp, err := svc.ListMetrics(params)
89+
if err != nil {
90+
c.JsonApiErr(500, "Unable to call AWS API", err)
91+
return
92+
}
93+
94+
c.JSON(200, resp)
95+
}
96+
97+
func handleDescribeInstances(req *cwRequest, c *middleware.Context) {
98+
svc := ec2.New(&aws.Config{Region: aws.String(req.Region)})
99+
100+
reqParam := &struct {
101+
Parameters struct {
102+
Filters []*ec2.Filter `json:"filters"`
103+
InstanceIds []*string `json:"instanceIds"`
104+
} `json:"parameters"`
105+
}{}
106+
json.Unmarshal(req.Body, reqParam)
107+
108+
params := &ec2.DescribeInstancesInput{}
109+
if len(reqParam.Parameters.Filters) > 0 {
110+
params.Filters = reqParam.Parameters.Filters
111+
}
112+
if len(reqParam.Parameters.InstanceIds) > 0 {
113+
params.InstanceIDs = reqParam.Parameters.InstanceIds
114+
}
115+
116+
resp, err := svc.DescribeInstances(params)
117+
if err != nil {
118+
c.JsonApiErr(500, "Unable to call AWS API", err)
119+
return
120+
}
121+
122+
c.JSON(200, resp)
123+
}
124+
125+
func handleGetRegions(req *cwRequest, c *middleware.Context) {
126+
regions := []string{
127+
"us-west-2", "us-west-1", "eu-west-1", "eu-central-1", "ap-southeast-1",
128+
"ap-southeast-2", "ap-northeast-1", "sa-east-1",
129+
}
130+
131+
result := []interface{}{}
132+
for _, region := range regions {
133+
result = append(result, util.DynMap{"text": region, "value": region})
134+
}
135+
136+
c.JSON(200, result)
137+
}
138+
139+
func HandleRequest(c *middleware.Context) {
140+
var req cwRequest
141+
req.Body, _ = ioutil.ReadAll(c.Req.Request.Body)
142+
json.Unmarshal(req.Body, &req)
143+
144+
if handler, found := actionHandlers[req.Action]; !found {
145+
c.JsonApiErr(500, "Unexpected AWS Action", errors.New(req.Action))
146+
return
147+
} else {
148+
handler(&req, c)
149+
}
150+
}

pkg/api/dataproxy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/url"
99
"time"
1010

11+
"github.com/grafana/grafana/pkg/api/cloudwatch"
1112
"github.com/grafana/grafana/pkg/bus"
1213
"github.com/grafana/grafana/pkg/middleware"
1314
m "github.com/grafana/grafana/pkg/models"
@@ -83,7 +84,7 @@ func ProxyDataSourceRequest(c *middleware.Context) {
8384
}
8485

8586
if query.Result.Type == m.DS_CLOUDWATCH {
86-
ProxyCloudWatchDataSourceRequest(c)
87+
cloudwatch.HandleRequest(c)
8788
} else {
8889
proxyPath := c.Params("*")
8990
proxy := NewReverseProxy(&ds, proxyPath, targetUrl)

pkg/api/dataproxy_cloudwatch.go

Lines changed: 0 additions & 125 deletions
This file was deleted.

public/app/plugins/datasource/cloudwatch/datasource.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ function (angular, _) {
2020
this.defaultRegion = datasource.jsonData.defaultRegion;
2121

2222
/* jshint -W101 */
23-
this.supportedRegion = [
24-
'us-east-1', 'us-west-2', 'us-west-1', 'eu-west-1', 'eu-central-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'sa-east-1'
25-
];
2623

2724
this.supportedMetrics = {
2825
'AWS/AutoScaling': [
@@ -265,7 +262,6 @@ function (angular, _) {
265262
CloudWatchDatasource.prototype.performTimeSeriesQuery = function(query, start, end) {
266263
return this.awsRequest({
267264
region: query.region,
268-
service: 'CloudWatch',
269265
action: 'GetMetricStatistics',
270266
parameters: {
271267
namespace: query.namespace,
@@ -280,7 +276,7 @@ function (angular, _) {
280276
};
281277

282278
CloudWatchDatasource.prototype.getRegions = function() {
283-
return $q.when(this.supportedRegion);
279+
return this.awsRequest({action: '__GetRegions'});
284280
};
285281

286282
CloudWatchDatasource.prototype.getNamespaces = function() {
@@ -300,7 +296,6 @@ function (angular, _) {
300296
CloudWatchDatasource.prototype.getDimensionValues = function(region, namespace, metricName, dimensions) {
301297
var request = {
302298
region: templateSrv.replace(region),
303-
service: 'CloudWatch',
304299
action: 'ListMetrics',
305300
parameters: {
306301
namespace: templateSrv.replace(namespace),
@@ -321,7 +316,6 @@ function (angular, _) {
321316
CloudWatchDatasource.prototype.performEC2DescribeInstances = function(region, filters, instanceIds) {
322317
return this.awsRequest({
323318
region: region,
324-
service: 'EC2',
325319
action: 'DescribeInstances',
326320
parameters: {
327321
filter: filters,
@@ -341,12 +335,12 @@ function (angular, _) {
341335
});
342336
};
343337

344-
var regionQuery = query.match(/^region\(\)/);
338+
var regionQuery = query.match(/^regions\(\)/);
345339
if (regionQuery) {
346-
return this.getRegions().then(transformSuggestData);
340+
return this.getRegions();
347341
}
348342

349-
var namespaceQuery = query.match(/^namespace\(\)/);
343+
var namespaceQuery = query.match(/^namespaces\(\)/);
350344
if (namespaceQuery) {
351345
return this.getNamespaces().then(transformSuggestData);
352346
}

public/app/plugins/datasource/cloudwatch/query_ctrl.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ function (angular, _) {
2525
};
2626

2727
$scope.getRegions = function() {
28-
return $scope.datasource.metricFindQuery('region()')
28+
return $scope.datasource.metricFindQuery('regions()')
2929
.then($scope.transformToSegments(true));
3030
};
3131

3232
$scope.getNamespaces = function() {
33-
return $scope.datasource.metricFindQuery('namespace()')
33+
return $scope.datasource.metricFindQuery('namespaces()')
3434
.then($scope.transformToSegments(true));
3535
};
3636

0 commit comments

Comments
 (0)