Files
grafana/pkg/tsdb/prometheus/resource/resource.go
T
Galen Kistler 5647a981ed Prometheus: Flavor/version configuration (#57554) (#57563)
* Backport PR for: Prometheus: Flavor/version configuration (#57554), and /label match parameter support #56510

* Revert "Revert "Prometheus: Type and flavor configuration (#56496)" (#57552)"
This reverts commit 2432ce619a.
* Adds new fields and documentation for Prometheus datasource configuration: prometheus type, and version

(cherry picked from commit f93c3acc51)

* Revert "Revert "Prometheus: Provide label values match parameter API when supported prometheus instance is configured (#56510)" (#57551)" (#57553) (#57564)

This reverts commit e7671bf909.
(cherry picked from commit e59ddd6bc5)
Co-authored-by: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com>

Co-authored-by: Grot (@grafanabot) <43478413+grafanabot@users.noreply.github.com>
2022-10-26 08:10:05 -05:00

121 lines
2.6 KiB
Go

package resource
import (
"bytes"
"context"
"fmt"
"net/http"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/tsdb/prometheus/client"
"github.com/grafana/grafana/pkg/tsdb/prometheus/utils"
"github.com/grafana/grafana/pkg/util/maputil"
)
type Resource struct {
promClient *client.Client
log log.Logger
}
// Hop-by-hop headers. These are removed when sent to the backend.
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
var hopHeaders = []string{
"Connection",
"Keep-Alive",
"Proxy-Authenticate",
"Proxy-Authorization",
"Te", // canonicalized version of "TE"
"Trailers",
"Transfer-Encoding",
"Upgrade",
}
// The following headers will be removed from the request
var stopHeaders = []string{
"cookie",
"Cookie",
}
func delHopHeaders(header http.Header) {
for _, h := range hopHeaders {
header.Del(h)
}
}
func delStopHeaders(header http.Header) {
for _, h := range stopHeaders {
header.Del(h)
}
}
func New(
httpClient *http.Client,
settings backend.DataSourceInstanceSettings,
plog log.Logger,
) (*Resource, error) {
jsonData, err := utils.GetJsonData(settings)
if err != nil {
return nil, err
}
httpMethod, _ := maputil.GetStringOptional(jsonData, "httpMethod")
return &Resource{
log: plog,
promClient: client.NewClient(httpClient, httpMethod, settings.URL),
}, nil
}
func (r *Resource) Execute(ctx context.Context, req *backend.CallResourceRequest) (*backend.CallResourceResponse, error) {
delHopHeaders(req.Headers)
delStopHeaders(req.Headers)
r.log.Debug("Sending resource query", "URL", req.URL)
resp, err := r.promClient.QueryResource(ctx, req)
if err != nil {
return nil, fmt.Errorf("error querying resource: %v", err)
}
defer func() {
tmpErr := resp.Body.Close()
if tmpErr != nil && err == nil {
err = tmpErr
}
}()
var buf bytes.Buffer
// Should be more efficient than ReadAll. See https://github.com/prometheus/client_golang/pull/976
_, err = buf.ReadFrom(resp.Body)
body := buf.Bytes()
if err != nil {
return nil, err
}
callResponse := &backend.CallResourceResponse{
Status: resp.StatusCode,
Headers: resp.Header,
Body: body,
}
return callResponse, err
}
func (r *Resource) DetectVersion(ctx context.Context, req *backend.CallResourceRequest) (*backend.CallResourceResponse, error) {
newReq := &backend.CallResourceRequest{
PluginContext: req.PluginContext,
Path: "/api/v1/status/buildinfo",
}
resp, err := r.Execute(ctx, newReq)
if err != nil {
return nil, err
}
callResponse := &backend.CallResourceResponse{
Status: 200,
Body: resp.Body,
}
return callResponse, nil
}