diff --git a/apps/advisor/kinds/check.cue b/apps/advisor/kinds/check.cue
index 7ae338e888e..4aea38d6759 100644
--- a/apps/advisor/kinds/check.cue
+++ b/apps/advisor/kinds/check.cue
@@ -21,17 +21,21 @@ check: {
// Generic data input that a check can receive
data?: [string]: string
}
+ #ErrorLink: {
+ // URL to a page with more information about the error
+ url: string
+ // Human readable error message
+ message: string
+ }
#ReportFailure: {
// Severity of the failure
severity: "high" | "low"
- // Human readable reason for the failure
- reason: string
- // Action to take to resolve the failure
- action: string
// Step ID that the failure is associated with
stepID: string
- // Item ID that the failure is associated with
- itemID: string
+ // Human readable identifier of the item that failed
+ item: string
+ // Links to actions that can be taken to resolve the failure
+ links: [...#ErrorLink]
}
#Report: {
// Number of elements analyzed
diff --git a/apps/advisor/kinds/checktype.cue b/apps/advisor/kinds/checktype.cue
index aa31430ad2e..e2d653e629e 100644
--- a/apps/advisor/kinds/checktype.cue
+++ b/apps/advisor/kinds/checktype.cue
@@ -15,6 +15,7 @@ checktype: {
title: string
description: string
stepID: string
+ resolution: string
}
spec: {
name: string
diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go
index 342751c6ac3..c9acc5ce31c 100644
--- a/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go
+++ b/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go
@@ -2,18 +2,29 @@
package v0alpha1
+// +k8s:openapi-gen=true
+type CheckErrorLink struct {
+ // URL to a page with more information about the error
+ Url string `json:"url"`
+ // Human readable error message
+ Message string `json:"message"`
+}
+
+// NewCheckErrorLink creates a new CheckErrorLink object.
+func NewCheckErrorLink() *CheckErrorLink {
+ return &CheckErrorLink{}
+}
+
// +k8s:openapi-gen=true
type CheckReportFailure struct {
// Severity of the failure
Severity CheckReportFailureSeverity `json:"severity"`
- // Human readable reason for the failure
- Reason string `json:"reason"`
- // Action to take to resolve the failure
- Action string `json:"action"`
// Step ID that the failure is associated with
StepID string `json:"stepID"`
- // Item ID that the failure is associated with
- ItemID string `json:"itemID"`
+ // Human readable identifier of the item that failed
+ Item string `json:"item"`
+ // Links to actions that can be taken to resolve the failure
+ Links []CheckErrorLink `json:"links"`
}
// NewCheckReportFailure creates a new CheckReportFailure object.
diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go
index a0392a49c18..528643b69dd 100644
--- a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go
+++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go
@@ -7,6 +7,7 @@ type CheckTypeStep struct {
Title string `json:"title"`
Description string `json:"description"`
StepID string `json:"stepID"`
+ Resolution string `json:"resolution"`
}
// NewCheckTypeStep creates a new CheckTypeStep object.
diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go
index 6f84fa9ef4c..79d78cd2766 100644
--- a/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go
+++ b/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go
@@ -13,6 +13,7 @@ import (
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.Check": schema_pkg_apis_advisor_v0alpha1_Check(ref),
+ "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckErrorLink": schema_pkg_apis_advisor_v0alpha1_CheckErrorLink(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckList": schema_pkg_apis_advisor_v0alpha1_CheckList(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure": schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec": schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref),
@@ -75,6 +76,35 @@ func schema_pkg_apis_advisor_v0alpha1_Check(ref common.ReferenceCallback) common
}
}
+func schema_pkg_apis_advisor_v0alpha1_CheckErrorLink(ref common.ReferenceCallback) common.OpenAPIDefinition {
+ return common.OpenAPIDefinition{
+ Schema: spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "url": {
+ SchemaProps: spec.SchemaProps{
+ Description: "URL to a page with more information about the error",
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "message": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Human readable error message",
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ },
+ Required: []string{"url", "message"},
+ },
+ },
+ }
+}
+
func schema_pkg_apis_advisor_v0alpha1_CheckList(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@@ -137,22 +167,6 @@ func schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref common.ReferenceCal
Format: "",
},
},
- "reason": {
- SchemaProps: spec.SchemaProps{
- Description: "Human readable reason for the failure",
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
- "action": {
- SchemaProps: spec.SchemaProps{
- Description: "Action to take to resolve the failure",
- Default: "",
- Type: []string{"string"},
- Format: "",
- },
- },
"stepID": {
SchemaProps: spec.SchemaProps{
Description: "Step ID that the failure is associated with",
@@ -161,18 +175,34 @@ func schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref common.ReferenceCal
Format: "",
},
},
- "itemID": {
+ "item": {
SchemaProps: spec.SchemaProps{
- Description: "Item ID that the failure is associated with",
+ Description: "Human readable identifier of the item that failed",
Default: "",
Type: []string{"string"},
Format: "",
},
},
+ "links": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Links to actions that can be taken to resolve the failure",
+ Type: []string{"array"},
+ Items: &spec.SchemaOrArray{
+ Schema: &spec.Schema{
+ SchemaProps: spec.SchemaProps{
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckErrorLink"),
+ },
+ },
+ },
+ },
+ },
},
- Required: []string{"severity", "reason", "action", "stepID", "itemID"},
+ Required: []string{"severity", "stepID", "item", "links"},
},
},
+ Dependencies: []string{
+ "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckErrorLink"},
}
}
@@ -456,8 +486,15 @@ func schema_pkg_apis_advisor_v0alpha1_CheckTypeStep(ref common.ReferenceCallback
Format: "",
},
},
+ "resolution": {
+ SchemaProps: spec.SchemaProps{
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
},
- Required: []string{"title", "description", "stepID"},
+ Required: []string{"title", "description", "stepID", "resolution"},
},
},
}
diff --git a/apps/advisor/pkg/apis/advisor_manifest.go b/apps/advisor/pkg/apis/advisor_manifest.go
index 4048f4f687a..e333774303f 100644
--- a/apps/advisor/pkg/apis/advisor_manifest.go
+++ b/apps/advisor/pkg/apis/advisor_manifest.go
@@ -12,10 +12,10 @@ import (
)
var (
- rawSchemaCheckv0alpha1 = []byte(`{"spec":{"properties":{"data":{"additionalProperties":{"type":"string"},"description":"Generic data input that a check can receive","type":"object"}},"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"},"report":{"properties":{"count":{"description":"Number of elements analyzed","type":"integer"},"failures":{"description":"List of failures","items":{"properties":{"action":{"description":"Action to take to resolve the failure","type":"string"},"itemID":{"description":"Item ID that the failure is associated with","type":"string"},"reason":{"description":"Human readable reason for the failure","type":"string"},"severity":{"description":"Severity of the failure","enum":["high","low"],"type":"string"},"stepID":{"description":"Step ID that the failure is associated with","type":"string"}},"required":["severity","reason","action","stepID","itemID"],"type":"object"},"type":"array"}},"required":["count","failures"],"type":"object"}},"required":["report"],"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
+ rawSchemaCheckv0alpha1 = []byte(`{"spec":{"properties":{"data":{"additionalProperties":{"type":"string"},"description":"Generic data input that a check can receive","type":"object"}},"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"},"report":{"properties":{"count":{"description":"Number of elements analyzed","type":"integer"},"failures":{"description":"List of failures","items":{"properties":{"item":{"description":"Human readable identifier of the item that failed","type":"string"},"links":{"description":"Links to actions that can be taken to resolve the failure","items":{"properties":{"message":{"description":"Human readable error message","type":"string"},"url":{"description":"URL to a page with more information about the error","type":"string"}},"required":["url","message"],"type":"object"},"type":"array"},"severity":{"description":"Severity of the failure","enum":["high","low"],"type":"string"},"stepID":{"description":"Step ID that the failure is associated with","type":"string"}},"required":["severity","stepID","item","links"],"type":"object"},"type":"array"}},"required":["count","failures"],"type":"object"}},"required":["report"],"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
versionSchemaCheckv0alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaCheckv0alpha1, &versionSchemaCheckv0alpha1)
- rawSchemaCheckTypev0alpha1 = []byte(`{"spec":{"properties":{"name":{"type":"string"},"steps":{"items":{"properties":{"description":{"type":"string"},"stepID":{"type":"string"},"title":{"type":"string"}},"required":["title","description","stepID"],"type":"object"},"type":"array"}},"required":["name","steps"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
+ rawSchemaCheckTypev0alpha1 = []byte(`{"spec":{"properties":{"name":{"type":"string"},"steps":{"items":{"properties":{"description":{"type":"string"},"resolution":{"type":"string"},"stepID":{"type":"string"},"title":{"type":"string"}},"required":["title","description","stepID","resolution"],"type":"object"},"type":"array"}},"required":["name","steps"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
versionSchemaCheckTypev0alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaCheckTypev0alpha1, &versionSchemaCheckTypev0alpha1)
)
diff --git a/apps/advisor/pkg/app/checks/datasourcecheck/check.go b/apps/advisor/pkg/app/checks/datasourcecheck/check.go
index ff11740c62e..2cab8e3f903 100644
--- a/apps/advisor/pkg/app/checks/datasourcecheck/check.go
+++ b/apps/advisor/pkg/app/checks/datasourcecheck/check.go
@@ -12,6 +12,7 @@ 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 {
@@ -72,7 +73,12 @@ func (s *uidValidationStep) Title() string {
}
func (s *uidValidationStep) Description() string {
- return "Check if the UID of each data source is valid."
+ return "Checks if the UID of a data source is valid."
+}
+
+func (s *uidValidationStep) Resolution() string {
+ return "Check the documentation for more information or delete the data source and create a new one."
}
func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
@@ -85,10 +91,9 @@ func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i a
if err != nil {
return checks.NewCheckReportFailure(
advisor.CheckReportFailureSeverityLow,
- fmt.Sprintf("Invalid UID '%s' for data source %s", ds.UID, ds.Name),
- "Check the documentation for more information.",
s.ID(),
- ds.UID,
+ fmt.Sprintf("%s (%s)", ds.Name, ds.UID),
+ []advisor.CheckErrorLink{},
), nil
}
return nil, nil
@@ -104,7 +109,11 @@ func (s *healthCheckStep) Title() string {
}
func (s *healthCheckStep) Description() string {
- return "Check if all data sources are healthy."
+ return "Checks if a data sources is healthy."
+}
+
+func (s *healthCheckStep) Resolution() string {
+ return "Go to the data source configuration page and address the issues reported."
}
func (s *healthCheckStep) ID() string {
@@ -124,7 +133,9 @@ func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any
}
pCtx, err := s.PluginContextProvider.GetWithDataSource(ctx, ds.Type, requester, ds)
if err != nil {
- return nil, fmt.Errorf("failed to get plugin context: %w", err)
+ // Unable to check health check
+ klog.Error("Failed to get plugin context", "datasource_uid", ds.UID, "error", err)
+ return nil, nil
}
req := &backend.CheckHealthRequest{
PluginContext: pCtx,
@@ -134,12 +145,14 @@ func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any
if err != nil || resp.Status != backend.HealthStatusOk {
return checks.NewCheckReportFailure(
advisor.CheckReportFailureSeverityHigh,
- fmt.Sprintf("Health check failed for %s", ds.Name),
- fmt.Sprintf(
- "Go to the data source configuration"+
- " and address the issues reported.", ds.UID),
s.ID(),
- ds.UID,
+ ds.Name,
+ []advisor.CheckErrorLink{
+ {
+ Message: "Fix me",
+ Url: fmt.Sprintf("/connections/datasources/edit/%s", ds.UID),
+ },
+ },
), nil
}
return nil, nil
diff --git a/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go b/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
index c71122efc1b..813a6434ad9 100644
--- a/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
+++ b/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
@@ -81,7 +81,7 @@ func TestCheck_Run(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 1, len(items))
assert.Len(t, failures, 1)
- assert.Equal(t, "Invalid UID 'invalid uid' for data source Prometheus", failures[0].Reason)
+ assert.Equal(t, "uid-validation", failures[0].StepID)
})
t.Run("should return failures when datasource health check fails", func(t *testing.T) {
@@ -116,7 +116,7 @@ func TestCheck_Run(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 1, len(items))
assert.Len(t, failures, 1)
- assert.Equal(t, "Health check failed for Prometheus", failures[0].Reason)
+ assert.Equal(t, "health-check", failures[0].StepID)
})
}
diff --git a/apps/advisor/pkg/app/checks/ifaces.go b/apps/advisor/pkg/app/checks/ifaces.go
index 7972baf3c57..31456599381 100644
--- a/apps/advisor/pkg/app/checks/ifaces.go
+++ b/apps/advisor/pkg/app/checks/ifaces.go
@@ -24,6 +24,8 @@ type Step interface {
Title() string
// Description returns the description of the step
Description() string
+ // Explains the action that needs to be taken to resolve the issue
+ Resolution() string
// Run executes the step for an item and returns a report
Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error)
}
diff --git a/apps/advisor/pkg/app/checks/plugincheck/check.go b/apps/advisor/pkg/app/checks/plugincheck/check.go
index 40b4328d9e0..45c54d4fdc0 100644
--- a/apps/advisor/pkg/app/checks/plugincheck/check.go
+++ b/apps/advisor/pkg/app/checks/plugincheck/check.go
@@ -74,6 +74,11 @@ func (s *deprecationStep) Description() string {
return "Check if any installed plugins are deprecated."
}
+func (s *deprecationStep) Resolution() string {
+ return "Check the documentation for recommended steps or delete the plugin."
+}
+
func (s *deprecationStep) ID() string {
return "deprecation"
}
@@ -98,10 +103,14 @@ func (s *deprecationStep) Run(ctx context.Context, _ *advisor.CheckSpec, it any)
if i.Status == "deprecated" {
return checks.NewCheckReportFailure(
advisor.CheckReportFailureSeverityHigh,
- fmt.Sprintf("Plugin deprecated: %s", p.ID),
- "Check the documentation for recommended steps.",
s.ID(),
p.ID,
+ []advisor.CheckErrorLink{
+ {
+ Message: "Admin",
+ Url: fmt.Sprintf("/plugins/%s", p.ID),
+ },
+ },
), nil
}
return nil, nil
@@ -118,7 +127,11 @@ func (s *updateStep) Title() string {
}
func (s *updateStep) Description() string {
- return "Check if any installed plugins have a newer version available."
+ return "Checks if an installed plugins has a newer version available."
+}
+
+func (s *updateStep) Resolution() string {
+ return "Go to the plugin admin page and upgrade to the latest version."
}
func (s *updateStep) ID() string {
@@ -151,12 +164,14 @@ func (s *updateStep) Run(ctx context.Context, _ *advisor.CheckSpec, i any) (*adv
if hasUpdate(p, info) {
return checks.NewCheckReportFailure(
advisor.CheckReportFailureSeverityLow,
- fmt.Sprintf("New version available for %s", p.ID),
- fmt.Sprintf(
- "Go to the plugin admin page"+
- " and upgrade to the latest version.", p.ID),
s.ID(),
p.ID,
+ []advisor.CheckErrorLink{
+ {
+ Message: "Upgrade",
+ Url: fmt.Sprintf("/plugins/%s?page=version-history", p.ID),
+ },
+ },
), nil
}
diff --git a/apps/advisor/pkg/app/checks/plugincheck/check_test.go b/apps/advisor/pkg/app/checks/plugincheck/check_test.go
index 1013d9818d1..13b2a17ea1b 100644
--- a/apps/advisor/pkg/app/checks/plugincheck/check_test.go
+++ b/apps/advisor/pkg/app/checks/plugincheck/check_test.go
@@ -42,10 +42,14 @@ func TestRun(t *testing.T) {
expectedFailures: []advisor.CheckReportFailure{
{
Severity: advisor.CheckReportFailureSeverityHigh,
- Reason: "Plugin deprecated: plugin1",
- Action: "Check the documentation for recommended steps.",
StepID: "deprecation",
- ItemID: "plugin1",
+ Item: "plugin1",
+ Links: []advisor.CheckErrorLink{
+ {
+ Url: "/plugins/plugin1",
+ Message: "Admin",
+ },
+ },
},
},
},
@@ -63,10 +67,14 @@ func TestRun(t *testing.T) {
expectedFailures: []advisor.CheckReportFailure{
{
Severity: advisor.CheckReportFailureSeverityLow,
- Reason: "New version available for plugin2",
- Action: "Go to the plugin admin page and upgrade to the latest version.",
StepID: "update",
- ItemID: "plugin2",
+ Item: "plugin2",
+ Links: []advisor.CheckErrorLink{
+ {
+ Url: "/plugins/plugin2?page=version-history",
+ Message: "Upgrade",
+ },
+ },
},
},
},
@@ -84,10 +92,14 @@ func TestRun(t *testing.T) {
expectedFailures: []advisor.CheckReportFailure{
{
Severity: advisor.CheckReportFailureSeverityLow,
- Reason: "New version available for plugin2",
- Action: "Go to the plugin admin page and upgrade to the latest version.",
StepID: "update",
- ItemID: "plugin2",
+ Item: "plugin2",
+ Links: []advisor.CheckErrorLink{
+ {
+ Url: "/plugins/plugin2?page=version-history",
+ Message: "Upgrade",
+ },
+ },
},
},
},
diff --git a/apps/advisor/pkg/app/checks/utils.go b/apps/advisor/pkg/app/checks/utils.go
index a02357cf013..b9b609b10a4 100644
--- a/apps/advisor/pkg/app/checks/utils.go
+++ b/apps/advisor/pkg/app/checks/utils.go
@@ -11,16 +11,14 @@ const (
func NewCheckReportFailure(
severity advisor.CheckReportFailureSeverity,
- reason string,
- action string,
stepID string,
- itemID string,
+ item string,
+ links []advisor.CheckErrorLink,
) *advisor.CheckReportFailure {
return &advisor.CheckReportFailure{
Severity: severity,
- Reason: reason,
- Action: action,
StepID: stepID,
- ItemID: itemID,
+ Item: item,
+ Links: links,
}
}
diff --git a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
index de250b4535e..50f2a09b6d2 100644
--- a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
+++ b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
@@ -52,6 +52,7 @@ func (r *Runner) Run(ctx context.Context) error {
Title: s.Title(),
Description: s.Description(),
StepID: s.ID(),
+ Resolution: s.Resolution(),
}
}
obj := &advisorv0alpha1.CheckType{
diff --git a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
index e10ecab9876..f1623a6534b 100644
--- a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
+++ b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
@@ -6,6 +6,7 @@ import (
"testing"
"github.com/grafana/grafana-app-sdk/resource"
+ advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
k8sErrs "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -134,8 +135,6 @@ func (m *mockCheck) Steps() []checks.Step {
}
type mockStep struct {
- checks.Step
-
id string
title string
description string
@@ -153,6 +152,14 @@ func (m *mockStep) Description() string {
return m.description
}
+func (m *mockStep) Resolution() string {
+ return ""
+}
+
+func (m *mockStep) Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error) {
+ return nil, nil
+}
+
type mockClient struct {
resource.Client
diff --git a/apps/advisor/pkg/app/utils_test.go b/apps/advisor/pkg/app/utils_test.go
index 090397333d0..b3b8d36f60b 100644
--- a/apps/advisor/pkg/app/utils_test.go
+++ b/apps/advisor/pkg/app/utils_test.go
@@ -191,6 +191,10 @@ func (m *mockStep) Description() string {
return "mock"
}
+func (m *mockStep) Resolution() string {
+ return "mock"
+}
+
func (m *mockStep) ID() string {
return "mock"
}