mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Remove provisional APIVersion from plugin info (#89831)
This commit is contained in:
parent
55ba32bda7
commit
a22c1ae424
@ -582,11 +582,6 @@
|
|||||||
},
|
},
|
||||||
"required": ["extensionPointId", "title", "type"]
|
"required": ["extensionPointId", "title", "type"]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"apiVersion": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "[internal only] The API version for the plugin. Used for Datasource API servers. This metadata is temporary and will be removed in the future.",
|
|
||||||
"pattern": "^v([\\d]+)(?:(alpha|beta)([\\d]+))?$"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ type PluginSetting struct {
|
|||||||
SignatureType plugins.SignatureType `json:"signatureType"`
|
SignatureType plugins.SignatureType `json:"signatureType"`
|
||||||
SignatureOrg string `json:"signatureOrg"`
|
SignatureOrg string `json:"signatureOrg"`
|
||||||
AngularDetected bool `json:"angularDetected"`
|
AngularDetected bool `json:"angularDetected"`
|
||||||
APIVersion string `json:"apiVersion"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PluginListItem struct {
|
type PluginListItem struct {
|
||||||
@ -50,7 +49,6 @@ type PluginListItem struct {
|
|||||||
AccessControl accesscontrol.Metadata `json:"accessControl,omitempty"`
|
AccessControl accesscontrol.Metadata `json:"accessControl,omitempty"`
|
||||||
AngularDetected bool `json:"angularDetected"`
|
AngularDetected bool `json:"angularDetected"`
|
||||||
IAM *pfs.IAM `json:"iam,omitempty"`
|
IAM *pfs.IAM `json:"iam,omitempty"`
|
||||||
APIVersion string `json:"apiVersion"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PluginList []PluginListItem
|
type PluginList []PluginListItem
|
||||||
|
@ -142,7 +142,6 @@ func (hs *HTTPServer) GetPluginList(c *contextmodel.ReqContext) response.Respons
|
|||||||
SignatureOrg: pluginDef.SignatureOrg,
|
SignatureOrg: pluginDef.SignatureOrg,
|
||||||
AccessControl: pluginsMetadata[pluginDef.ID],
|
AccessControl: pluginsMetadata[pluginDef.ID],
|
||||||
AngularDetected: pluginDef.Angular.Detected,
|
AngularDetected: pluginDef.Angular.Detected,
|
||||||
APIVersion: pluginDef.APIVersion,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagExternalServiceAccounts) {
|
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagExternalServiceAccounts) {
|
||||||
@ -209,7 +208,6 @@ func (hs *HTTPServer) GetPluginSettingByID(c *contextmodel.ReqContext) response.
|
|||||||
SignatureOrg: plugin.SignatureOrg,
|
SignatureOrg: plugin.SignatureOrg,
|
||||||
SecureJsonFields: map[string]bool{},
|
SecureJsonFields: map[string]bool{},
|
||||||
AngularDetected: plugin.Angular.Detected,
|
AngularDetected: plugin.Angular.Detected,
|
||||||
APIVersion: plugin.APIVersion,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if plugin.IsApp() {
|
if plugin.IsApp() {
|
||||||
|
@ -3,8 +3,6 @@ package validation
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -117,36 +115,3 @@ func (a *AngularDetector) Validate(ctx context.Context, p *plugins.Plugin) error
|
|||||||
p.Angular.HideDeprecation = slices.Contains(a.cfg.HideAngularDeprecation, p.ID)
|
p.Angular.HideDeprecation = slices.Contains(a.cfg.HideAngularDeprecation, p.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIVersionValidation implements a ValidateFunc for validating plugin API versions.
|
|
||||||
type APIVersionValidation struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIVersionValidationStep returns a new ValidateFunc for validating plugin signatures.
|
|
||||||
func APIVersionValidationStep() ValidateFunc {
|
|
||||||
sv := &APIVersionValidation{}
|
|
||||||
return sv.Validate
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates the plugin signature. If a signature error is encountered, the error is recorded with the
|
|
||||||
// pluginerrs.ErrorTracker.
|
|
||||||
func (v *APIVersionValidation) Validate(ctx context.Context, p *plugins.Plugin) error {
|
|
||||||
if p.APIVersion != "" {
|
|
||||||
if !p.Backend {
|
|
||||||
return fmt.Errorf("plugin %s has an API version but is not a backend plugin", p.ID)
|
|
||||||
}
|
|
||||||
// Eventually, all backend plugins will be supported
|
|
||||||
if p.Type != plugins.TypeDataSource {
|
|
||||||
return fmt.Errorf("plugin %s has an API version but is not a datasource plugin", p.ID)
|
|
||||||
}
|
|
||||||
m, err := regexp.MatchString(`^v([\d]+)(?:(alpha|beta)([\d]+))?$`, p.APIVersion)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to verify apiVersion %s: %v", p.APIVersion, err)
|
|
||||||
}
|
|
||||||
if !m {
|
|
||||||
return fmt.Errorf("plugin %s has an invalid API version %s", p.ID, p.APIVersion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
package validation
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAPIVersionValidation(t *testing.T) {
|
|
||||||
s := APIVersionValidationStep()
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
plugin *plugins.Plugin
|
|
||||||
err bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "valid plugin",
|
|
||||||
plugin: &plugins.Plugin{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
Backend: true,
|
|
||||||
Type: plugins.TypeDataSource,
|
|
||||||
APIVersion: "v0alpha1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid plugin - not backend",
|
|
||||||
plugin: &plugins.Plugin{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
Backend: false,
|
|
||||||
Type: plugins.TypeDataSource,
|
|
||||||
APIVersion: "v0alpha1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid plugin - not datasource",
|
|
||||||
plugin: &plugins.Plugin{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
Backend: true,
|
|
||||||
Type: plugins.TypeApp,
|
|
||||||
APIVersion: "v0alpha1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid plugin - invalid API version",
|
|
||||||
plugin: &plugins.Plugin{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
Backend: true,
|
|
||||||
Type: plugins.TypeDataSource,
|
|
||||||
APIVersion: "invalid",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
err := s(context.Background(), tt.plugin)
|
|
||||||
if tt.err {
|
|
||||||
require.Error(t, err)
|
|
||||||
} else {
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -128,9 +128,6 @@ type JSONData struct {
|
|||||||
|
|
||||||
// App Service Auth Registration
|
// App Service Auth Registration
|
||||||
IAM *pfs.IAM `json:"iam,omitempty"`
|
IAM *pfs.IAM `json:"iam,omitempty"`
|
||||||
|
|
||||||
// API Version: Temporary field while plugins don't expose a OpenAPI schema
|
|
||||||
APIVersion string `json:"apiVersion,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadPluginJSON(reader io.Reader) (JSONData, error) {
|
func ReadPluginJSON(reader io.Reader) (JSONData, error) {
|
||||||
|
@ -322,10 +322,7 @@ func (s *Service) prepareInstanceSettings(ctx context.Context, settings *backend
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When the APIVersion is set, the client must also implement AdmissionHandler
|
// When the APIVersion is set, the client must also implement AdmissionHandler
|
||||||
if p.APIVersion == "" {
|
if settings.APIVersion == "" {
|
||||||
if settings.APIVersion != "" {
|
|
||||||
return nil, fmt.Errorf("invalid request apiVersion (datasource does not have one configured)")
|
|
||||||
}
|
|
||||||
return settings, nil // NOOP
|
return settings, nil // NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +364,7 @@ func (s *Service) prepareInstanceSettings(ctx context.Context, settings *backend
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, plugins.ErrMethodNotImplemented) {
|
if errors.Is(err, plugins.ErrMethodNotImplemented) {
|
||||||
return nil, errutil.Internal("plugin.unimplemented").
|
return nil, errutil.Internal("plugin.unimplemented").
|
||||||
Errorf("plugin (%s) with apiVersion=%s must implement ValidateAdmission", p.ID, p.APIVersion)
|
Errorf("plugin (%s) with apiVersion=%s must implement ValidateAdmission", p.ID, settings.APIVersion)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -388,7 +385,7 @@ func (s *Service) prepareInstanceSettings(ctx context.Context, settings *backend
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, plugins.ErrMethodNotImplemented) {
|
if errors.Is(err, plugins.ErrMethodNotImplemented) {
|
||||||
return nil, errutil.Internal("plugin.unimplemented").
|
return nil, errutil.Internal("plugin.unimplemented").
|
||||||
Errorf("plugin (%s) with apiVersion=%s must implement MutateAdmission", p.ID, p.APIVersion)
|
Errorf("plugin (%s) with apiVersion=%s must implement MutateAdmission", p.ID, settings.APIVersion)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -110,10 +110,9 @@ func TestService_AddDataSource(t *testing.T) {
|
|||||||
dsService.pluginStore = &pluginstore.FakePluginStore{
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
PluginList: []pluginstore.Plugin{{
|
PluginList: []pluginstore.Plugin{{
|
||||||
JSONData: plugins.JSONData{
|
JSONData: plugins.JSONData{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
Type: plugins.TypeDataSource,
|
Type: plugins.TypeDataSource,
|
||||||
Name: "test",
|
Name: "test",
|
||||||
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
@ -150,10 +149,9 @@ func TestService_AddDataSource(t *testing.T) {
|
|||||||
dsService.pluginStore = &pluginstore.FakePluginStore{
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
PluginList: []pluginstore.Plugin{{
|
PluginList: []pluginstore.Plugin{{
|
||||||
JSONData: plugins.JSONData{
|
JSONData: plugins.JSONData{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
Type: plugins.TypeDataSource,
|
Type: plugins.TypeDataSource,
|
||||||
Name: "test",
|
Name: "test",
|
||||||
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
@ -200,10 +198,9 @@ func TestService_AddDataSource(t *testing.T) {
|
|||||||
dsService.pluginStore = &pluginstore.FakePluginStore{
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
PluginList: []pluginstore.Plugin{{
|
PluginList: []pluginstore.Plugin{{
|
||||||
JSONData: plugins.JSONData{
|
JSONData: plugins.JSONData{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
Type: plugins.TypeDataSource,
|
Type: plugins.TypeDataSource,
|
||||||
Name: "test",
|
Name: "test",
|
||||||
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
@ -491,10 +488,9 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
dsService.pluginStore = &pluginstore.FakePluginStore{
|
dsService.pluginStore = &pluginstore.FakePluginStore{
|
||||||
PluginList: []pluginstore.Plugin{{
|
PluginList: []pluginstore.Plugin{{
|
||||||
JSONData: plugins.JSONData{
|
JSONData: plugins.JSONData{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
Type: plugins.TypeDataSource,
|
Type: plugins.TypeDataSource,
|
||||||
Name: "test",
|
Name: "test",
|
||||||
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callbacks will be executed
|
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ func ProvideValidationStage(cfg *config.PluginManagementCfg, sv signature.Valida
|
|||||||
SignatureValidationStep(sv),
|
SignatureValidationStep(sv),
|
||||||
validation.ModuleJSValidationStep(),
|
validation.ModuleJSValidationStep(),
|
||||||
validation.AngularDetectionStep(cfg, ai),
|
validation.AngularDetectionStep(cfg, ai),
|
||||||
validation.APIVersionValidationStep(),
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ func (p *BaseProvider) GetBasePluginContext(ctx context.Context, plugin pluginst
|
|||||||
pCtx := backend.PluginContext{
|
pCtx := backend.PluginContext{
|
||||||
PluginID: plugin.ID,
|
PluginID: plugin.ID,
|
||||||
PluginVersion: plugin.Info.Version,
|
PluginVersion: plugin.Info.Version,
|
||||||
APIVersion: plugin.APIVersion,
|
|
||||||
}
|
}
|
||||||
if user != nil && !user.IsNil() {
|
if user != nil && !user.IsNil() {
|
||||||
pCtx.OrgID = user.GetOrgID()
|
pCtx.OrgID = user.GetOrgID()
|
||||||
|
@ -26,17 +26,15 @@ import (
|
|||||||
|
|
||||||
func TestGet(t *testing.T) {
|
func TestGet(t *testing.T) {
|
||||||
const (
|
const (
|
||||||
pluginID = "plugin-id"
|
pluginID = "plugin-id"
|
||||||
alias = "alias"
|
alias = "alias"
|
||||||
apiVersion = "v0alpha1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
preg := registry.NewInMemory()
|
preg := registry.NewInMemory()
|
||||||
require.NoError(t, preg.Add(context.Background(), &plugins.Plugin{
|
require.NoError(t, preg.Add(context.Background(), &plugins.Plugin{
|
||||||
JSONData: plugins.JSONData{
|
JSONData: plugins.JSONData{
|
||||||
ID: pluginID,
|
ID: pluginID,
|
||||||
AliasIDs: []string{alias},
|
AliasIDs: []string{alias},
|
||||||
APIVersion: apiVersion,
|
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -61,7 +59,6 @@ func TestGet(t *testing.T) {
|
|||||||
pCtx, err := pcp.Get(context.Background(), tc.input, identity, identity.OrgID)
|
pCtx, err := pcp.Get(context.Background(), tc.input, identity, identity.OrgID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pluginID, pCtx.PluginID)
|
require.Equal(t, pluginID, pCtx.PluginID)
|
||||||
require.Equal(t, apiVersion, pCtx.APIVersion)
|
|
||||||
require.NotNil(t, pCtx.GrafanaConfig)
|
require.NotNil(t, pCtx.GrafanaConfig)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -75,7 +72,6 @@ func TestGet(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, pluginID, pCtx.PluginID)
|
require.Equal(t, pluginID, pCtx.PluginID)
|
||||||
require.Equal(t, apiVersion, pCtx.APIVersion)
|
|
||||||
require.NotNil(t, pCtx.GrafanaConfig)
|
require.NotNil(t, pCtx.GrafanaConfig)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1671,8 +1671,7 @@
|
|||||||
"signature": "internal",
|
"signature": "internal",
|
||||||
"signatureType": "",
|
"signatureType": "",
|
||||||
"signatureOrg": "",
|
"signatureOrg": "",
|
||||||
"angularDetected": false,
|
"angularDetected": false
|
||||||
"apiVersion": "v0alpha1"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Text",
|
"name": "Text",
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"alerting": true,
|
"alerting": true,
|
||||||
"annotations": true,
|
"annotations": true,
|
||||||
"backend": true,
|
"backend": true,
|
||||||
"apiVersion": "v0alpha1",
|
|
||||||
|
|
||||||
"queryOptions": {
|
"queryOptions": {
|
||||||
"minInterval": true,
|
"minInterval": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user