mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-05 20:40:16 -08:00
feat(plugin): Add option to update plugin (#1462)
* Add option to update plugin - add plugin update [pluginName] to update - add supporting test * refactor: wrap errors
This commit is contained in:
@@ -686,6 +686,12 @@ func NewPluginCommand() *cli.Command {
|
||||
ArgsUsage: "PLUGIN_NAME [PLUGIN_OPTIONS]",
|
||||
Action: plugin.Run,
|
||||
},
|
||||
{
|
||||
Name: "update",
|
||||
Usage: "update an existing plugin",
|
||||
ArgsUsage: "PLUGIN_NAME",
|
||||
Action: plugin.Update,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,24 @@ func List(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update updates an existing plugin
|
||||
func Update(c *cli.Context) error {
|
||||
if c.NArg() != 1 {
|
||||
cli.ShowSubcommandHelpAndExit(c, 1)
|
||||
}
|
||||
|
||||
if err := initLogger(c); err != nil {
|
||||
return xerrors.Errorf("initialize error: %w", err)
|
||||
}
|
||||
|
||||
pluginName := c.Args().First()
|
||||
if err := plugin.Update(pluginName); err != nil {
|
||||
return xerrors.Errorf("plugin update error: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run runs the plugin
|
||||
func Run(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/downloader"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
@@ -206,7 +206,6 @@ Plugin: %s
|
||||
Description: %s
|
||||
Version: %s
|
||||
Usage: %s
|
||||
|
||||
`, plugin.Name, plugin.Description, plugin.Version, plugin.Usage), nil
|
||||
}
|
||||
|
||||
@@ -230,6 +229,35 @@ func List() (string, error) {
|
||||
return strings.Join(pluginList, "\n"), nil
|
||||
}
|
||||
|
||||
// Update updates an existing plugin
|
||||
func Update(name string) error {
|
||||
pluginDir := filepath.Join(dir(), name)
|
||||
|
||||
if _, err := os.Stat(pluginDir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return xerrors.Errorf("could not find a plugin called '%s' to update: %w", name, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
plugin, err := loadMetadata(pluginDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Logger.Infof("Updating plugin '%s'", name)
|
||||
updated, err := Install(nil, plugin.Repository, true)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("unable to perform an update installation: %w", err)
|
||||
}
|
||||
|
||||
if plugin.Version == updated.Version {
|
||||
log.Logger.Infof("The %s plugin is the latest version. [%s]", name, plugin.Version)
|
||||
} else {
|
||||
log.Logger.Infof("Updated '%s' from %s to %s", name, plugin.Version, updated.Version)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadAll loads all plugins
|
||||
func LoadAll() ([]Plugin, error) {
|
||||
pluginsDir := dir()
|
||||
|
||||
@@ -316,7 +316,7 @@ description: A simple test plugin`
|
||||
// Get Information for the plugin
|
||||
info, err := plugin.Information(pluginName)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "\nPlugin: test_plugin\n Description: A simple test plugin\n Version: 0.1.0\n Usage: test\n\n", info)
|
||||
assert.Equal(t, "\nPlugin: test_plugin\n Description: A simple test plugin\n Version: 0.1.0\n Usage: test\n", info)
|
||||
|
||||
// Get Information for unknown plugin
|
||||
info, err = plugin.Information("unknown")
|
||||
@@ -378,3 +378,46 @@ func TestLoadAll1(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
pluginName := "test_plugin"
|
||||
|
||||
tempDir := t.TempDir()
|
||||
pluginDir := filepath.Join(tempDir, ".trivy", "plugins", pluginName)
|
||||
|
||||
t.Setenv("XDG_DATA_HOME", tempDir)
|
||||
|
||||
// Create the test plugin directory
|
||||
err := os.MkdirAll(pluginDir, os.ModePerm)
|
||||
require.NoError(t, err)
|
||||
|
||||
// write the plugin name
|
||||
pluginMetadata := `name: "test_plugin"
|
||||
repository: testdata/test_plugin
|
||||
version: "0.0.5"
|
||||
usage: test
|
||||
description: A simple test plugin`
|
||||
|
||||
err = os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(pluginMetadata), os.ModePerm)
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify initial version
|
||||
verifyVersion(t, pluginName, "0.0.5")
|
||||
|
||||
// Update the existing plugin
|
||||
err = plugin.Update(pluginName)
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify plugin updated
|
||||
verifyVersion(t, pluginName, "0.1.0")
|
||||
}
|
||||
|
||||
func verifyVersion(t *testing.T, pluginName, expectedVersion string) {
|
||||
plugins, err := plugin.LoadAll()
|
||||
require.NoError(t, err)
|
||||
for _, plugin := range plugins {
|
||||
if plugin.Name == pluginName {
|
||||
assert.Equal(t, expectedVersion, plugin.Version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user