diff --git a/pkg/config/config.go b/pkg/config/config.go
index 3fed1a7..5e35ee4 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -30,7 +30,6 @@ var defaultConfig *Config
var configPath string
func init() {
-
homeDir, err := os.UserHomeDir()
if err != nil {
homeDir = os.TempDir()
@@ -58,24 +57,23 @@ func init() {
_ = os.MkdirAll(lazyTrivyConfigDir, os.ModePerm)
configPath = filepath.Join(lazyTrivyConfigDir, "config.yaml")
-
}
func Load() (*Config, error) {
- logger.Debug("Attempting to load config from %s", configPath)
+ logger.Debugf("Attempting to load config from %s", configPath)
if _, err := os.Stat(configPath); err != nil {
- logger.Debug("No config file found, using defaults")
+ logger.Debugf("No config file found, using defaults")
return defaultConfig, nil
}
content, err := os.ReadFile(configPath)
if err != nil {
- logger.Error("Error reading config file: %s", err)
+ logger.Errorf("Error reading config file: %s", err)
return defaultConfig, nil
}
if err := yaml.Unmarshal(content, &defaultConfig); err != nil {
- logger.Error("Error parsing config file: %s", err)
+ logger.Errorf("Error parsing config file: %s", err)
return defaultConfig, err
}
@@ -83,15 +81,15 @@ func Load() (*Config, error) {
}
func Save(config *Config) error {
- logger.Debug("Saving the config to %s", configPath)
+ logger.Debugf("Saving the config to %s", configPath)
content, err := yaml.Marshal(config)
if err != nil {
- logger.Error("Error marshalling config: %s", err)
+ logger.Errorf("Error marshalling config: %s", err)
return err
}
- if err := os.WriteFile(configPath, content, 0644); err != nil {
- logger.Error("Error writing config file: %s", err)
+ if err := os.WriteFile(configPath, content, 0600); err != nil {
+ logger.Errorf("Error writing config file: %s", err)
return err
}
diff --git a/pkg/controllers/aws/aws.go b/pkg/controllers/aws/aws.go
index 846949a..c26a245 100644
--- a/pkg/controllers/aws/aws.go
+++ b/pkg/controllers/aws/aws.go
@@ -41,7 +41,7 @@ func NewAWSController(cui *gocui.Gui, dockerClient *docker.Client, cfg *config.C
}
func (c *Controller) Initialise() error {
- logger.Debug("Initialising AWS controller")
+ logger.Debugf("Initialising AWS controller")
var outerErr error
c.Cui.Update(func(gui *gocui.Gui) error {
@@ -51,13 +51,13 @@ func (c *Controller) Initialise() error {
return err
}
- logger.Debug("Configuring keyboard shortcuts")
+ logger.Debugf("Configuring keyboard shortcuts")
if err := c.configureKeyBindings(); err != nil {
return fmt.Errorf("failed to configure global keys: %w", err)
}
for _, v := range c.Views {
- if err := v.ConfigureKeys(); err != nil {
+ if err := v.ConfigureKeys(gui); err != nil {
return fmt.Errorf("failed to configure view keys: %w", err)
}
}
@@ -78,13 +78,13 @@ func (c *Controller) Initialise() error {
}
func (c *Controller) refreshServices() error {
- logger.Debug("getting caches services")
+ logger.Debugf("getting caches services")
services, err := c.accountRegionCacheServices(c.Config.AWS.AccountNo, c.Config.AWS.Region)
if err != nil {
return err
}
- logger.Debug("Updating the services view with the identified services")
+ logger.Debugf("Updating the services view with the identified services")
if v, ok := c.Views[widgets.Services].(*widgets.ServicesWidget); ok {
if err := v.RefreshServices(services, 20); err != nil {
return err
@@ -94,7 +94,7 @@ func (c *Controller) refreshServices() error {
}
func (c *Controller) CreateWidgets(manager base.Manager) error {
- logger.Debug("Creating AWS view widgets")
+ logger.Debugf("Creating AWS view widgets")
menuItems := []string{
"[?] help", "s[w]itch mode", "[t]erminate scan", "[q]uit",
"\n\nNavigation: Use arrow keys to navigate and ESC to exit screens",
@@ -118,7 +118,7 @@ func (c *Controller) CreateWidgets(manager base.Manager) error {
}
func (c *Controller) UpdateAccount(account string) error {
- logger.Debug("Updating the AWS account details in the config")
+ logger.Debugf("Updating the AWS account details in the config")
c.Config.AWS.AccountNo = account
c.Config.AWS.Region = "us-east-1"
if err := c.Config.Save(); err != nil {
@@ -129,7 +129,7 @@ func (c *Controller) UpdateAccount(account string) error {
}
func (c *Controller) UpdateRegion(region string) error {
- logger.Debug("Updating the AWS region details in the config")
+ logger.Debugf("Updating the AWS region details in the config")
c.Config.AWS.Region = region
if err := c.Config.Save(); err != nil {
return err
@@ -140,7 +140,7 @@ func (c *Controller) UpdateRegion(region string) error {
func (c *Controller) update() error {
if v, ok := c.Views[widgets.Account]; ok {
if a, ok := v.(*widgets.AccountWidget); ok {
- logger.Debug("Updating the AWS account details in the UI")
+ logger.Debugf("Updating the AWS account details in the UI")
a.UpdateAccount(c.Config.AWS.AccountNo, c.Config.AWS.Region)
if err := c.refreshServices(); err != nil {
return err
@@ -180,10 +180,10 @@ func (c *Controller) moveViewRight(*gocui.Gui, *gocui.View) error {
func (c *Controller) switchAccount(gui *gocui.Gui, _ *gocui.View) error {
- logger.Debug("Switching AWS account")
+ logger.Debugf("Switching AWS account")
accounts, err := c.listAccountNumbers()
if err != nil {
- logger.Error("Failed to list AWS accounts. %s", err)
+ logger.Errorf("Failed to list AWS accounts. %s", err)
return err
}
@@ -191,7 +191,7 @@ func (c *Controller) switchAccount(gui *gocui.Gui, _ *gocui.View) error {
accountChoices := widgets.NewChoiceWidget("choice", x/2-10, y/2-2, x/2+10, y/2+2, " Choose or ESC ", accounts, c.UpdateAccount, c)
if err := accountChoices.Layout(gui); err != nil {
- logger.Error("Failed to create account choice widget. %s", err)
+ logger.Errorf("Failed to create account choice widget. %s", err)
return fmt.Errorf("error when rendering account choices: %w", err)
}
gui.Update(func(gui *gocui.Gui) error {
@@ -203,10 +203,10 @@ func (c *Controller) switchAccount(gui *gocui.Gui, _ *gocui.View) error {
}
func (c *Controller) switchRegion(gui *gocui.Gui, _ *gocui.View) error {
- logger.Debug("Switching AWS region")
+ logger.Debugf("Switching AWS region")
regions, err := c.listRegions(c.Config.AWS.AccountNo)
if err != nil {
- logger.Error("Failed to list AWS regions. %s", err)
+ logger.Errorf("Failed to list AWS regions. %s", err)
return err
}
@@ -214,7 +214,7 @@ func (c *Controller) switchRegion(gui *gocui.Gui, _ *gocui.View) error {
regionChoices := widgets.NewChoiceWidget("choice", x/2-10, y/2-2, x/2+10, y/2+len(regions), " Choose or ESC ", regions, c.UpdateRegion, c)
if err := regionChoices.Layout(gui); err != nil {
- logger.Error("Failed to create region choice widget. %s", err)
+ logger.Errorf("Failed to create region choice widget. %s", err)
return fmt.Errorf("error when rendering region choices: %w", err)
}
gui.Update(func(gui *gocui.Gui) error {
@@ -227,7 +227,7 @@ func (c *Controller) switchRegion(gui *gocui.Gui, _ *gocui.View) error {
func (c *Controller) discoverAccount(region string) (string, string, error) {
ctx := context.Background()
- logger.Debug("Loading credentials from default config")
+ logger.Debugf("Loading credentials from default config")
cfg, err := awsConfig.LoadDefaultConfig(ctx)
if err != nil {
return "", "", err
@@ -239,21 +239,21 @@ func (c *Controller) discoverAccount(region string) (string, string, error) {
}
if regionEnv, ok := os.LookupEnv("AWS_REGION"); ok {
- logger.Debug("Using AWS_REGION environment variable")
+ logger.Debugf("Using AWS_REGION environment variable")
cfg.Region = regionEnv
}
svc := sts.NewFromConfig(cfg)
result, err := svc.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
if err != nil {
- logger.Error("Error getting caller identity")
+ logger.Errorf("Error getting caller identity")
return "", "", fmt.Errorf("failed to discover AWS caller identity: %w", err)
}
if result.Account == nil {
return "", "", fmt.Errorf("missing account id for aws account")
}
- logger.Debug("Discovered AWS account %s", *result.Account)
+ logger.Debugf("Discovered AWS account %s", *result.Account)
return *result.Account, cfg.Region, nil
}
@@ -263,7 +263,7 @@ func (c *Controller) scanAccount(gui *gocui.Gui, _ *gocui.View) error {
if err != nil {
if strings.HasPrefix(err.Error(), "failed to discover AWS caller identity") {
c.UpdateStatus("Failed to discover AWS credentials.")
- logger.Error("failed to discover AWS credentials: %v", err)
+ logger.Errorf("failed to discover AWS credentials: %v", err)
return NewErrNoValidCredentials()
}
return err
@@ -272,7 +272,7 @@ func (c *Controller) scanAccount(gui *gocui.Gui, _ *gocui.View) error {
c.UpdateStatus("Checking credentials for account...")
if account != c.Config.AWS.AccountNo && c.Config.AWS.AccountNo != "" {
c.UpdateStatus("Account number does not match credentials.")
- logger.Error("Account number does not match credentials.")
+ logger.Errorf("Account number does not match credentials.")
return fmt.Errorf("account number mismatch: %s != %s", account, c.Config.AWS.AccountNo)
}
@@ -293,7 +293,7 @@ func (c *Controller) scanAccount(gui *gocui.Gui, _ *gocui.View) error {
_, _ = gui.SetCurrentView(widgets.Results)
if err := c.refreshServices(); err != nil {
- logger.Error("Error refreshing services: %v", err)
+ logger.Errorf("Error refreshing services: %v", err)
}
c.UpdateStatus("Account scan complete.")
}()
@@ -313,8 +313,8 @@ func (c *Controller) RenderAWSResultsReport(report *output.Report) error {
func (c *Controller) RenderAWSResultsReportSummary(report *output.Report) error {
if v, ok := c.Views[widgets.Results].(*widgets.AWSResultWidget); ok {
- v.UpdateResultsTable([]*output.Report{report})
- _, _ = c.Cui.SetCurrentView(widgets.Results)
+ v.UpdateResultsTable([]*output.Report{report}, c.Cui)
+
}
return fmt.Errorf("failed to render results report summary") //nolint:goerr113
}
diff --git a/pkg/controllers/aws/help.go b/pkg/controllers/aws/help.go
index 88a2bdd..af8ba9d 100644
--- a/pkg/controllers/aws/help.go
+++ b/pkg/controllers/aws/help.go
@@ -20,7 +20,7 @@ func help(gui *gocui.Gui, _ *gocui.View) error {
w, h := gui.Size()
- v := widgets.NewHelpWidget("help", w/2-22, h/2-4, w/2+23, h/2+3, helpCommands)
+ v := widgets.NewAnnouncementWidget("help", "Help", w, h, helpCommands, gui)
if err := gui.SetKeybinding("help", gocui.KeyEsc, gocui.ModNone, func(gui *gocui.Gui, _ *gocui.View) error {
if _, err := gui.SetCurrentView("services"); err != nil {
diff --git a/pkg/controllers/aws/key_bindings.go b/pkg/controllers/aws/key_bindings.go
index 0f7fc09..5ba274d 100644
--- a/pkg/controllers/aws/key_bindings.go
+++ b/pkg/controllers/aws/key_bindings.go
@@ -9,7 +9,7 @@ import (
)
func (c *Controller) configureKeyBindings() error {
- logger.Debug("Configuring global AWS Controller keyboard shortcuts")
+ logger.Debugf("Configuring global AWS Controller keyboard shortcuts")
if err := c.ConfigureGlobalKeyBindings(); err != nil {
return fmt.Errorf("error configuring global keybindings: %w", err)
}
diff --git a/pkg/controllers/aws/service.go b/pkg/controllers/aws/service.go
index 21e3a63..df19e42 100644
--- a/pkg/controllers/aws/service.go
+++ b/pkg/controllers/aws/service.go
@@ -50,7 +50,7 @@ func (c *Controller) CancelCurrentScan(_ *gocui.Gui, _ *gocui.View) error {
c.Lock()
defer c.Unlock()
if c.ActiveCancel != nil {
- logger.Debug("Cancelling current scan")
+ logger.Debugf("Cancelling current scan")
c.UpdateStatus("Current scan cancelled.")
c.ActiveCancel()
c.ActiveCancel = nil
diff --git a/pkg/controllers/aws/state.go b/pkg/controllers/aws/state.go
index 1f43983..f2b1eff 100644
--- a/pkg/controllers/aws/state.go
+++ b/pkg/controllers/aws/state.go
@@ -5,14 +5,12 @@ import (
"fmt"
"os"
"path/filepath"
- "sync"
"github.com/owenrumney/lazytrivy/pkg/logger"
"github.com/owenrumney/lazytrivy/pkg/output"
)
type state struct {
- stateLock sync.Mutex
services []string
selectedService string
serviceWidth int
@@ -25,7 +23,7 @@ func (s *state) accountRegionCache(accountID, region string) string {
}
func (s *state) listAccountNumbers() ([]string, error) {
- logger.Debug("listing account numbers")
+ logger.Debugf("listing account numbers")
var accountNumbers []string
fileInfos, err := os.ReadDir(s.cacheDirectory)
if err != nil {
@@ -40,7 +38,7 @@ func (s *state) listAccountNumbers() ([]string, error) {
}
func (s *state) listRegions(accountNumber string) ([]string, error) {
- logger.Debug("listing regions")
+ logger.Debugf("listing regions")
var regions []string
accountPath := filepath.Join(s.cacheDirectory, accountNumber)
fileInfos, err := os.ReadDir(accountPath)
@@ -59,7 +57,7 @@ func (s *state) accountRegionCacheExists(accountID, region string) bool {
if _, err := os.Stat(s.accountRegionCache(accountID, region)); err == nil {
return true
}
- logger.Debug("cache does not exist for %s (%s)", accountID, region)
+ logger.Debugf("cache does not exist for %s (%s)", accountID, region)
return false
}
@@ -93,21 +91,6 @@ func (s *state) accountRegionCacheServices(accountID, region string) ([]string,
return services, nil
}
-func (s *state) updateServices(services []string) {
- s.stateLock.Lock()
- defer s.stateLock.Unlock()
- s.services = services
-
- s.serviceWidth = getLongestName(services)
- s.selectedService = ""
-}
-
-func (s *state) setSelected(selectedImage string) {
- s.stateLock.Lock()
- defer s.stateLock.Unlock()
- s.selectedService = selectedImage
-}
-
func (s *state) getServiceReport(accountID, region, serviceName string) (*output.Report, error) {
cachePath := s.accountRegionCache(accountID, region)
@@ -120,7 +103,7 @@ func (s *state) getServiceReport(accountID, region, serviceName string) (*output
var report output.Report
if err := json.Unmarshal(content, &report); err != nil {
- logger.Error("failed to unmarshal report: %s", err)
+ logger.Errorf("failed to unmarshal report: %s", err)
return nil, err
}
report.Process()
diff --git a/pkg/controllers/base/global_keybindings.go b/pkg/controllers/base/global_keybindings.go
index bdbcfbd..e78f94e 100644
--- a/pkg/controllers/base/global_keybindings.go
+++ b/pkg/controllers/base/global_keybindings.go
@@ -8,7 +8,7 @@ import (
)
func (c *Controller) ConfigureGlobalKeyBindings() error {
- logger.Debug("Configuring global keyboard shortcuts")
+ logger.Debugf("Configuring global keyboard shortcuts")
if err := c.Cui.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, Quit); err != nil {
return fmt.Errorf("error setting keybinding for quitting with Ctrl+C: %w", err)
diff --git a/pkg/controllers/gui/gui.go b/pkg/controllers/gui/gui.go
index f6b2717..cc531cc 100644
--- a/pkg/controllers/gui/gui.go
+++ b/pkg/controllers/gui/gui.go
@@ -26,7 +26,7 @@ type Controller struct {
}
func New() (*Controller, error) {
- logger.Debug("Creating GUI")
+ logger.Debugf("Creating GUI")
cui, err := gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
return nil, fmt.Errorf("failed to create gui: %w", err)
diff --git a/pkg/controllers/vulnerabilities/help.go b/pkg/controllers/vulnerabilities/help.go
index 1ee351e..47b29e8 100644
--- a/pkg/controllers/vulnerabilities/help.go
+++ b/pkg/controllers/vulnerabilities/help.go
@@ -19,16 +19,7 @@ func help(gui *gocui.Gui, _ *gocui.View) error {
w, h := gui.Size()
- v := widgets.NewHelpWidget("help", w/2-22, h/2-4, w/2+22, h/2+4, helpCommands)
-
- if err := gui.SetKeybinding("help", gocui.KeyEsc, gocui.ModNone, func(gui *gocui.Gui, _ *gocui.View) error {
- if _, err := gui.SetCurrentView("images"); err != nil {
- return err
- }
- return gui.DeleteView("help")
- }); err != nil {
- return err
- }
+ v := widgets.NewAnnouncementWidget("help", "Help", w, h, helpCommands, gui)
gui.Update(func(g *gocui.Gui) error {
if err := v.Layout(g); err != nil {
diff --git a/pkg/controllers/vulnerabilities/image.go b/pkg/controllers/vulnerabilities/image.go
index 5e8fca8..08ce41d 100644
--- a/pkg/controllers/vulnerabilities/image.go
+++ b/pkg/controllers/vulnerabilities/image.go
@@ -12,7 +12,7 @@ import (
)
func (c *Controller) SetSelected(selected string) {
- logger.Debug("Setting selected image to %s", selected)
+ logger.Debugf("Setting selected image to %s", selected)
c.setSelected(strings.TrimSpace(selected))
}
@@ -81,12 +81,12 @@ func (c *Controller) ScanAllImages(gui *gocui.Gui, _ *gocui.View) error {
}
func (c *Controller) RefreshImages() error {
- logger.Debug("refreshing images")
+ logger.Debugf("refreshing images")
c.UpdateStatus("Refreshing images")
defer c.ClearStatus()
images := c.DockerClient.ListImages()
- logger.Debug("found %d images", len(images))
+ logger.Debugf("found %d images", len(images))
c.updateImages(images)
if v, ok := c.Views[widgets.Images].(*widgets.ImagesWidget); ok {
diff --git a/pkg/controllers/vulnerabilities/vulnerability.go b/pkg/controllers/vulnerabilities/vulnerability.go
index db9f7e7..0a77058 100644
--- a/pkg/controllers/vulnerabilities/vulnerability.go
+++ b/pkg/controllers/vulnerabilities/vulnerability.go
@@ -32,7 +32,7 @@ func NewVulnerabilityController(cui *gocui.Gui, dockerClient *docker.Client, cfg
}
func (c *Controller) Initialise() error {
- logger.Debug("initialising vulnerability controller")
+ logger.Debugf("initialising vulnerability controller")
var outerErr error
c.Cui.Update(func(gui *gocui.Gui) error {
@@ -45,7 +45,7 @@ func (c *Controller) Initialise() error {
}
for _, v := range c.Views {
- if err := v.ConfigureKeys(); err != nil {
+ if err := v.ConfigureKeys(nil); err != nil {
return fmt.Errorf("failed to configure view keys: %w", err)
}
}
@@ -119,18 +119,15 @@ func (c *Controller) moveViewRight(*gocui.Gui, *gocui.View) error {
func (c *Controller) RenderResultsReport(report *output.Report) error {
if v, ok := c.Views[widgets.Results].(*widgets.ImageResultWidget); ok {
- v.RenderReport(report, "ALL")
- _, err := c.Cui.SetCurrentView(widgets.Results)
- if err != nil {
- return fmt.Errorf("failed to set current view: %w", err)
- }
+ v.RenderReport(report, "ALL", c.Cui)
+
}
return nil
}
func (c *Controller) RenderResultsReportSummary(reports []*output.Report) error {
if v, ok := c.Views[widgets.Results].(*widgets.ImageResultWidget); ok {
- v.UpdateResultsTable(reports)
+ v.UpdateResultsTable(reports, c.Cui)
_, err := c.Cui.SetCurrentView(widgets.Results)
if err != nil {
return fmt.Errorf("error setting current view: %w", err)
diff --git a/pkg/docker/client.go b/pkg/docker/client.go
index f28bfdd..d518d3f 100644
--- a/pkg/docker/client.go
+++ b/pkg/docker/client.go
@@ -32,7 +32,7 @@ type Client struct {
}
func NewClient() *Client {
- logger.Debug("Creating docker client")
+ logger.Debugf("Creating docker client")
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
panic(err)
@@ -58,7 +58,7 @@ func (c *Client) ListImages() []string {
if image.RepoTags != nil {
imageName := image.RepoTags[0]
if strings.HasPrefix(imageName, "lazytrivy:") {
- logger.Debug("Found trivy image %s", imageName)
+ logger.Debugf("Found trivy image %s", imageName)
c.trivyImagePresent = true
continue
@@ -70,7 +70,7 @@ func (c *Client) ListImages() []string {
sort.Strings(imageNames)
c.imageNames = imageNames
- logger.Debug("Found %d images", len(imageNames))
+ logger.Debugf("Found %d images", len(imageNames))
return c.imageNames
}
@@ -102,18 +102,18 @@ func (c *Client) ScanService(ctx context.Context, serviceName string, accountNo,
}
if serviceName != "" {
- logger.Debug("Scan will target service %s", serviceName)
+ logger.Debugf("Scan will target service %s", serviceName)
command = append(command, "--services", serviceName)
}
if updateCache {
- logger.Debug("Cache will be updated for %s", serviceName)
+ logger.Debugf("Cache will be updated for %s", serviceName)
command = append(command, "--update-cache")
}
return c.scan(ctx, command, target, env, progress)
}
func (c *Client) ScanImage(ctx context.Context, imageName string, progress Progress) (*output.Report, error) {
- logger.Debug("Scanning image %s", imageName)
+ logger.Debugf("Scanning image %s", imageName)
progress.UpdateStatus(fmt.Sprintf("Scanning image %s...", imageName))
command := []string{"image", "-f=json", imageName}
@@ -122,44 +122,18 @@ func (c *Client) ScanImage(ctx context.Context, imageName string, progress Progr
func (c *Client) scan(ctx context.Context, command []string, scanTarget string, env []string, progress Progress) (*output.Report, error) {
if !c.trivyImagePresent {
- logger.Debug("Creating the docker image, it isn't present")
-
- dockerfile := createDockerFile()
- tempDir, err := os.MkdirTemp("", "lazytrivy")
- dockerFilePath := filepath.Join(tempDir, "Dockerfile")
-
- defer func() { _ = os.RemoveAll(tempDir) }()
-
- if err := os.WriteFile(dockerFilePath, []byte(dockerfile), 0644); err != nil {
- return nil, err
- }
-
- tar, err := archive.TarWithOptions(tempDir, &archive.TarOptions{})
- if err != nil {
- return nil, err
- }
-
- resp, err := c.client.ImageBuild(ctx, tar, types.ImageBuildOptions{
- PullParent: true,
- Dockerfile: "Dockerfile",
- Tags: []string{"lazytrivy:latest"},
- })
- if err != nil {
- return nil, err
- }
-
- _, _ = io.Copy(io.Discard, resp.Body)
- if err := resp.Body.Close(); err != nil {
- return nil, err
+ report, err2 := c.buildScannerImage(ctx)
+ if err2 != nil {
+ return report, err2
}
}
- logger.Debug("Running trivy scan with command %s", command)
+ logger.Debugf("Running trivy scan with command %s", command)
userHomeDir, err := os.UserHomeDir()
if err != nil {
- logger.Debug("Error getting user home dir: %s", err)
+ logger.Debugf("Error getting user home dir: %s", err)
userHomeDir = os.TempDir()
}
@@ -186,7 +160,7 @@ func (c *Client) scan(ctx context.Context, command []string, scanTarget string,
// make sure we kill the container
defer func() {
- logger.Debug("Removing container %s", cont.ID)
+ logger.Debugf("Removing container %s", cont.ID)
_ = c.client.ContainerRemove(ctx, cont.ID, types.ContainerRemoveOptions{})
}()
@@ -230,23 +204,57 @@ func (c *Client) scan(ctx context.Context, command []string, scanTarget string,
}
}
+func (c *Client) buildScannerImage(ctx context.Context) (*output.Report, error) {
+ logger.Debugf("Creating the docker image, it isn't present")
+
+ dockerfile := createDockerFile()
+ tempDir, err := os.MkdirTemp("", "lazytrivy")
+ dockerFilePath := filepath.Join(tempDir, "Dockerfile")
+
+ defer func() { _ = os.RemoveAll(tempDir) }()
+
+ if err := os.WriteFile(dockerFilePath, []byte(dockerfile), 0644); err != nil {
+ return nil, err
+ }
+
+ tar, err := archive.TarWithOptions(tempDir, &archive.TarOptions{})
+ if err != nil {
+ return nil, err
+ }
+
+ resp, err := c.client.ImageBuild(ctx, tar, types.ImageBuildOptions{
+ PullParent: true,
+ Dockerfile: "Dockerfile",
+ Tags: []string{"lazytrivy:latest"},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ _, _ = io.Copy(io.Discard, resp.Body)
+ if err := resp.Body.Close(); err != nil {
+ return nil, err
+ }
+ return nil, nil
+}
+
func (c *Client) ScanAllImages(ctx context.Context, progress Progress) ([]*output.Report, error) {
var reports []*output.Report // nolint
for _, imageName := range c.imageNames {
progress.UpdateStatus(fmt.Sprintf("Scanning image %s...", imageName))
- logger.Debug("Scanning image %s", imageName)
+ logger.Debugf("Scanning image %s", imageName)
report, err := c.ScanImage(ctx, imageName, progress)
if err != nil {
return nil, err
}
progress.UpdateStatus(fmt.Sprintf("Scanning image %s...done", imageName))
- logger.Debug("Scanning image %s...done", imageName)
+ logger.Debugf("Scanning image %s...done", imageName)
reports = append(reports, report)
select {
case <-ctx.Done():
- logger.Debug("Context cancelled")
+ logger.Debugf("Context cancelled")
return nil, ctx.Err() // nolint
default:
}
diff --git a/pkg/logger/debug.go b/pkg/logger/debug.go
index 750d33f..40500c3 100644
--- a/pkg/logger/debug.go
+++ b/pkg/logger/debug.go
@@ -14,19 +14,19 @@ var (
func EnableDebugging() {
debugEnabled = true
- logFile := filepath.Join(os.TempDir(), "lazytrivy-logger.log")
- debugFile, _ = os.OpenFile(logFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
+ logFile := filepath.Join(os.TempDir(), "lazytrivy-logger.logf")
+ debugFile, _ = os.OpenFile(logFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) // nolint: nosnakecase
}
-func Debug(format string, args ...interface{}) {
- log("DEBUG", format, args...)
+func Debugf(format string, args ...interface{}) {
+ logf("DEBUG", format, args...)
}
-func Error(format string, args ...interface{}) {
- log("ERROR", format, args...)
+func Errorf(format string, args ...interface{}) {
+ logf("ERROR", format, args...)
}
-func log(level string, format string, args ...interface{}) {
+func logf(level string, format string, args ...interface{}) {
if debugEnabled {
_, _ = fmt.Fprintf(debugFile, fmt.Sprintf("%s [%s] ", time.RFC3339, level)+fmt.Sprintf(format, args...))
_, _ = fmt.Fprintln(debugFile)
diff --git a/pkg/output/report.go b/pkg/output/report.go
index c66d8df..fe84bd1 100644
--- a/pkg/output/report.go
+++ b/pkg/output/report.go
@@ -68,10 +68,10 @@ type Misconfiguration struct {
}
func FromJSON(imageName string, content string) (*Report, error) {
- logger.Debug("Parsing JSON report")
+ logger.Debugf("Parsing JSON report")
var report Report
if err := json.Unmarshal([]byte(content), &report); err != nil {
- logger.Error("Failed to parse JSON report. %s", err)
+ logger.Errorf("Failed to parse JSON report. %s", err)
return nil, err
}
report.Process()
@@ -102,7 +102,7 @@ func (r *Report) Process() {
}
}
if found {
- r.vulnerabilities++
+
foundResult.Vulnerabilities = append(foundResult.Vulnerabilities, v)
} else {
foundResult = &Result{
@@ -111,6 +111,7 @@ func (r *Report) Process() {
}
sevMap = append(sevMap, foundResult)
}
+ r.vulnerabilities++
r.SeverityMap[v.Severity] = sevMap
r.SeverityCount[v.Severity]++
@@ -132,7 +133,7 @@ func (r *Report) Process() {
}
}
if found {
- r.misconfigurations++
+
foundResult.Misconfigurations = append(foundResult.Misconfigurations, m)
} else {
foundResult = &Result{
@@ -141,6 +142,7 @@ func (r *Report) Process() {
}
sevMap = append(sevMap, foundResult)
}
+ r.misconfigurations++
r.SeverityMap[m.Severity] = sevMap
r.SeverityCount[m.Severity]++
@@ -175,3 +177,7 @@ func (r *Report) GetTotalVulnerabilities() int {
func (r *Report) GetTotalMisconfigurations() int {
return r.misconfigurations
}
+
+func (r *Report) HasIssues() bool {
+ return r.GetTotalVulnerabilities() > 0 || r.GetTotalMisconfigurations() > 0
+}
diff --git a/pkg/widgets/account.go b/pkg/widgets/account.go
index df2d563..2a313a8 100644
--- a/pkg/widgets/account.go
+++ b/pkg/widgets/account.go
@@ -32,7 +32,7 @@ func NewAccountWidget(name, accountNumber, region string) *AccountWidget {
}
}
-func (w *AccountWidget) ConfigureKeys() error {
+func (w *AccountWidget) ConfigureKeys(*gocui.Gui) error {
// nothing to configure here
return nil
}
diff --git a/pkg/widgets/announce.go b/pkg/widgets/announce.go
new file mode 100644
index 0000000..5aed49f
--- /dev/null
+++ b/pkg/widgets/announce.go
@@ -0,0 +1,92 @@
+package widgets
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/awesome-gocui/gocui"
+)
+
+type AnnouncementWidget struct {
+ name string
+ x, y int
+ w, h int
+ body []string
+ v *gocui.View
+ title string
+ ctx *gocui.Gui
+}
+
+func (w *AnnouncementWidget) RefreshView() {
+ panic("unimplemented")
+}
+
+func NewAnnouncementWidget(name, title string, width, height int, lines []string, ctx *gocui.Gui) *AnnouncementWidget {
+ maxLength := 0
+
+ for _, item := range lines {
+ if len(item) > maxLength {
+ maxLength = len(item)
+ }
+ }
+
+ maxLength += 2
+ maxHeight := len(lines) + 2
+
+ x := width/2 - maxLength/2
+ w := width/2 + maxLength/2
+
+ y := height/2 - maxHeight/2
+ h := height/2 + maxHeight/2
+
+ return &AnnouncementWidget{
+ name: name,
+ title: title,
+ x: x,
+ y: y,
+ w: w,
+ h: h,
+ body: lines,
+ v: nil,
+ ctx: ctx,
+ }
+}
+
+func (w *AnnouncementWidget) ConfigureKeys(*gocui.Gui) error {
+ if err := w.ctx.SetKeybinding(w.name, gocui.KeyEsc, gocui.ModNone, func(gui *gocui.Gui, _ *gocui.View) error {
+ if _, err := gui.SetCurrentView(Results); err != nil {
+ return err
+ }
+ return gui.DeleteView(w.name)
+ }); err != nil {
+ return err
+ }
+
+ if err := w.ctx.SetKeybinding(w.name, 'q', gocui.ModNone, func(gui *gocui.Gui, _ *gocui.View) error {
+ if _, err := gui.SetCurrentView(Results); err != nil {
+ return err
+ }
+ return gui.DeleteView(w.name)
+ }); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (w *AnnouncementWidget) Layout(g *gocui.Gui) error {
+ v, err := g.SetView(w.name, w.x, w.y, w.w, w.h, 0)
+ if err != nil {
+ if !errors.Is(err, gocui.ErrUnknownView) {
+ return fmt.Errorf("%w", err)
+ }
+ }
+ v.Clear()
+ _, _ = fmt.Fprint(v, strings.Join(w.body, "\n"))
+ v.Title = fmt.Sprintf(" %s ", w.title)
+ v.Wrap = true
+ v.FrameColor = gocui.ColorGreen
+ w.v = v
+
+ return w.ConfigureKeys(nil)
+}
diff --git a/pkg/widgets/aws_results.go b/pkg/widgets/aws_results.go
index a43ee4d..0293e7b 100644
--- a/pkg/widgets/aws_results.go
+++ b/pkg/widgets/aws_results.go
@@ -38,7 +38,7 @@ func NewAWSResultWidget(name string, g awsContext) *AWSResultWidget {
return widget
}
-func (w *AWSResultWidget) ConfigureKeys() error {
+func (w *AWSResultWidget) ConfigureKeys(gui *gocui.Gui) error {
if err := w.configureListWidgetKeys(w.name); err != nil {
return err
}
@@ -49,14 +49,14 @@ func (w *AWSResultWidget) ConfigureKeys() error {
if err := w.ctx.SetKeyBinding(w.name, 'b', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
if w.results != nil && len(w.results) > 0 {
- w.UpdateResultsTable([]*output.Report{w.currentReport})
+ w.UpdateResultsTable([]*output.Report{w.currentReport}, g)
}
return nil
}); err != nil {
return fmt.Errorf("failed to set keybinding: %w", err)
}
- if err := w.addFilteringKeyBindings(); err != nil {
+ if err := w.addFilteringKeyBindings(gui); err != nil {
return err
}
@@ -71,8 +71,8 @@ func (w *AWSResultWidget) diveDeeper(g *gocui.Gui, _ *gocui.View) error {
return nil
}
w.currentResult = w.results[id]
- logger.Debug("Diving deeper into result: %s", w.currentResult.Target)
- w.GenerateFilteredReport("ALL")
+ logger.Debugf("Diving deeper into result: %s", w.currentResult.Target)
+ w.GenerateFilteredReport("ALL", g)
case DetailsResultMode:
x, y, wi, h := w.v.Dimensions()
@@ -137,12 +137,32 @@ func (w *AWSResultWidget) Reset() {
}
}
-func (w *AWSResultWidget) UpdateResultsTable(reports []*output.Report) {
+func (w *AWSResultWidget) UpdateResultsTable(reports []*output.Report, g *gocui.Gui) {
if len(reports) == 0 {
return
}
+
w.mode = SummaryResultMode
w.currentReport = reports[0]
+ w.currentReport.Process()
+ w.v.Clear()
+ w.body = []string{}
+
+ if w.currentReport == nil || !w.currentReport.HasIssues() {
+ width, height := w.v.Size()
+
+ lines := []string{
+ "Great News!",
+ "",
+ "No misconfigurations found!",
+ }
+
+ announcement := NewAnnouncementWidget(Announcement, "No Results", width, height, lines, g)
+ _ = announcement.Layout(g)
+ _, _ = g.SetCurrentView(Announcement)
+
+ return
+ }
width, _ := w.v.Size()
@@ -180,6 +200,7 @@ func (w *AWSResultWidget) UpdateResultsTable(reports []*output.Report) {
w.body = bodyContent
+ _, _ = g.SetCurrentView(Results)
w.ctx.RefreshView(w.name)
w.SetStartPosition(3)
@@ -190,11 +211,23 @@ func (w *AWSResultWidget) UpdateResultsTable(reports []*output.Report) {
func (w *AWSResultWidget) RenderReport(report *output.Report, severity string) {
w.currentReport = report
- w.GenerateFilteredReport(severity)
+ w.GenerateFilteredReport(severity, nil)
}
-func (w *AWSResultWidget) GenerateFilteredReport(severity string) {
+func (w *AWSResultWidget) GenerateFilteredReport(severity string, g *gocui.Gui) {
if w.currentResult == nil || len(w.currentResult.Misconfigurations) == 0 {
+ width, height := w.v.Size()
+
+ lines := []string{
+ "Great News!",
+ "",
+ "No misconfigurations found!",
+ }
+
+ announcement := NewAnnouncementWidget(Announcement, "No Results", width, height, lines, g)
+ _ = announcement.Layout(g)
+ _, _ = g.SetCurrentView(Announcement)
+
return
}
diff --git a/pkg/widgets/aws_summary.go b/pkg/widgets/aws_summary.go
index 176c743..cc44be2 100644
--- a/pkg/widgets/aws_summary.go
+++ b/pkg/widgets/aws_summary.go
@@ -19,7 +19,6 @@ type AWSSummaryWidget struct {
func NewAWSSummaryWidget(name string, x, y, w, h int, ctx awsContext, vulnerability output.Misconfiguration) (*AWSSummaryWidget, error) {
if err := ctx.SetKeyBinding(Remote, gocui.KeyEnter, gocui.ModNone, func(gui *gocui.Gui, view *gocui.View) error {
-
gui.Mouse = true
gui.Cursor = false
diff --git a/pkg/widgets/choices.go b/pkg/widgets/choices.go
index 8627f17..c7fd95a 100644
--- a/pkg/widgets/choices.go
+++ b/pkg/widgets/choices.go
@@ -43,7 +43,7 @@ func NewChoiceWidget(name string, x, y, w, h int, title string, choices []string
}
}
-func (w *ChoiceWidget) ConfigureKeys() error {
+func (w *ChoiceWidget) ConfigureKeys(*gocui.Gui) error {
if err := w.configureListWidgetKeys(w.name); err != nil {
return err
}
@@ -84,7 +84,7 @@ func (w *ChoiceWidget) Layout(g *gocui.Gui) error {
w.SetStartPosition(0)
w.v = v
- if err := w.ConfigureKeys(); err != nil {
+ if err := w.ConfigureKeys(nil); err != nil {
return err
}
diff --git a/pkg/widgets/help.go b/pkg/widgets/help.go
deleted file mode 100644
index ebfc119..0000000
--- a/pkg/widgets/help.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package widgets
-
-import (
- "errors"
- "fmt"
- "strings"
-
- "github.com/awesome-gocui/gocui"
-)
-
-type HelpWidget struct {
- name string
- x, y int
- w, h int
- body []string
- v *gocui.View
-}
-
-func (w *HelpWidget) RefreshView() {
- panic("unimplemented")
-}
-
-func NewHelpWidget(name string, x, y, w, h int, helpItems []string) *HelpWidget {
- // TODO update to accept parent size and calculate own size based on helpItems
-
- return &HelpWidget{
- name: name,
- x: x,
- y: y,
- w: w,
- h: h,
- body: helpItems,
- v: nil,
- }
-}
-
-func (w *HelpWidget) ConfigureKeys() error {
- // nothing to configure here
- return nil
-}
-
-func (w *HelpWidget) Layout(g *gocui.Gui) error {
- v, err := g.SetView(w.name, w.x, w.y, w.w, w.h, 0)
- if err != nil {
- if !errors.Is(err, gocui.ErrUnknownView) {
- return fmt.Errorf("%w", err)
- }
- }
- v.Clear()
- _, _ = fmt.Fprint(v, strings.Join(w.body, "\n"))
- v.Title = " Help "
- v.Subtitle = " ESC to exit"
- v.Wrap = true
- v.FrameColor = gocui.ColorGreen
- w.v = v
- return nil
-}
diff --git a/pkg/widgets/host.go b/pkg/widgets/host.go
index de50f63..837b057 100644
--- a/pkg/widgets/host.go
+++ b/pkg/widgets/host.go
@@ -34,7 +34,7 @@ func NewHostWidget(name string, ctx vulnerabilityContext) *HostWidget {
}
}
-func (w *HostWidget) ConfigureKeys() error {
+func (w *HostWidget) ConfigureKeys(*gocui.Gui) error {
// nothing to configure here
return nil
}
diff --git a/pkg/widgets/image_results.go b/pkg/widgets/image_results.go
index e0d3b50..121aef1 100644
--- a/pkg/widgets/image_results.go
+++ b/pkg/widgets/image_results.go
@@ -35,7 +35,7 @@ func NewImageResultWidget(name string, g vulnerabilityContext) *ImageResultWidge
return widget
}
-func (w *ImageResultWidget) ConfigureKeys() error {
+func (w *ImageResultWidget) ConfigureKeys(g *gocui.Gui) error {
if err := w.configureListWidgetKeys(w.name); err != nil {
return err
}
@@ -50,14 +50,14 @@ func (w *ImageResultWidget) ConfigureKeys() error {
if err := w.ctx.SetKeyBinding(w.name, 'b', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error {
if w.reports != nil && len(w.reports) > 0 {
- w.UpdateResultsTable(w.reports)
+ w.UpdateResultsTable(w.reports, g)
}
return nil
}); err != nil {
return fmt.Errorf("failed to set keybinding: %w", err)
}
- if err := w.addFilteringKeyBindings(); err != nil {
+ if err := w.addFilteringKeyBindings(nil); err != nil {
return err
}
@@ -74,7 +74,7 @@ func (w *ImageResultWidget) diveDeeper(g *gocui.Gui, v *gocui.View) error {
return nil
}
- w.GenerateFilteredReport("ALL")
+ w.GenerateFilteredReport("ALL", g)
case DetailsResultMode:
x, y, wi, h := v.Dimensions()
@@ -105,7 +105,7 @@ func (w *ImageResultWidget) diveDeeper(g *gocui.Gui, v *gocui.View) error {
return nil
}
-func (w *ImageResultWidget) UpdateResultsTable(reports []*output.Report) {
+func (w *ImageResultWidget) UpdateResultsTable(reports []*output.Report, g *gocui.Gui) {
w.mode = SummaryResultMode
w.reports = reports
@@ -148,13 +148,33 @@ func (w *ImageResultWidget) UpdateResultsTable(reports []*output.Report) {
w.v.Subtitle = ""
}
-func (w *ImageResultWidget) RenderReport(report *output.Report, severity string) {
+func (w *ImageResultWidget) RenderReport(report *output.Report, severity string, cui *gocui.Gui) {
w.currentReport = report
+ w.v.Clear()
+ w.body = []string{}
- w.GenerateFilteredReport(severity)
+ if w.currentReport == nil || !w.currentReport.HasIssues() {
+ width, height := w.v.Size()
+
+ lines := []string{
+ "Great News!",
+ "",
+ "No vulnerabilities found!",
+ }
+
+ announcement := NewAnnouncementWidget(Announcement, "No Results", width, height, lines, cui)
+ _ = announcement.Layout(cui)
+ _, _ = cui.SetCurrentView(Announcement)
+
+ return
+ }
+
+ w.GenerateFilteredReport(severity, cui)
+
+ _, _ = cui.SetCurrentView(Results)
}
-func (w *ImageResultWidget) GenerateFilteredReport(severity string) {
+func (w *ImageResultWidget) GenerateFilteredReport(severity string, g *gocui.Gui) {
if w.currentReport == nil {
return
}
diff --git a/pkg/widgets/images.go b/pkg/widgets/images.go
index 1c91433..1ee6fa6 100644
--- a/pkg/widgets/images.go
+++ b/pkg/widgets/images.go
@@ -15,9 +15,8 @@ type ImagesWidget struct {
x, y int
w, h int
- imageCount int
- ctx vulnerabilityContext
- v *gocui.View
+ ctx vulnerabilityContext
+ v *gocui.View
}
func NewImagesWidget(name string, g vulnerabilityContext) *ImagesWidget {
@@ -39,7 +38,7 @@ func NewImagesWidget(name string, g vulnerabilityContext) *ImagesWidget {
return widget
}
-func (w *ImagesWidget) ConfigureKeys() error {
+func (w *ImagesWidget) ConfigureKeys(*gocui.Gui) error {
if err := w.ctx.SetKeyBinding(w.name, gocui.KeyArrowUp, gocui.ModNone, w.previousItem); err != nil {
return fmt.Errorf("failed to set the previous image %w", err)
}
diff --git a/pkg/widgets/list.go b/pkg/widgets/list.go
index dcb3743..835c9bb 100644
--- a/pkg/widgets/list.go
+++ b/pkg/widgets/list.go
@@ -51,10 +51,9 @@ func (w *ListWidget) nextItem(_ *gocui.Gui, v *gocui.View) error {
}
v.MoveCursor(0, 1)
- _, h := v.Size()
_, oy := v.Origin()
_, y := v.Cursor()
- if y == h {
+ if _, h := v.Size(); y == h {
if err := v.SetOrigin(0, oy+1); err != nil {
return err
}
@@ -74,6 +73,10 @@ func (w *ListWidget) nextItem(_ *gocui.Gui, v *gocui.View) error {
}
func (w *ListWidget) CurrentItemPosition() int {
+ if len(w.body) == 0 {
+ return -1
+ }
+
currentLine := w.body[w.currentPos]
if strings.HasPrefix(currentLine, "**") {
idString := strings.TrimPrefix(strings.Split(currentLine, "***")[0], "**")
diff --git a/pkg/widgets/menu.go b/pkg/widgets/menu.go
index 8bf8c92..948c61e 100644
--- a/pkg/widgets/menu.go
+++ b/pkg/widgets/menu.go
@@ -34,7 +34,7 @@ func NewMenuWidget(name string, x, y, w, h int, menuItems []string) *MenuWidget
}
}
-func (w *MenuWidget) ConfigureKeys() error {
+func (w *MenuWidget) ConfigureKeys(*gocui.Gui) error {
// nothing to configure here
return nil
}
diff --git a/pkg/widgets/results.go b/pkg/widgets/results.go
index 7adc450..f17c8aa 100644
--- a/pkg/widgets/results.go
+++ b/pkg/widgets/results.go
@@ -21,16 +21,16 @@ type ResultsWidget struct {
ListWidget
name string
- generateReportFunc func(severity string)
- updateResultsTableFunc func(reports []*output.Report)
+ generateReportFunc func(severity string, gui *gocui.Gui)
+ updateResultsTableFunc func(reports []*output.Report, g *gocui.Gui)
ctx baseContext
currentReport *output.Report
mode ResultsMode
v *gocui.View
}
-func NewResultsWidget(name string, generateReportFunc func(severity string),
- updateResultsTableFunc func(reports []*output.Report), g baseContext) ResultsWidget {
+func NewResultsWidget(name string, generateReportFunc func(severity string, gui *gocui.Gui),
+ updateResultsTableFunc func(reports []*output.Report, g *gocui.Gui), g baseContext) ResultsWidget {
widget := ResultsWidget{
ListWidget: ListWidget{
ctx: g,
@@ -45,17 +45,17 @@ func NewResultsWidget(name string, generateReportFunc func(severity string),
return widget
}
-func (w *ResultsWidget) addFilteringKeyBinding(key rune, severity string) error {
+func (w *ResultsWidget) addFilteringKeyBinding(key rune, severity string, gui *gocui.Gui) error {
if err := w.ctx.SetKeyBinding(w.name, key, gocui.ModNone, func(gui *gocui.Gui, view *gocui.View) error {
if w.currentReport == nil {
return nil
}
switch severity {
case "ALL":
- w.generateReportFunc(severity)
+ w.generateReportFunc(severity, gui)
default:
if w.currentReport.SeverityCount[severity] > 0 {
- w.generateReportFunc(severity)
+ w.generateReportFunc(severity, gui)
}
}
@@ -66,40 +66,30 @@ func (w *ResultsWidget) addFilteringKeyBinding(key rune, severity string) error
return nil
}
-func (w *ResultsWidget) addFilteringKeyBindings() error {
- logger.Debug("adding filtering keybindings")
- if err := w.addFilteringKeyBinding('e', "ALL"); err != nil {
+func (w *ResultsWidget) addFilteringKeyBindings(gui *gocui.Gui) error {
+ logger.Debugf("adding filtering keybindings")
+ if err := w.addFilteringKeyBinding('e', "ALL", gui); err != nil {
return err
}
- if err := w.addFilteringKeyBinding('c', "CRITICAL"); err != nil {
+ if err := w.addFilteringKeyBinding('c', "CRITICAL", nil); err != nil {
return err
}
- if err := w.addFilteringKeyBinding('h', "HIGH"); err != nil {
+ if err := w.addFilteringKeyBinding('h', "HIGH", nil); err != nil {
return err
}
- if err := w.addFilteringKeyBinding('m', "MEDIUM"); err != nil {
+ if err := w.addFilteringKeyBinding('m', "MEDIUM", nil); err != nil {
return err
}
- if err := w.addFilteringKeyBinding('l', "LOW"); err != nil {
+ if err := w.addFilteringKeyBinding('l', "LOW", nil); err != nil {
return err
}
- if err := w.addFilteringKeyBinding('u', "UNKNOWN"); err != nil {
+ if err := w.addFilteringKeyBinding('u', "UNKNOWN", nil); err != nil {
return err
}
return nil
}
-func (w *ResultsWidget) RenderReport(report *output.Report, severity string) {
- w.currentReport = report
-
- w.generateReportFunc(severity)
-}
-
-func (w *ResultsWidget) UpdateResultsTable(reports []*output.Report) {
- w.updateResultsTableFunc(reports)
-}
-
func (w *ResultsWidget) layout(g *gocui.Gui, x int, y int, wi int, h int) error {
v, err := g.View(w.name)
@@ -155,6 +145,6 @@ func (w *ResultsWidget) Layout(*gocui.Gui) error {
return nil
}
-func (w *ResultsWidget) ConfigureKeys() error {
+func (w *ResultsWidget) ConfigureKeys(*gocui.Gui) error {
return nil
}
diff --git a/pkg/widgets/services.go b/pkg/widgets/services.go
index 300608d..dae0904 100644
--- a/pkg/widgets/services.go
+++ b/pkg/widgets/services.go
@@ -38,7 +38,7 @@ func NewServicesWidget(name string, g awsContext) *ServicesWidget {
return widget
}
-func (w *ServicesWidget) ConfigureKeys() error {
+func (w *ServicesWidget) ConfigureKeys(*gocui.Gui) error {
if err := w.ctx.SetKeyBinding(w.name, gocui.KeyArrowUp, gocui.ModNone, w.previousItem); err != nil {
return fmt.Errorf("failed to set the previous image %w", err)
}
@@ -81,8 +81,6 @@ func (w *ServicesWidget) Layout(g *gocui.Gui) error {
}
func (w *ServicesWidget) RefreshServices(services []string, serviceWidth int) error {
- // w.w = serviceWidth + 4
-
serviceList := make([]string, len(services))
for i, service := range services {
serviceList[i] = fmt.Sprintf(" % -*s", serviceWidth+1, service)
diff --git a/pkg/widgets/status.go b/pkg/widgets/status.go
index 99d9158..6b39819 100644
--- a/pkg/widgets/status.go
+++ b/pkg/widgets/status.go
@@ -28,7 +28,7 @@ func NewStatusWidget(name string) *StatusWidget {
}
}
-func (w *StatusWidget) ConfigureKeys() error {
+func (w *StatusWidget) ConfigureKeys(*gocui.Gui) error {
return nil
}
diff --git a/pkg/widgets/widget.go b/pkg/widgets/widget.go
index c05f758..62dd87d 100644
--- a/pkg/widgets/widget.go
+++ b/pkg/widgets/widget.go
@@ -3,20 +3,21 @@ package widgets
import "github.com/awesome-gocui/gocui"
const (
- Filter = "filter"
- Host = "host"
- Images = "images"
- Menu = "menu"
- Remote = "remote"
- Results = "results"
- Status = "status"
- Summary = "summary"
- Services = "services"
- Account = "account"
+ Account = "account"
+ Announcement = "announcement"
+ Filter = "filter"
+ Host = "host"
+ Images = "images"
+ Menu = "menu"
+ Remote = "remote"
+ Results = "results"
+ Services = "services"
+ Status = "status"
+ Summary = "summary"
)
type Widget interface {
- ConfigureKeys() error
+ ConfigureKeys(*gocui.Gui) error
Layout(*gocui.Gui) error
RefreshView()
}