Advisor: Run check steps in parallel (#100200)
This commit is contained in:
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type check struct {
|
||||
@@ -76,26 +75,23 @@ func (s *uidValidationStep) Description() string {
|
||||
return "Check if the UID of each data source is valid."
|
||||
}
|
||||
|
||||
func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, items []any) ([]advisor.CheckReportError, error) {
|
||||
dsErrs := []advisor.CheckReportError{}
|
||||
for _, i := range items {
|
||||
ds, ok := i.(*datasources.DataSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
// Data source UID validation
|
||||
err := util.ValidateUID(ds.UID)
|
||||
if err != nil {
|
||||
dsErrs = append(dsErrs, checks.NewCheckReportError(
|
||||
advisor.CheckReportErrorSeverityLow,
|
||||
fmt.Sprintf("Invalid UID '%s' for data source %s", ds.UID, ds.Name),
|
||||
"Check the <a href='https://grafana.com/docs/grafana/latest/upgrade-guide/upgrade-v11.2/#grafana-data-source-uid-format-enforcement' target=_blank>documentation</a> for more information.",
|
||||
s.ID(),
|
||||
ds.UID,
|
||||
))
|
||||
}
|
||||
func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportError, error) {
|
||||
ds, ok := i.(*datasources.DataSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
return dsErrs, nil
|
||||
// Data source UID validation
|
||||
err := util.ValidateUID(ds.UID)
|
||||
if err != nil {
|
||||
return checks.NewCheckReportError(
|
||||
advisor.CheckReportErrorSeverityLow,
|
||||
fmt.Sprintf("Invalid UID '%s' for data source %s", ds.UID, ds.Name),
|
||||
"Check the <a href='https://grafana.com/docs/grafana/latest/upgrade-guide/upgrade-v11.2/#grafana-data-source-uid-format-enforcement' target=_blank>documentation</a> for more information.",
|
||||
s.ID(),
|
||||
ds.UID,
|
||||
), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type healthCheckStep struct {
|
||||
@@ -115,46 +111,38 @@ func (s *healthCheckStep) ID() string {
|
||||
return "health-check"
|
||||
}
|
||||
|
||||
func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, items []any) ([]advisor.CheckReportError, error) {
|
||||
dsErrs := []advisor.CheckReportError{}
|
||||
for _, i := range items {
|
||||
ds, ok := i.(*datasources.DataSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
|
||||
// Health check execution
|
||||
requester, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pCtx, err := s.PluginContextProvider.GetWithDataSource(ctx, ds.Type, requester, ds)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Error creating plugin context", "datasource", ds.Name)
|
||||
continue
|
||||
}
|
||||
req := &backend.CheckHealthRequest{
|
||||
PluginContext: pCtx,
|
||||
Headers: map[string]string{},
|
||||
}
|
||||
resp, err := s.PluginClient.CheckHealth(ctx, req)
|
||||
if err != nil {
|
||||
fmt.Println("Error checking health", err)
|
||||
continue
|
||||
}
|
||||
if resp.Status != backend.HealthStatusOk {
|
||||
dsErrs = append(dsErrs, checks.NewCheckReportError(
|
||||
advisor.CheckReportErrorSeverityHigh,
|
||||
fmt.Sprintf("Health check failed for %s", ds.Name),
|
||||
fmt.Sprintf(
|
||||
"Go to the <a href='/connections/datasources/edit/%s'>data source configuration</a>"+
|
||||
" and address the issues reported.", ds.UID),
|
||||
s.ID(),
|
||||
ds.UID,
|
||||
))
|
||||
}
|
||||
func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportError, error) {
|
||||
ds, ok := i.(*datasources.DataSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
return dsErrs, nil
|
||||
|
||||
// Health check execution
|
||||
requester, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pCtx, err := s.PluginContextProvider.GetWithDataSource(ctx, ds.Type, requester, ds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get plugin context: %w", err)
|
||||
}
|
||||
req := &backend.CheckHealthRequest{
|
||||
PluginContext: pCtx,
|
||||
Headers: map[string]string{},
|
||||
}
|
||||
resp, err := s.PluginClient.CheckHealth(ctx, req)
|
||||
if err != nil || resp.Status != backend.HealthStatusOk {
|
||||
return checks.NewCheckReportError(
|
||||
advisor.CheckReportErrorSeverityHigh,
|
||||
fmt.Sprintf("Health check failed for %s", ds.Name),
|
||||
fmt.Sprintf(
|
||||
"Go to the <a href='/connections/datasources/edit/%s'>data source configuration</a>"+
|
||||
" and address the issues reported.", ds.UID),
|
||||
s.ID(),
|
||||
ds.UID,
|
||||
), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type pluginContextProvider interface {
|
||||
|
||||
@@ -35,9 +35,13 @@ func TestCheck_Run(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
errs := []advisor.CheckReportError{}
|
||||
for _, step := range check.Steps() {
|
||||
stepErrs, err := step.Run(ctx, &advisor.CheckSpec{}, items)
|
||||
assert.NoError(t, err)
|
||||
errs = append(errs, stepErrs...)
|
||||
for _, item := range items {
|
||||
stepErr, err := step.Run(ctx, &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepErr != nil {
|
||||
errs = append(errs, *stepErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
@@ -65,9 +69,13 @@ func TestCheck_Run(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
errs := []advisor.CheckReportError{}
|
||||
for _, step := range check.Steps() {
|
||||
stepErrs, err := step.Run(ctx, &advisor.CheckSpec{}, items)
|
||||
assert.NoError(t, err)
|
||||
errs = append(errs, stepErrs...)
|
||||
for _, item := range items {
|
||||
stepErr, err := step.Run(ctx, &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepErr != nil {
|
||||
errs = append(errs, *stepErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
@@ -96,9 +104,13 @@ func TestCheck_Run(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
errs := []advisor.CheckReportError{}
|
||||
for _, step := range check.Steps() {
|
||||
stepErrs, err := step.Run(ctx, &advisor.CheckSpec{}, items)
|
||||
assert.NoError(t, err)
|
||||
errs = append(errs, stepErrs...)
|
||||
for _, item := range items {
|
||||
stepErr, err := step.Run(ctx, &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepErr != nil {
|
||||
errs = append(errs, *stepErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user