Plugin: Validate plugin version on installation (#71488)

This commit is contained in:
Hugo Kiyodi Oshiro
2023-07-17 10:22:28 +02:00
committed by GitHub
parent 2e8cd1c021
commit 2776a000ab
2 changed files with 69 additions and 4 deletions

View File

@@ -8,6 +8,7 @@ import (
"runtime"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/fatih/color"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
@@ -22,16 +23,27 @@ import (
const installArgsSize = 2
func validateInput(c utils.CommandLine) error {
if c.Args().Len() > installArgsSize {
args := c.Args()
argsLen := args.Len()
if argsLen > installArgsSize {
logger.Info(color.RedString("Please specify the correct format. For example ./grafana cli (<command arguments>) plugins install <plugin ID> (<plugin version>)\n\n"))
return errors.New("install only supports 2 arguments: plugin and version")
}
arg := c.Args().First()
arg := args.First()
if arg == "" {
return errors.New("please specify plugin to install")
}
if argsLen == installArgsSize {
version := args.Get(1)
_, err := semver.NewVersion(version)
if err != nil {
return fmt.Errorf("the provided version (%s) is invalid", version)
}
}
pluginsDir := c.PluginDirectory()
if pluginsDir == "" {
return errors.New("missing pluginsDir flag")

View File

@@ -1,14 +1,16 @@
package commands
import (
"fmt"
"testing"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/utils"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func TestValidateInput(t *testing.T) {
t.Run("should print message for ignored args", func(t *testing.T) {
t.Run("should return an error for wrong args number", func(t *testing.T) {
mockCmdLine := &utils.MockCommandLine{}
defer mockCmdLine.AssertExpectations(t)
@@ -18,9 +20,60 @@ func TestValidateInput(t *testing.T) {
defer mockArgs.AssertExpectations(t)
mockArgs.On("Len").Return(len(cmdArgs))
mockCmdLine.On("Args").Return(mockArgs).Times(1)
mockCmdLine.On("Args").Return(mockArgs).Once()
err := validateInput(mockCmdLine)
require.EqualError(t, err, "install only supports 2 arguments: plugin and version")
})
tests := []struct {
desc string
versionArg string
shouldSucceed bool
}{
{
desc: "should successful validate semver arg",
versionArg: "1.2.3",
shouldSucceed: true,
},
{
desc: "should successful validate complex semver arg",
versionArg: "1.0.0-alpha.0valid",
shouldSucceed: true,
},
{
desc: "should fail non version arg",
versionArg: "bar",
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
mockCmdLine := &utils.MockCommandLine{}
defer mockCmdLine.AssertExpectations(t)
cmdArgs := []string{"foo", tt.versionArg}
mockArgs := &utils.MockArgs{}
defer mockArgs.AssertExpectations(t)
mockArgs.On("Len").Return(len(cmdArgs))
mockArgs.On("First").Return(cmdArgs[0])
mockArgs.On("Get", mock.AnythingOfType("int")).Return(cmdArgs[1])
mockCmdLine.On("Args").Return(mockArgs).Once()
if tt.shouldSucceed {
mockCmdLine.On("PluginDirectory").Return("/tmp").Once()
}
err := validateInput(mockCmdLine)
if tt.shouldSucceed {
require.NoError(t, err)
} else {
require.EqualError(t, err, fmt.Sprintf("the provided version (%s) is invalid", cmdArgs[1]))
}
})
}
}