mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-08 22:00:46 -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]",
|
ArgsUsage: "PLUGIN_NAME [PLUGIN_OPTIONS]",
|
||||||
Action: plugin.Run,
|
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
|
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
|
// Run runs the plugin
|
||||||
func Run(c *cli.Context) error {
|
func Run(c *cli.Context) error {
|
||||||
if c.NArg() < 1 {
|
if c.NArg() < 1 {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
yaml "gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/downloader"
|
"github.com/aquasecurity/trivy/pkg/downloader"
|
||||||
"github.com/aquasecurity/trivy/pkg/log"
|
"github.com/aquasecurity/trivy/pkg/log"
|
||||||
@@ -206,7 +206,6 @@ Plugin: %s
|
|||||||
Description: %s
|
Description: %s
|
||||||
Version: %s
|
Version: %s
|
||||||
Usage: %s
|
Usage: %s
|
||||||
|
|
||||||
`, plugin.Name, plugin.Description, plugin.Version, plugin.Usage), nil
|
`, plugin.Name, plugin.Description, plugin.Version, plugin.Usage), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +229,35 @@ func List() (string, error) {
|
|||||||
return strings.Join(pluginList, "\n"), nil
|
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
|
// LoadAll loads all plugins
|
||||||
func LoadAll() ([]Plugin, error) {
|
func LoadAll() ([]Plugin, error) {
|
||||||
pluginsDir := dir()
|
pluginsDir := dir()
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ description: A simple test plugin`
|
|||||||
// Get Information for the plugin
|
// Get Information for the plugin
|
||||||
info, err := plugin.Information(pluginName)
|
info, err := plugin.Information(pluginName)
|
||||||
require.NoError(t, err)
|
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
|
// Get Information for unknown plugin
|
||||||
info, err = plugin.Information("unknown")
|
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