Advisor: Check plugin signature (#106044)

This commit is contained in:
Andres Martinez Gotor
2025-05-29 11:33:19 +02:00
committed by GitHub
parent 27ab895eef
commit e2e8de29ba
7 changed files with 397 additions and 143 deletions
+52 -131
View File
@@ -2,43 +2,42 @@ package plugincheck
import (
"context"
"fmt"
sysruntime "runtime"
"github.com/grafana/grafana-app-sdk/logging"
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/repo"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
)
const (
CheckID = "plugin"
DeprecationStepID = "deprecation"
UpdateStepID = "update"
CheckID = "plugin"
)
func New(
pluginStore pluginstore.Store,
pluginRepo repo.Service,
updateChecker pluginchecker.PluginUpdateChecker,
pluginErrorResolver plugins.ErrorResolver,
grafanaVersion string,
) checks.Check {
return &check{
PluginStore: pluginStore,
PluginRepo: pluginRepo,
GrafanaVersion: grafanaVersion,
updateChecker: updateChecker,
PluginStore: pluginStore,
PluginRepo: pluginRepo,
GrafanaVersion: grafanaVersion,
updateChecker: updateChecker,
pluginErrorResolver: pluginErrorResolver,
}
}
type check struct {
PluginStore pluginstore.Store
PluginRepo repo.Service
updateChecker pluginchecker.PluginUpdateChecker
GrafanaVersion string
pluginIndex map[string]repo.PluginInfo
PluginStore pluginstore.Store
PluginRepo repo.Service
updateChecker pluginchecker.PluginUpdateChecker
pluginErrorResolver plugins.ErrorResolver
GrafanaVersion string
pluginIndex map[string]repo.PluginInfo
}
func (c *check) ID() string {
@@ -49,12 +48,40 @@ func (c *check) Name() string {
return "plugin"
}
type pluginItem struct {
Plugin *pluginstore.Plugin
Err *plugins.Error
}
func (c *check) Items(ctx context.Context) ([]any, error) {
ps := c.PluginStore.Plugins(ctx)
res := make([]any, len(ps))
for i, p := range ps {
res[i] = p
resMap := map[string]*pluginItem{}
for _, p := range ps {
resMap[p.ID] = &pluginItem{
Plugin: &p,
Err: c.pluginErrorResolver.PluginError(ctx, p.ID),
}
}
// Plugins with errors are not added to the plugin store but
// we still want to show them in the check results so we add them to the map
pluginErrors := c.pluginErrorResolver.PluginErrors(ctx)
for _, e := range pluginErrors {
if _, exists := resMap[e.PluginID]; exists {
resMap[e.PluginID].Err = e
} else {
resMap[e.PluginID] = &pluginItem{
Plugin: nil,
Err: e,
}
}
}
res := make([]any, 0, len(resMap))
for _, p := range resMap {
res = append(res, p)
}
return res, nil
}
@@ -63,7 +90,10 @@ func (c *check) Item(ctx context.Context, id string) (any, error) {
if !exists {
return nil, nil
}
return p, nil
return &pluginItem{
Plugin: &p,
Err: c.pluginErrorResolver.PluginError(ctx, p.ID),
}, nil
}
func (c *check) Init(ctx context.Context) error {
@@ -99,117 +129,8 @@ func (c *check) Steps() []checks.Step {
updateChecker: c.updateChecker,
pluginIndex: c.pluginIndex,
},
&unsignedStep{
pluginIndex: c.pluginIndex,
},
}
}
type deprecationStep struct {
GrafanaVersion string
updateChecker pluginchecker.PluginUpdateChecker
pluginIndex map[string]repo.PluginInfo
}
func (s *deprecationStep) Title() string {
return "Deprecation check"
}
func (s *deprecationStep) Description() string {
return "Check if any installed plugins are deprecated."
}
func (s *deprecationStep) Resolution() string {
return "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 or delete the plugin."
}
func (s *deprecationStep) ID() string {
return DeprecationStepID
}
func (s *deprecationStep) Run(ctx context.Context, log logging.Logger, _ *advisor.CheckSpec, it any) ([]advisor.CheckReportFailure, error) {
p, ok := it.(pluginstore.Plugin)
if !ok {
return nil, fmt.Errorf("invalid item type %T", it)
}
if !s.updateChecker.IsUpdatable(ctx, p) {
return nil, nil
}
// Check if plugin is deprecated
i, ok := s.pluginIndex[p.ID]
if !ok {
// Unable to check deprecation status
return nil, nil
}
if i.Status == "deprecated" {
return []advisor.CheckReportFailure{checks.NewCheckReportFailure(
advisor.CheckReportFailureSeverityHigh,
s.ID(),
p.Name,
p.ID,
[]advisor.CheckErrorLink{
{
Message: "View plugin",
Url: fmt.Sprintf("/plugins/%s", p.ID),
},
},
)}, nil
}
return nil, nil
}
type updateStep struct {
GrafanaVersion string
updateChecker pluginchecker.PluginUpdateChecker
pluginIndex map[string]repo.PluginInfo
}
func (s *updateStep) Title() string {
return "Update check"
}
func (s *updateStep) Description() string {
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 {
return UpdateStepID
}
func (s *updateStep) Run(ctx context.Context, log logging.Logger, _ *advisor.CheckSpec, i any) ([]advisor.CheckReportFailure, error) {
p, ok := i.(pluginstore.Plugin)
if !ok {
return nil, fmt.Errorf("invalid item type %T", i)
}
if !s.updateChecker.IsUpdatable(ctx, p) {
return nil, nil
}
// Check if plugin has a newer version available
info, ok := s.pluginIndex[p.ID]
if !ok {
// Unable to check updates
return nil, nil
}
if s.updateChecker.CanUpdate(p.ID, p.Info.Version, info.Version, false) {
return []advisor.CheckReportFailure{checks.NewCheckReportFailure(
advisor.CheckReportFailureSeverityLow,
s.ID(),
p.Name,
p.ID,
[]advisor.CheckErrorLink{
{
Message: "Upgrade",
Url: fmt.Sprintf("/plugins/%s?page=version-history", p.ID),
},
},
)}, nil
}
return nil, nil
}