//ProxyDataSourceRequest TODO need to cache datasources func ProxyDataSourceRequest(c *middleware.Context) { id := c.ParamsInt64(":id") query := m.GetDataSourceByIdQuery{Id: id, OrgId: c.OrgId} if err := bus.Dispatch(&query); err != nil { c.JsonApiErr(500, "Unable to load datasource meta data", err) return } ds := query.Result targetUrl, _ := url.Parse(ds.Url) if len(setting.DataProxyWhiteList) > 0 { if _, exists := setting.DataProxyWhiteList[targetUrl.Host]; !exists { c.JsonApiErr(403, "Data proxy hostname and ip are not included in whitelist", nil) return } } if query.Result.Type == m.DS_CLOUDWATCH { cloudwatch.HandleRequest(c) } else { proxyPath := c.Params("*") proxy := NewReverseProxy(&ds, proxyPath, targetUrl) proxy.Transport = dataProxyTransport proxy.ServeHTTP(c.RW(), c.Req.Request) } }
func GraphiteProxy(c *middleware.Context) { proxyPath := c.Params("*") target, _ := url.Parse(setting.GraphiteUrl) // check if this is a special raintank_db requests if proxyPath == "metrics/find" { query := c.Query("query") if strings.HasPrefix(query, "raintank_db") { response, err := executeRaintankDbQuery(query, c.OrgId) if err != nil { c.JsonApiErr(500, "Failed to execute raintank_db query", err) return } c.JSON(200, response) return } } director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.Header.Add("X-Org-Id", strconv.FormatInt(c.OrgId, 10)) req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) } proxy := &httputil.ReverseProxy{Director: director} proxy.ServeHTTP(c.RW(), c.Req.Request) }
//ProxyDataSourceRequest TODO need to cache datasources func ProxyDataSourceRequest(c *middleware.Context) { id := c.ParamsInt64(":id") query := m.GetDataSourceByIdQuery{Id: id, OrgId: c.OrgId} if err := bus.Dispatch(&query); err != nil { c.JsonApiErr(500, "Unable to load datasource meta data", err) return } proxyPath := c.Params("*") proxy := NewReverseProxy(&query.Result, proxyPath) proxy.Transport = dataProxyTransport proxy.ServeHTTP(c.RW(), c.Req.Request) }
func ProxyCloudWatchDataSourceRequest(c *middleware.Context) { body, _ := ioutil.ReadAll(c.Req.Request.Body) reqInfo := &struct { Region string `json:"region"` Service string `json:"service"` Action string `json:"action"` }{} json.Unmarshal([]byte(body), reqInfo) svc := cloudwatch.New(&aws.Config{Region: aws.String(reqInfo.Region)}) switch reqInfo.Action { case "GetMetricStatistics": reqParam := &struct { Parameters struct { Namespace string `json:"Namespace"` MetricName string `json:"MetricName"` Dimensions []map[string]string `json:"Dimensions"` Statistics []string `json:"Statistics"` StartTime int64 `json:"StartTime"` EndTime int64 `json:"EndTime"` Period int64 `json:"Period"` } `json:"parameters"` }{} json.Unmarshal([]byte(body), reqParam) statistics := make([]*string, 0) for k := range reqParam.Parameters.Statistics { statistics = append(statistics, &reqParam.Parameters.Statistics[k]) } dimensions := make([]*cloudwatch.Dimension, 0) for _, d := range reqParam.Parameters.Dimensions { dimensions = append(dimensions, &cloudwatch.Dimension{ Name: aws.String(d["Name"]), Value: aws.String(d["Value"]), }) } params := &cloudwatch.GetMetricStatisticsInput{ Namespace: aws.String(reqParam.Parameters.Namespace), MetricName: aws.String(reqParam.Parameters.MetricName), Dimensions: dimensions, Statistics: statistics, StartTime: aws.Time(time.Unix(reqParam.Parameters.StartTime, 0)), EndTime: aws.Time(time.Unix(reqParam.Parameters.EndTime, 0)), Period: aws.Int64(reqParam.Parameters.Period), } resp, err := svc.GetMetricStatistics(params) if err != nil { c.JsonApiErr(500, "Unable to call AWS API", err) return } respJson, _ := json.Marshal(resp) fmt.Fprint(c.RW(), string(respJson)) case "ListMetrics": reqParam := &struct { Parameters struct { Namespace string `json:"Namespace"` MetricName string `json:"MetricName"` Dimensions []map[string]string `json:"Dimensions"` } `json:"parameters"` }{} json.Unmarshal([]byte(body), reqParam) dimensions := make([]*cloudwatch.DimensionFilter, 0) for _, d := range reqParam.Parameters.Dimensions { dimensions = append(dimensions, &cloudwatch.DimensionFilter{ Name: aws.String(d["Name"]), Value: aws.String(d["Value"]), }) } params := &cloudwatch.ListMetricsInput{ Namespace: aws.String(reqParam.Parameters.Namespace), MetricName: aws.String(reqParam.Parameters.MetricName), Dimensions: dimensions, } resp, err := svc.ListMetrics(params) if err != nil { c.JsonApiErr(500, "Unable to call AWS API", err) return } respJson, _ := json.Marshal(resp) fmt.Fprint(c.RW(), string(respJson)) default: c.JsonApiErr(500, "Unexpected CloudWatch action", errors.New(reqInfo.Action)) } }