mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
k8s/query+ds: catch query errors, fix datasourceProvider and expose prometheus (#85071)
This commit is contained in:
parent
2f3a01f79f
commit
e6fa367d02
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
@ -23,6 +23,20 @@
|
||||
"--secure-port=8443",
|
||||
"--runtime-config=testdata.datasource.grafana.app/v0alpha1=true"]
|
||||
},
|
||||
{
|
||||
"name": "Run API Server (query-localhost)",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/pkg/cmd/grafana/",
|
||||
"env": {},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["apiserver",
|
||||
"--secure-port=8443",
|
||||
"--runtime-config=query.grafana.app/v0alpha1=true",
|
||||
"--hg-url=http://localhost:3000",
|
||||
"--hg-key=$HGAPIKEY"]
|
||||
},
|
||||
{
|
||||
"name": "Attach to Chrome",
|
||||
"port": 9222,
|
||||
|
@ -31,6 +31,10 @@ type PluginDatasourceProvider interface {
|
||||
GetInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error)
|
||||
}
|
||||
|
||||
type ScopedPluginDatasourceProvider interface {
|
||||
GetDatasourceProvider(pluginJson plugins.JSONData) PluginDatasourceProvider
|
||||
}
|
||||
|
||||
// PluginContext requires adding system settings (feature flags, etc) to the datasource config
|
||||
type PluginContextWrapper interface {
|
||||
PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error)
|
||||
@ -39,18 +43,30 @@ type PluginContextWrapper interface {
|
||||
func ProvideDefaultPluginConfigs(
|
||||
dsService datasources.DataSourceService,
|
||||
dsCache datasources.CacheService,
|
||||
contextProvider *plugincontext.Provider) PluginDatasourceProvider {
|
||||
return &defaultPluginDatasourceProvider{
|
||||
plugin: plugins.JSONData{
|
||||
ID: datasources.DS_TESTDATA,
|
||||
},
|
||||
contextProvider *plugincontext.Provider) ScopedPluginDatasourceProvider {
|
||||
return &cachingDatasourceProvider{
|
||||
dsService: dsService,
|
||||
dsCache: dsCache,
|
||||
contextProvider: contextProvider,
|
||||
}
|
||||
}
|
||||
|
||||
type defaultPluginDatasourceProvider struct {
|
||||
type cachingDatasourceProvider struct {
|
||||
dsService datasources.DataSourceService
|
||||
dsCache datasources.CacheService
|
||||
contextProvider *plugincontext.Provider
|
||||
}
|
||||
|
||||
func (q *cachingDatasourceProvider) GetDatasourceProvider(pluginJson plugins.JSONData) PluginDatasourceProvider {
|
||||
return &scopedDatasourceProvider{
|
||||
plugin: pluginJson,
|
||||
dsService: q.dsService,
|
||||
dsCache: q.dsCache,
|
||||
contextProvider: q.contextProvider,
|
||||
}
|
||||
}
|
||||
|
||||
type scopedDatasourceProvider struct {
|
||||
plugin plugins.JSONData
|
||||
dsService datasources.DataSourceService
|
||||
dsCache datasources.CacheService
|
||||
@ -58,10 +74,11 @@ type defaultPluginDatasourceProvider struct {
|
||||
}
|
||||
|
||||
var (
|
||||
_ PluginDatasourceProvider = (*defaultPluginDatasourceProvider)(nil)
|
||||
_ PluginDatasourceProvider = (*scopedDatasourceProvider)(nil)
|
||||
_ ScopedPluginDatasourceProvider = (*cachingDatasourceProvider)(nil)
|
||||
)
|
||||
|
||||
func (q *defaultPluginDatasourceProvider) Get(ctx context.Context, uid string) (*v0alpha1.DataSourceConnection, error) {
|
||||
func (q *scopedDatasourceProvider) Get(ctx context.Context, uid string) (*v0alpha1.DataSourceConnection, error) {
|
||||
info, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -77,7 +94,7 @@ func (q *defaultPluginDatasourceProvider) Get(ctx context.Context, uid string) (
|
||||
return asConnection(ds, info.Value)
|
||||
}
|
||||
|
||||
func (q *defaultPluginDatasourceProvider) List(ctx context.Context) (*v0alpha1.DataSourceConnectionList, error) {
|
||||
func (q *scopedDatasourceProvider) List(ctx context.Context) (*v0alpha1.DataSourceConnectionList, error) {
|
||||
info, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -101,11 +118,9 @@ func (q *defaultPluginDatasourceProvider) List(ctx context.Context) (*v0alpha1.D
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (q *defaultPluginDatasourceProvider) GetInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) {
|
||||
func (q *scopedDatasourceProvider) GetInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) {
|
||||
if q.contextProvider == nil {
|
||||
// NOTE!!! this is only here for the standalone example
|
||||
// if we cleanup imports this can throw an error
|
||||
return nil, nil
|
||||
return nil, fmt.Errorf("missing contextProvider")
|
||||
}
|
||||
return q.contextProvider.GetDataSourceInstanceSettings(ctx, uid)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func RegisterAPIService(
|
||||
features featuremgmt.FeatureToggles,
|
||||
apiRegistrar builder.APIRegistrar,
|
||||
pluginClient plugins.Client, // access to everything
|
||||
datasources PluginDatasourceProvider,
|
||||
datasources ScopedPluginDatasourceProvider,
|
||||
contextProvider PluginContextWrapper,
|
||||
pluginStore pluginstore.Store,
|
||||
accessControl accesscontrol.AccessControl,
|
||||
@ -69,7 +69,8 @@ func RegisterAPIService(
|
||||
all := pluginStore.Plugins(context.Background(), plugins.TypeDataSource)
|
||||
ids := []string{
|
||||
"grafana-testdata-datasource",
|
||||
// "prometheus",
|
||||
"prometheus",
|
||||
"graphite",
|
||||
}
|
||||
|
||||
for _, ds := range all {
|
||||
@ -79,7 +80,7 @@ func RegisterAPIService(
|
||||
|
||||
builder, err = NewDataSourceAPIBuilder(ds.JSONData,
|
||||
pluginClient,
|
||||
datasources,
|
||||
datasources.GetDatasourceProvider(ds.JSONData),
|
||||
contextProvider,
|
||||
accessControl,
|
||||
)
|
||||
|
@ -119,7 +119,7 @@ func (b *QueryAPIBuilder) handleQuerySingleDatasource(ctx context.Context, req d
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, rsp, err := client.QueryData(ctx, *req.Request)
|
||||
code, rsp, err := client.QueryData(ctx, *req.Request)
|
||||
if err == nil && rsp != nil {
|
||||
for _, q := range req.Request.Queries {
|
||||
if q.ResultAssertions != nil {
|
||||
@ -135,6 +135,17 @@ func (b *QueryAPIBuilder) handleQuerySingleDatasource(ctx context.Context, req d
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a response object with the error when missing (happens for client errors like 404)
|
||||
if rsp == nil && err != nil {
|
||||
rsp = &backend.QueryDataResponse{Responses: make(backend.Responses)}
|
||||
for _, q := range req.Request.Queries {
|
||||
rsp.Responses[q.RefID] = backend.DataResponse{
|
||||
Status: backend.Status(code),
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
@ -229,6 +240,9 @@ func (b *QueryAPIBuilder) handleExpressions(ctx context.Context, req parsedReque
|
||||
if qdr == nil {
|
||||
qdr = &backend.QueryDataResponse{}
|
||||
}
|
||||
if qdr.Responses == nil {
|
||||
qdr.Responses = make(backend.Responses) // avoid NPE for lookup
|
||||
}
|
||||
now := start // <<< this should come from the original query parser
|
||||
vars := make(mathexp.Vars)
|
||||
for _, expression := range req.Expressions {
|
||||
|
Loading…
Reference in New Issue
Block a user