Grafana Advisor: Automatically generate frontend types (#99807)

* Grafana Advisor: Frontend types

* fix bad merge
jackw/fix-e2e-plugin-configs
Andres Martinez Gotor 6 months ago committed by GitHub
parent 74e3beabd0
commit 4cd2ebe186
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      apps/advisor/.gitignore
  2. 29
      apps/advisor/kinds/check.cue
  3. 46
      apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go
  4. 92
      apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go
  5. 10
      apps/advisor/pkg/app/checks/datasourcecheck/check.go
  6. 10
      apps/advisor/pkg/app/checks/plugincheck/check.go
  7. 20
      apps/advisor/pkg/app/checks/plugincheck/check_test.go
  8. 7
      apps/advisor/plugin/README.md

@ -0,0 +1 @@
plugin/src

@ -7,7 +7,7 @@ check: {
versions: {
"v0alpha1": {
codegen: {
frontend: false
frontend: true
backend: true
}
validation: {
@ -17,24 +17,27 @@ check: {
]
}
schema: {
spec: {
#Data: {
// Generic data input that a check can receive
data?: [string]: string
}
status: {
report: {
#ReportError: {
// Severity of the error
severity: "high" | "low"
// Human readable reason for the error
reason: string
// Action to take to resolve the error
action: string
}
#Report: {
// Number of elements analyzed
count: int
// List of errors
errors: [...{
// Severity of the error
severity: "high" | "low"
// Human readable reason for the error
reason: string
// Action to take to resolve the error
action: string
}]
}
errors: [...#ReportError]
}
spec: #Data
status: {
report: #Report
}
}
}

@ -2,6 +2,21 @@
package v0alpha1
// +k8s:openapi-gen=true
type CheckReportError struct {
// Severity of the error
Severity CheckReportErrorSeverity `json:"severity"`
// Human readable reason for the error
Reason string `json:"reason"`
// Action to take to resolve the error
Action string `json:"action"`
}
// NewCheckReportError creates a new CheckReportError object.
func NewCheckReportError() *CheckReportError {
return &CheckReportError{}
}
// +k8s:openapi-gen=true
type CheckstatusOperatorState struct {
// lastEvaluation is the ResourceVersion last evaluated
@ -38,43 +53,28 @@ func NewCheckStatus() *CheckStatus {
}
// +k8s:openapi-gen=true
type CheckStatusOperatorStateState string
type CheckReportErrorSeverity string
const (
CheckStatusOperatorStateStateSuccess CheckStatusOperatorStateState = "success"
CheckStatusOperatorStateStateInProgress CheckStatusOperatorStateState = "in_progress"
CheckStatusOperatorStateStateFailed CheckStatusOperatorStateState = "failed"
CheckReportErrorSeverityHigh CheckReportErrorSeverity = "high"
CheckReportErrorSeverityLow CheckReportErrorSeverity = "low"
)
// +k8s:openapi-gen=true
type CheckStatusSeverity string
type CheckStatusOperatorStateState string
const (
CheckStatusSeverityHigh CheckStatusSeverity = "high"
CheckStatusSeverityLow CheckStatusSeverity = "low"
CheckStatusOperatorStateStateSuccess CheckStatusOperatorStateState = "success"
CheckStatusOperatorStateStateInProgress CheckStatusOperatorStateState = "in_progress"
CheckStatusOperatorStateStateFailed CheckStatusOperatorStateState = "failed"
)
// +k8s:openapi-gen=true
type CheckV0alpha1StatusReportErrors struct {
// Severity of the error
Severity CheckStatusSeverity `json:"severity"`
// Human readable reason for the error
Reason string `json:"reason"`
// Action to take to resolve the error
Action string `json:"action"`
}
// NewCheckV0alpha1StatusReportErrors creates a new CheckV0alpha1StatusReportErrors object.
func NewCheckV0alpha1StatusReportErrors() *CheckV0alpha1StatusReportErrors {
return &CheckV0alpha1StatusReportErrors{}
}
// +k8s:openapi-gen=true
type CheckV0alpha1StatusReport struct {
// Number of elements analyzed
Count int64 `json:"count"`
// List of errors
Errors []CheckV0alpha1StatusReportErrors `json:"errors"`
Errors []CheckReportError `json:"errors"`
}
// NewCheckV0alpha1StatusReport creates a new CheckV0alpha1StatusReport object.

@ -12,13 +12,13 @@ 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.CheckList": schema_pkg_apis_advisor_v0alpha1_CheckList(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec": schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus": schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReportErrors": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReportErrors(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckstatusOperatorState(ref),
"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.CheckList": schema_pkg_apis_advisor_v0alpha1_CheckList(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportError": schema_pkg_apis_advisor_v0alpha1_CheckReportError(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec": schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus": schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref),
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckstatusOperatorState(ref),
}
}
@ -117,6 +117,43 @@ func schema_pkg_apis_advisor_v0alpha1_CheckList(ref common.ReferenceCallback) co
}
}
func schema_pkg_apis_advisor_v0alpha1_CheckReportError(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"severity": {
SchemaProps: spec.SchemaProps{
Description: "Severity of the error",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"reason": {
SchemaProps: spec.SchemaProps{
Description: "Human readable reason for the error",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"action": {
SchemaProps: spec.SchemaProps{
Description: "Action to take to resolve the error",
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"severity", "reason", "action"},
},
},
}
}
func schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -218,7 +255,7 @@ func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref common.Refer
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReportErrors"),
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportError"),
},
},
},
@ -229,44 +266,7 @@ func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref common.Refer
},
},
Dependencies: []string{
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReportErrors"},
}
}
func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReportErrors(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"severity": {
SchemaProps: spec.SchemaProps{
Description: "Severity of the error",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"reason": {
SchemaProps: spec.SchemaProps{
Description: "Human readable reason for the error",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"action": {
SchemaProps: spec.SchemaProps{
Description: "Action to take to resolve the error",
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"severity", "reason", "action"},
},
},
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportError"},
}
}

@ -49,13 +49,13 @@ func (c *check) Run(ctx context.Context, obj *advisor.CheckSpec) (*advisor.Check
return nil, err
}
dsErrs := []advisor.CheckV0alpha1StatusReportErrors{}
dsErrs := []advisor.CheckReportError{}
for _, ds := range dss {
// Data source UID validation
err := util.ValidateUID(ds.UID)
if err != nil {
dsErrs = append(dsErrs, advisor.CheckV0alpha1StatusReportErrors{
Severity: advisor.CheckStatusSeverityLow,
dsErrs = append(dsErrs, advisor.CheckReportError{
Severity: advisor.CheckReportErrorSeverityLow,
Reason: fmt.Sprintf("Invalid UID '%s' for data source %s", ds.UID, ds.Name),
Action: "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.",
})
@ -81,8 +81,8 @@ func (c *check) Run(ctx context.Context, obj *advisor.CheckSpec) (*advisor.Check
continue
}
if resp.Status != backend.HealthStatusOk {
dsErrs = append(dsErrs, advisor.CheckV0alpha1StatusReportErrors{
Severity: advisor.CheckStatusSeverityHigh,
dsErrs = append(dsErrs, advisor.CheckReportError{
Severity: advisor.CheckReportErrorSeverityHigh,
Reason: fmt.Sprintf("Health check failed for %s", ds.Name),
Action: fmt.Sprintf(
"Go to the <a href='/connections/datasources/edit/%s'>data source configuration</a>"+

@ -43,7 +43,7 @@ func (c *check) Type() string {
func (c *check) Run(ctx context.Context, _ *advisor.CheckSpec) (*advisor.CheckV0alpha1StatusReport, error) {
ps := c.PluginStore.Plugins(ctx)
errs := []advisor.CheckV0alpha1StatusReportErrors{}
errs := []advisor.CheckReportError{}
for _, p := range ps {
// Skip if it's a core plugin
if p.IsCorePlugin() {
@ -56,8 +56,8 @@ func (c *check) Run(ctx context.Context, _ *advisor.CheckSpec) (*advisor.CheckV0
continue
}
if i.Status == "deprecated" {
errs = append(errs, advisor.CheckV0alpha1StatusReportErrors{
Severity: advisor.CheckStatusSeverityHigh,
errs = append(errs, advisor.CheckReportError{
Severity: advisor.CheckReportErrorSeverityHigh,
Reason: fmt.Sprintf("Plugin deprecated: %s", p.ID),
Action: "Check the <a href='https://grafana.com/legal/plugin-deprecation/#a-plugin-i-use-is-deprecated-what-should-i-do' target=_blank>documentation</a> for recommended steps.",
})
@ -73,8 +73,8 @@ func (c *check) Run(ctx context.Context, _ *advisor.CheckSpec) (*advisor.CheckV0
continue
}
if hasUpdate(p, info) {
errs = append(errs, advisor.CheckV0alpha1StatusReportErrors{
Severity: advisor.CheckStatusSeverityLow,
errs = append(errs, advisor.CheckReportError{
Severity: advisor.CheckReportErrorSeverityLow,
Reason: fmt.Sprintf("New version available for %s", p.ID),
Action: fmt.Sprintf(
"Go to the <a href='/plugins/%s?page=version-history'>plugin admin page</a>"+

@ -21,12 +21,12 @@ func TestRun(t *testing.T) {
pluginArchives map[string]*repo.PluginArchiveInfo
pluginPreinstalled []string
pluginManaged []string
expectedErrors []advisor.CheckV0alpha1StatusReportErrors
expectedErrors []advisor.CheckReportError
}{
{
name: "No plugins",
plugins: []pluginstore.Plugin{},
expectedErrors: []advisor.CheckV0alpha1StatusReportErrors{},
expectedErrors: []advisor.CheckReportError{},
},
{
name: "Deprecated plugin",
@ -39,9 +39,9 @@ func TestRun(t *testing.T) {
pluginArchives: map[string]*repo.PluginArchiveInfo{
"plugin1": {Version: "1.0.0"},
},
expectedErrors: []advisor.CheckV0alpha1StatusReportErrors{
expectedErrors: []advisor.CheckReportError{
{
Severity: advisor.CheckStatusSeverityHigh,
Severity: advisor.CheckReportErrorSeverityHigh,
Reason: "Plugin deprecated: plugin1",
Action: "Check the <a href='https://grafana.com/legal/plugin-deprecation/#a-plugin-i-use-is-deprecated-what-should-i-do' target=_blank>documentation</a> for recommended steps.",
},
@ -58,9 +58,9 @@ func TestRun(t *testing.T) {
pluginArchives: map[string]*repo.PluginArchiveInfo{
"plugin2": {Version: "1.1.0"},
},
expectedErrors: []advisor.CheckV0alpha1StatusReportErrors{
expectedErrors: []advisor.CheckReportError{
{
Severity: advisor.CheckStatusSeverityLow,
Severity: advisor.CheckReportErrorSeverityLow,
Reason: "New version available for plugin2",
Action: "Go to the <a href='/plugins/plugin2?page=version-history'>plugin admin page</a> and upgrade to the latest version.",
},
@ -77,9 +77,9 @@ func TestRun(t *testing.T) {
pluginArchives: map[string]*repo.PluginArchiveInfo{
"plugin2": {Version: "beta"},
},
expectedErrors: []advisor.CheckV0alpha1StatusReportErrors{
expectedErrors: []advisor.CheckReportError{
{
Severity: advisor.CheckStatusSeverityLow,
Severity: advisor.CheckReportErrorSeverityLow,
Reason: "New version available for plugin2",
Action: "Go to the <a href='/plugins/plugin2?page=version-history'>plugin admin page</a> and upgrade to the latest version.",
},
@ -97,7 +97,7 @@ func TestRun(t *testing.T) {
"plugin3": {Version: "1.1.0"},
},
pluginPreinstalled: []string{"plugin3"},
expectedErrors: []advisor.CheckV0alpha1StatusReportErrors{},
expectedErrors: []advisor.CheckReportError{},
},
{
name: "Managed plugin",
@ -111,7 +111,7 @@ func TestRun(t *testing.T) {
"plugin4": {Version: "1.1.0"},
},
pluginManaged: []string{"plugin4"},
expectedErrors: []advisor.CheckV0alpha1StatusReportErrors{},
expectedErrors: []advisor.CheckReportError{},
},
}

@ -0,0 +1,7 @@
This folder contains the automatically generated types for the frontend that are used in the app plugin.
To update the types:
1. Make any necessary changes in the `kinds` directory
2. Run `make generate`
3. Copy the `plugin` directory to the frontend app: https://github.com/grafana/grafana-advisor-app/tree/main/src/plugin
Loading…
Cancel
Save