Influx: Support flux in the influx datasource (#25308)

* add flux 
* add token to datasource config editor
* add backend for flux
* make the interpolated query available in query inspector
* go mod tidy
* Chore: fixes a couple of strict null errors in influxdb plugin

Co-authored-by: kyle <kyle@grafana.com>
Co-authored-by: Lukas Siatka <lukasz.siatka@grafana.com>
This commit is contained in:
Ryan McKinley
2020-06-10 15:26:24 -04:00
committed by GitHub
co-authored by kyle Lukas Siatka
parent c7aac1fd40
commit 5f1f820bb9
24 changed files with 1449 additions and 55 deletions
+88
View File
@@ -0,0 +1,88 @@
package flux
import (
"context"
"fmt"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
influxdb2 "github.com/influxdata/influxdb-client-go"
)
// ExecuteQuery runs a flux query using the QueryModel to interpolate the query and the runner to execute it.
// maxSeries somehow limits the response.
func ExecuteQuery(ctx context.Context, query QueryModel, runner queryRunner, maxSeries int) (dr backend.DataResponse) {
dr = backend.DataResponse{}
flux, err := Interpolate(query)
if err != nil {
dr.Error = err
return
}
glog.Debug("Flux", "interpolated query", flux)
tables, err := runner.runQuery(ctx, flux)
if err != nil {
dr.Error = err
return
}
dr = readDataFrames(tables, int(float64(query.MaxDataPoints)*1.5), maxSeries)
for _, frame := range dr.Frames {
if frame.Meta == nil {
frame.Meta = &data.FrameMeta{}
}
frame.Meta.ExecutedQueryString = flux
}
return dr
}
func readDataFrames(result *influxdb2.QueryTableResult, maxPoints int, maxSeries int) (dr backend.DataResponse) {
dr = backend.DataResponse{}
builder := &FrameBuilder{
maxPoints: maxPoints,
maxSeries: maxSeries,
}
for result.Next() {
// Observe when there is new grouping key producing new table
if result.TableChanged() {
if builder.frames != nil {
for _, frame := range builder.frames {
dr.Frames = append(dr.Frames, frame)
}
}
err := builder.Init(result.TableMetadata())
if err != nil {
dr.Error = err
return
}
}
if builder.frames == nil {
dr.Error = fmt.Errorf("Invalid state")
return dr
}
err := builder.Append(result.Record())
if err != nil {
dr.Error = err
break
}
}
// Add the inprogress record
if builder.frames != nil {
for _, frame := range builder.frames {
dr.Frames = append(dr.Frames, frame)
}
}
// Attach any errors (may be null)
dr.Error = result.Err()
return dr
}