k8s/query+ds: catch query errors, fix datasourceProvider and expose prometheus (#85071)

pull/85219/head
Ryan McKinley 1 year ago committed by GitHub
parent 2f3a01f79f
commit e6fa367d02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      .vscode/launch.json
  2. 41
      pkg/registry/apis/datasource/plugincontext.go
  3. 7
      pkg/registry/apis/datasource/register.go
  4. 16
      pkg/registry/apis/query/query.go

@ -23,6 +23,20 @@
"--secure-port=8443", "--secure-port=8443",
"--runtime-config=testdata.datasource.grafana.app/v0alpha1=true"] "--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", "name": "Attach to Chrome",
"port": 9222, "port": 9222,

@ -31,6 +31,10 @@ type PluginDatasourceProvider interface {
GetInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) 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 // PluginContext requires adding system settings (feature flags, etc) to the datasource config
type PluginContextWrapper interface { type PluginContextWrapper interface {
PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error) PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error)
@ -39,18 +43,30 @@ type PluginContextWrapper interface {
func ProvideDefaultPluginConfigs( func ProvideDefaultPluginConfigs(
dsService datasources.DataSourceService, dsService datasources.DataSourceService,
dsCache datasources.CacheService, dsCache datasources.CacheService,
contextProvider *plugincontext.Provider) PluginDatasourceProvider { contextProvider *plugincontext.Provider) ScopedPluginDatasourceProvider {
return &defaultPluginDatasourceProvider{ return &cachingDatasourceProvider{
plugin: plugins.JSONData{
ID: datasources.DS_TESTDATA,
},
dsService: dsService, dsService: dsService,
dsCache: dsCache, dsCache: dsCache,
contextProvider: contextProvider, 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 plugin plugins.JSONData
dsService datasources.DataSourceService dsService datasources.DataSourceService
dsCache datasources.CacheService dsCache datasources.CacheService
@ -58,10 +74,11 @@ type defaultPluginDatasourceProvider struct {
} }
var ( 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) info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
@ -77,7 +94,7 @@ func (q *defaultPluginDatasourceProvider) Get(ctx context.Context, uid string) (
return asConnection(ds, info.Value) 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) info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
@ -101,11 +118,9 @@ func (q *defaultPluginDatasourceProvider) List(ctx context.Context) (*v0alpha1.D
return result, nil 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 { if q.contextProvider == nil {
// NOTE!!! this is only here for the standalone example return nil, fmt.Errorf("missing contextProvider")
// if we cleanup imports this can throw an error
return nil, nil
} }
return q.contextProvider.GetDataSourceInstanceSettings(ctx, uid) return q.contextProvider.GetDataSourceInstanceSettings(ctx, uid)
} }

@ -54,7 +54,7 @@ func RegisterAPIService(
features featuremgmt.FeatureToggles, features featuremgmt.FeatureToggles,
apiRegistrar builder.APIRegistrar, apiRegistrar builder.APIRegistrar,
pluginClient plugins.Client, // access to everything pluginClient plugins.Client, // access to everything
datasources PluginDatasourceProvider, datasources ScopedPluginDatasourceProvider,
contextProvider PluginContextWrapper, contextProvider PluginContextWrapper,
pluginStore pluginstore.Store, pluginStore pluginstore.Store,
accessControl accesscontrol.AccessControl, accessControl accesscontrol.AccessControl,
@ -69,7 +69,8 @@ func RegisterAPIService(
all := pluginStore.Plugins(context.Background(), plugins.TypeDataSource) all := pluginStore.Plugins(context.Background(), plugins.TypeDataSource)
ids := []string{ ids := []string{
"grafana-testdata-datasource", "grafana-testdata-datasource",
// "prometheus", "prometheus",
"graphite",
} }
for _, ds := range all { for _, ds := range all {
@ -79,7 +80,7 @@ func RegisterAPIService(
builder, err = NewDataSourceAPIBuilder(ds.JSONData, builder, err = NewDataSourceAPIBuilder(ds.JSONData,
pluginClient, pluginClient,
datasources, datasources.GetDatasourceProvider(ds.JSONData),
contextProvider, contextProvider,
accessControl, accessControl,
) )

@ -119,7 +119,7 @@ func (b *QueryAPIBuilder) handleQuerySingleDatasource(ctx context.Context, req d
return nil, err return nil, err
} }
_, rsp, err := client.QueryData(ctx, *req.Request) code, rsp, err := client.QueryData(ctx, *req.Request)
if err == nil && rsp != nil { if err == nil && rsp != nil {
for _, q := range req.Request.Queries { for _, q := range req.Request.Queries {
if q.ResultAssertions != nil { 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 return rsp, err
} }
@ -229,6 +240,9 @@ func (b *QueryAPIBuilder) handleExpressions(ctx context.Context, req parsedReque
if qdr == nil { if qdr == nil {
qdr = &backend.QueryDataResponse{} 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 now := start // <<< this should come from the original query parser
vars := make(mathexp.Vars) vars := make(mathexp.Vars)
for _, expression := range req.Expressions { for _, expression := range req.Expressions {

Loading…
Cancel
Save