Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 4 additions & 85 deletions cmd/luna/app/app.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package app

import (
"context"
"errors"
"fmt"
"os"
"time"

"github.com/spf13/cobra"

Expand All @@ -30,87 +26,10 @@ imports/exports of vulnerability store, management of scanning tasks, etc.
},
}
cmd.AddCommand(versionCmd)
var dsn string
var exportFrom string
var exportFileName string
exportCmd := &cobra.Command{
Use: "export",
Long: "Export vulnerability update package, so other luna can import this package to skip manual updates",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
var from time.Time
if exportFrom != "" {
var err error
const layout = "2006-01-02"
from, err = time.Parse(layout, exportFrom)
if err != nil {
return fmt.Errorf("invalid --from flag, valid values like %s", layout)
}
}
if exportFileName == "" {
return errors.New("-o is required")
}
if err := Export(ctx, dsn, from, exportFileName); err != nil {
return err
}
return nil
},
}

exportCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "DSN to connect to postgres")
exportCmd.PersistentFlags().StringVarP(&exportFrom, "from", "", "", "Export since time, leaving empty will export everything. Example: 2021-01-12")
exportCmd.PersistentFlags().StringVarP(&exportFileName, "out", "o", "", "Output filename for the export, better end with .gz")
cmd.AddCommand(exportCmd)

var importFileName string
importCmd := &cobra.Command{
Use: "import",
Long: "Import offline update package from a file, and load it into new database. Migrations will be done automatically",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
if importFileName == "" {
return errors.New("-i is required")
}
if dsn == "" {
return errors.New("--dsn is required")
}
return Import(ctx, importFileName, dsn)
},
}
importCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "DSN for the database to be migrated")
importCmd.PersistentFlags().StringVarP(&importFileName, "in", "i", "", "Input update package")
cmd.AddCommand(importCmd)

inspectCmd := &cobra.Command{
Use: "inspect",
Long: "Inspect image",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Args:", args)
m, err := Inspect(context.Background(), args[0])
if err != nil {
return err
}
raw, _ := json.MarshalIndent(m, "", " ")
fmt.Println(string(raw))
return nil
},
}
cmd.AddCommand(inspectCmd)

scanCmd := &cobra.Command{
Use: "scan",
Long: "Scan image",
RunE: func(cmd *cobra.Command, args []string) error {
if dsn == "" {
return errors.New("missing dsn argument")
}
err := ScanLocal(context.Background(), args[0], dsn)
return err
},
}
scanCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "DSN for the database to be migrated")
cmd.AddCommand(scanCmd)

cmd.AddCommand(NewExportCommand())
cmd.AddCommand(NewImportCommand())
cmd.AddCommand(NewInspectCommand())
cmd.AddCommand(NewScanCommand())
cmd.AddCommand(NewUpdateCommand())
cmd.AddCommand(NewInfraScanCommand())

Expand Down
36 changes: 36 additions & 0 deletions cmd/luna/app/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/pkg/errors"
"github.com/quay/claircore"
"github.com/quay/claircore/libvuln/driver"
"github.com/spf13/cobra"

"github.com/beacon/luna/pkg/dao"
)
Expand Down Expand Up @@ -40,6 +41,41 @@ type DiskEntry struct {
Vuln *claircore.Vulnerability
}

// NewExportCommand export command
func NewExportCommand() *cobra.Command {
var dsn string
var exportFrom string
var exportFileName string
exportCmd := &cobra.Command{
Use: "export",
Long: "Export vulnerability update package, so other luna can import this package to skip manual updates",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
var from time.Time
if exportFrom != "" {
var err error
const layout = "2006-01-02"
from, err = time.Parse(layout, exportFrom)
if err != nil {
return fmt.Errorf("invalid --from flag, valid values like %s", layout)
}
}
if exportFileName == "" {
return errors.New("-o is required")
}
if err := Export(ctx, dsn, from, exportFileName); err != nil {
return err
}
return nil
},
}

exportCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "DSN to connect to postgres")
exportCmd.PersistentFlags().StringVarP(&exportFrom, "from", "", "", "Export since time, leaving empty will export everything. Example: 2021-01-12")
exportCmd.PersistentFlags().StringVarP(&exportFileName, "out", "o", "", "Output filename for the export, better end with .gz")
return exportCmd
}

// Export vulnerability updates
func Export(ctx context.Context, dsn string, from time.Time, fileName string) error {
start := time.Now()
Expand Down
24 changes: 24 additions & 0 deletions cmd/luna/app/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,32 @@ import (
"github.com/quay/claircore/libvuln"
"github.com/quay/zlog"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
)

func NewImportCommand() *cobra.Command {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [sonarqube] <external_golint:Exported> reported by reviewdog 🐶
exported function NewImportCommand should have comment or be unexported

// TODO: move it into a single package
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [sonarqube] <go:S1135> reported by reviewdog 🐶
Complete the task associated to this TODO comment.

var importFileName string
var dsn string
importCmd := &cobra.Command{
Use: "import",
Long: "Import offline update package from a file, and load it into new database. Migrations will be done automatically",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
if importFileName == "" {
return errors.New("-i is required")
}
if dsn == "" {
return errors.New("--dsn is required")
}
return Import(ctx, importFileName, dsn)
},
}
importCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "DSN for the database to be migrated")
importCmd.PersistentFlags().StringVarP(&importFileName, "in", "i", "", "Input update package")
return importCmd
}

// Import import an update package and load it into specified database
func Import(ctx context.Context, srcFile string, dsn string) error {
opts := &libvuln.Opts{
Expand Down
38 changes: 38 additions & 0 deletions cmd/luna/app/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,50 @@ import (
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/quay/claircore"
"github.com/quay/claircore/libindex"
"github.com/quay/claircore/libvuln"
)

// NewInspectCommand inspect
func NewInspectCommand() *cobra.Command {
inspectCmd := &cobra.Command{
Use: "inspect",
Long: "Inspect image",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Args:", args)
m, err := Inspect(context.Background(), args[0])
if err != nil {
return err
}
raw, _ := json.MarshalIndent(m, "", " ")
fmt.Println(string(raw))
return nil
},
}
return inspectCmd
}

// NewScanCommand scan
func NewScanCommand() *cobra.Command {
var dsn string
scanCmd := &cobra.Command{
Use: "scan",
Long: "Scan image",
RunE: func(cmd *cobra.Command, args []string) error {
if dsn == "" {
return errors.New("missing dsn argument")
}
err := ScanLocal(context.Background(), args[0], dsn)
return err
},
}
scanCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "DSN for the database to be migrated")
return scanCmd
}

// Scan an image
func Scan(ctx context.Context, imageRef string, remote bool) error {
return nil
Expand Down
80 changes: 43 additions & 37 deletions pkg/infrascanner/dpkg/dpkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,43 +102,8 @@ func (ps *Scanner) Scan(ctx context.Context) ([]*claircore.Package, error) {
pkgs = append(pkgs, p)
}

infoDir := filepath.Join(p, "info")
const suffix = ".md5sums"
infos, err := ioutil.ReadDir(infoDir)
if err != nil {
return nil, errors.Wrap(err, "failed to read dir:"+infoDir)
}
for _, info := range infos {
if !strings.HasSuffix(info.Name(), suffix) {
continue
}
n := filepath.Base(info.Name())
n = strings.TrimSuffix(n, suffix)
if i := strings.IndexRune(n, ':'); i != -1 {
n = n[:i]
}
p, ok := found[n]
if !ok {
zlog.Debug(ctx).
Str("package", n).
Msg("extra metadata found, ignoring")
continue
}
sumFileName := path.Join(infoDir, info.Name())
sumFile, err := os.Open(sumFileName)
if err != nil {
return nil, errors.Wrap(err, "failed to open sum file:"+sumFileName)
}
hash := md5.New()
if _, err := io.Copy(hash, sumFile); err != nil {
zlog.Warn(ctx).
Err(err).
Str("package", n).
Msg("unable to read package metadata")
continue
}
sumFile.Close()
p.RepositoryHint = hex.EncodeToString(hash.Sum(nil))
if err := addFileHash(ctx, found, filepath.Join(p, "info")); err != nil {
return nil, err
}
zlog.Debug(ctx).
Int("count", len(found)).
Expand All @@ -147,3 +112,44 @@ func (ps *Scanner) Scan(ctx context.Context) ([]*claircore.Package, error) {

return pkgs, nil
}

func addFileHash(ctx context.Context, metamap map[string]*claircore.Package, infoDir string) error {
infos, err := ioutil.ReadDir(infoDir)
if err != nil {
return errors.Wrap(err, "failed to read dir:"+infoDir)
}
const suffix = ".md5sums"
for _, info := range infos {
if !strings.HasSuffix(info.Name(), suffix) {
continue
}
n := filepath.Base(info.Name())
n = strings.TrimSuffix(n, suffix)
if i := strings.IndexRune(n, ':'); i != -1 {
n = n[:i]
}
p, ok := metamap[n]
if !ok {
zlog.Debug(ctx).
Str("package", n).
Msg("extra metadata found, ignoring")
continue
}
sumFileName := path.Join(infoDir, info.Name())
sumFile, err := os.Open(sumFileName)
if err != nil {
return errors.Wrap(err, "failed to open sum file:"+sumFileName)
}
hash := md5.New()
if _, err := io.Copy(hash, sumFile); err != nil {
zlog.Warn(ctx).
Err(err).
Str("package", n).
Msg("unable to read package metadata")
continue
}
sumFile.Close()
p.RepositoryHint = hex.EncodeToString(hash.Sum(nil))
}
return nil
}