From 87efc874754e789ae25078310b1bded3aba3d553 Mon Sep 17 00:00:00 2001 From: ALTHAF Date: Tue, 20 Aug 2024 11:28:42 +0530 Subject: [PATCH 1/7] created systemcve cmd Signed-off-by: ALTHAF --- cmd/harbor/root/cmd.go | 2 + cmd/harbor/root/systemcve/cmd.go | 20 ++++++++++ cmd/harbor/root/systemcve/list.go | 32 ++++++++++++++++ cmd/harbor/root/systemcve/update.go | 51 +++++++++++++++++++++++++ pkg/api/systemcve_handler.go | 59 +++++++++++++++++++++++++++++ pkg/views/systemcve/list/view.go | 50 ++++++++++++++++++++++++ pkg/views/systemcve/update/view.go | 55 +++++++++++++++++++++++++++ 7 files changed, 269 insertions(+) create mode 100644 cmd/harbor/root/systemcve/cmd.go create mode 100644 cmd/harbor/root/systemcve/list.go create mode 100644 cmd/harbor/root/systemcve/update.go create mode 100644 pkg/api/systemcve_handler.go create mode 100644 pkg/views/systemcve/list/view.go create mode 100644 pkg/views/systemcve/update/view.go diff --git a/cmd/harbor/root/cmd.go b/cmd/harbor/root/cmd.go index 7a3fbf3d..d3d2decb 100644 --- a/cmd/harbor/root/cmd.go +++ b/cmd/harbor/root/cmd.go @@ -9,6 +9,7 @@ import ( "github.com/goharbor/harbor-cli/cmd/harbor/root/project" "github.com/goharbor/harbor-cli/cmd/harbor/root/registry" repositry "github.com/goharbor/harbor-cli/cmd/harbor/root/repository" + "github.com/goharbor/harbor-cli/cmd/harbor/root/systemcve" "github.com/goharbor/harbor-cli/cmd/harbor/root/user" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/spf13/cobra" @@ -109,6 +110,7 @@ harbor help repositry.Repository(), user.User(), artifact.Artifact(), + systemcve.SystemCVEAllowlist(), ) return root diff --git a/cmd/harbor/root/systemcve/cmd.go b/cmd/harbor/root/systemcve/cmd.go new file mode 100644 index 00000000..d27e9537 --- /dev/null +++ b/cmd/harbor/root/systemcve/cmd.go @@ -0,0 +1,20 @@ +package systemcve + +import ( + "github.com/spf13/cobra" +) + +func SystemCVEAllowlist() *cobra.Command { + cmd := &cobra.Command{ + Use: "systemcve", + Short: "Manage system CVE allowlist", + Long: `Manage system level allowlist of CVE`, + Example: `harbor systemcve list`, + } + cmd.AddCommand( + ListCveCommand(), + UpdateSystemCveCommand(), + ) + + return cmd +} diff --git a/cmd/harbor/root/systemcve/list.go b/cmd/harbor/root/systemcve/list.go new file mode 100644 index 00000000..0068391d --- /dev/null +++ b/cmd/harbor/root/systemcve/list.go @@ -0,0 +1,32 @@ +package systemcve + +import ( + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/goharbor/harbor-cli/pkg/utils" + "github.com/goharbor/harbor-cli/pkg/views/systemcve/list" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func ListCveCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "list", + Short: "list system level allowlist of cve", + Run: func(cmd *cobra.Command, args []string) { + cve, err := api.ListSystemCve() + if err != nil { + log.Fatalf("failed to get system cve list: %v", err) + } + FormatFlag := viper.GetString("output-format") + if FormatFlag != "" { + utils.PrintPayloadInJSONFormat(cve) + return + } + + list.ListSystemCve(cve.Payload) + }, + } + + return cmd +} diff --git a/cmd/harbor/root/systemcve/update.go b/cmd/harbor/root/systemcve/update.go new file mode 100644 index 00000000..24c16bb0 --- /dev/null +++ b/cmd/harbor/root/systemcve/update.go @@ -0,0 +1,51 @@ +package systemcve + +import ( + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/goharbor/harbor-cli/pkg/views/systemcve/update" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +func UpdateSystemCveCommand() *cobra.Command { + var opts update.UpdateView + + cmd := &cobra.Command{ + Use: "update", + Short: "update systemcve allowlist", + Run: func(cmd *cobra.Command, args []string) { + var err error + updateView := &update.UpdateView{ + CveId: opts.CveId, + IsExpire: opts.IsExpire, + ExpireDate: opts.ExpireDate, + } + + if opts.CveId != "" { + api.UpdateSystemCve(*updateView) + } else { + err = updatecveView(updateView) + } + + if err != nil { + log.Errorf("failed to update systemcve: %v", err) + } + }, + } + + flags := cmd.Flags() + flags.BoolVarP(&opts.IsExpire, "isexpire", "i", false, "Systemcve allowlist expire or not") + flags.StringVarP(&opts.CveId, "cveid", "n", "", "CVE ids seperate with commas") + flags.StringVarP(&opts.ExpireDate, "expiredate", "d", "", "If it expire,give Expiry date in the format MM/DD/YYYY") + + return cmd +} + +func updatecveView(updateView *update.UpdateView) error { + if updateView == nil { + updateView = &update.UpdateView{} + } + + update.UpdateCveView(updateView) + return api.UpdateSystemCve(*updateView) +} diff --git a/pkg/api/systemcve_handler.go b/pkg/api/systemcve_handler.go new file mode 100644 index 00000000..0cc36dbf --- /dev/null +++ b/pkg/api/systemcve_handler.go @@ -0,0 +1,59 @@ +package api + +import ( + "strings" + "time" + + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/system_cve_allowlist" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" + "github.com/goharbor/harbor-cli/pkg/utils" + "github.com/goharbor/harbor-cli/pkg/views/systemcve/update" + log "github.com/sirupsen/logrus" +) + +func ListSystemCve() (system_cve_allowlist.GetSystemCVEAllowlistOK, error) { + ctx, client, err := utils.ContextWithClient() + if err != nil { + return system_cve_allowlist.GetSystemCVEAllowlistOK{}, err + } + + response, err := client.SystemCVEAllowlist.GetSystemCVEAllowlist(ctx, &system_cve_allowlist.GetSystemCVEAllowlistParams{}) + if err != nil { + return system_cve_allowlist.GetSystemCVEAllowlistOK{}, err + } + + return *response, nil +} + +func UpdateSystemCve(opts update.UpdateView) error { + ctx, client, err := utils.ContextWithClient() + if err != nil { + return err + } + var unixTimestamp int64 + if opts.IsExpire { + expiresAt, err := time.Parse("01/02/2006", opts.ExpireDate) + if err != nil { + return err + } + unixTimestamp = expiresAt.Unix() + } else { + unixTimestamp = 0 + } + + var items []*models.CVEAllowlistItem + cveIds := strings.Split(opts.CveId, ",") + for _, id := range cveIds { + id = strings.TrimSpace(id) + items = append(items, &models.CVEAllowlistItem{CVEID: id}) + } + response, err := client.SystemCVEAllowlist.PutSystemCVEAllowlist(ctx, &system_cve_allowlist.PutSystemCVEAllowlistParams{Allowlist: &models.CVEAllowlist{Items: items, ExpiresAt: &unixTimestamp}}) + if err != nil { + return err + } + + if response != nil { + log.Info("system cveallowlist updated successfully") + } + return nil +} diff --git a/pkg/views/systemcve/list/view.go b/pkg/views/systemcve/list/view.go new file mode 100644 index 00000000..09e12063 --- /dev/null +++ b/pkg/views/systemcve/list/view.go @@ -0,0 +1,50 @@ +package list + +import ( + "fmt" + "os" + "strconv" + "time" + + "github.com/charmbracelet/bubbles/table" + tea "github.com/charmbracelet/bubbletea" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" + "github.com/goharbor/harbor-cli/pkg/utils" + "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" +) + +var columns = []table.Column{ + {Title: "ID", Width: 6}, + {Title: "CVE Name", Width: 18}, + {Title: "Expires At", Width: 18}, + {Title: "Creation Time", Width: 24}, +} + +func ListSystemCve(systemcve *models.CVEAllowlist) { + var rows []table.Row + var expiresAtStr string + for _, cve := range systemcve.Items { + CveName := cve.CVEID + + if systemcve.ExpiresAt != nil && *systemcve.ExpiresAt != 0 { + expiresAt := time.Unix(int64(*systemcve.ExpiresAt), 0) + expiresAtStr = expiresAt.Format("01/02/2006") + } else { + expiresAtStr = "Never expires" + } + + createdTime, _ := utils.FormatCreatedTime(systemcve.CreationTime.String()) + rows = append(rows, table.Row{ + strconv.FormatInt(systemcve.ID, 10), + CveName, + expiresAtStr, + createdTime, + }) + } + m := tablelist.NewModel(columns, rows, len(rows)) + + if _, err := tea.NewProgram(m).Run(); err != nil { + fmt.Println("Error running program:", err) + os.Exit(1) + } +} diff --git a/pkg/views/systemcve/update/view.go b/pkg/views/systemcve/update/view.go new file mode 100644 index 00000000..94163278 --- /dev/null +++ b/pkg/views/systemcve/update/view.go @@ -0,0 +1,55 @@ +package update + +import ( + "errors" + + "github.com/charmbracelet/huh" + log "github.com/sirupsen/logrus" +) + +type UpdateView struct { + CveId string + IsExpire bool + ExpireDate string +} + +func UpdateCveView(updateView *UpdateView) { + theme := huh.ThemeCharm() + err := huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("CVE ID"). + Value(&updateView.CveId). + Description("CVE IDs are separator by commas"). + Validate(func(str string) error { + if str == "" { + return errors.New("cve id cannot be empty") + } + return nil + }), + huh.NewConfirm(). + Title("Expires"). + Value(&updateView.IsExpire). + Affirmative("yes"). + Negative("never"), + ), + huh.NewGroup( + huh.NewInput(). + Validate(func(str string) error { + if str == "" { + return errors.New("ExpireDate cannot be empty") + } + return nil + }). + Description("Expire Date in the format MM/DD/YYYY"). + Title("Expire Date"). + Value(&updateView.ExpireDate), + ).WithHideFunc(func() bool { + return !updateView.IsExpire + }), + ).WithTheme(theme).Run() + + if err != nil { + log.Fatal(err) + } +} From 5a742a20f2bc3a1e4a98aafc49763656b87d7c56 Mon Sep 17 00:00:00 2001 From: ALTHAF Date: Tue, 20 Aug 2024 12:05:26 +0530 Subject: [PATCH 2/7] modified systemcve cmd Signed-off-by: ALTHAF --- cmd/harbor/root/systemcve/update.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cmd/harbor/root/systemcve/update.go b/cmd/harbor/root/systemcve/update.go index 24c16bb0..788a5f8a 100644 --- a/cmd/harbor/root/systemcve/update.go +++ b/cmd/harbor/root/systemcve/update.go @@ -21,12 +21,7 @@ func UpdateSystemCveCommand() *cobra.Command { ExpireDate: opts.ExpireDate, } - if opts.CveId != "" { - api.UpdateSystemCve(*updateView) - } else { - err = updatecveView(updateView) - } - + err = updatecveView(updateView) if err != nil { log.Errorf("failed to update systemcve: %v", err) } From 9cfee867126c7e3be861b1dcc35c650d919d268c Mon Sep 17 00:00:00 2001 From: ALTHAF Date: Tue, 10 Sep 2024 20:56:27 +0530 Subject: [PATCH 3/7] modified to harbor cve-allowlist list/add Signed-off-by: ALTHAF --- cmd/harbor/root/cmd.go | 4 ++-- .../root/{systemcve/update.go => cveallowlist/add.go} | 10 +++++----- cmd/harbor/root/{systemcve => cveallowlist}/cmd.go | 10 +++++----- cmd/harbor/root/{systemcve => cveallowlist}/list.go | 2 +- pkg/api/systemcve_handler.go | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) rename cmd/harbor/root/{systemcve/update.go => cveallowlist/add.go} (85%) rename cmd/harbor/root/{systemcve => cveallowlist}/cmd.go (58%) rename cmd/harbor/root/{systemcve => cveallowlist}/list.go (97%) diff --git a/cmd/harbor/root/cmd.go b/cmd/harbor/root/cmd.go index d3d2decb..1c9a399a 100644 --- a/cmd/harbor/root/cmd.go +++ b/cmd/harbor/root/cmd.go @@ -9,7 +9,7 @@ import ( "github.com/goharbor/harbor-cli/cmd/harbor/root/project" "github.com/goharbor/harbor-cli/cmd/harbor/root/registry" repositry "github.com/goharbor/harbor-cli/cmd/harbor/root/repository" - "github.com/goharbor/harbor-cli/cmd/harbor/root/systemcve" + "github.com/goharbor/harbor-cli/cmd/harbor/root/cveallowlist" "github.com/goharbor/harbor-cli/cmd/harbor/root/user" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/spf13/cobra" @@ -110,7 +110,7 @@ harbor help repositry.Repository(), user.User(), artifact.Artifact(), - systemcve.SystemCVEAllowlist(), + cveallowlist.CVEAllowlist(), ) return root diff --git a/cmd/harbor/root/systemcve/update.go b/cmd/harbor/root/cveallowlist/add.go similarity index 85% rename from cmd/harbor/root/systemcve/update.go rename to cmd/harbor/root/cveallowlist/add.go index 788a5f8a..749f0ec0 100644 --- a/cmd/harbor/root/systemcve/update.go +++ b/cmd/harbor/root/cveallowlist/add.go @@ -1,4 +1,4 @@ -package systemcve +package cveallowlist import ( "github.com/goharbor/harbor-cli/pkg/api" @@ -7,12 +7,12 @@ import ( "github.com/spf13/cobra" ) -func UpdateSystemCveCommand() *cobra.Command { +func AddCveAllowlistCommand() *cobra.Command { var opts update.UpdateView cmd := &cobra.Command{ - Use: "update", - Short: "update systemcve allowlist", + Use: "add", + Short: "add cve allowlist", Run: func(cmd *cobra.Command, args []string) { var err error updateView := &update.UpdateView{ @@ -23,7 +23,7 @@ func UpdateSystemCveCommand() *cobra.Command { err = updatecveView(updateView) if err != nil { - log.Errorf("failed to update systemcve: %v", err) + log.Errorf("failed to add cveallowlist: %v", err) } }, } diff --git a/cmd/harbor/root/systemcve/cmd.go b/cmd/harbor/root/cveallowlist/cmd.go similarity index 58% rename from cmd/harbor/root/systemcve/cmd.go rename to cmd/harbor/root/cveallowlist/cmd.go index d27e9537..dd4a6b51 100644 --- a/cmd/harbor/root/systemcve/cmd.go +++ b/cmd/harbor/root/cveallowlist/cmd.go @@ -1,19 +1,19 @@ -package systemcve +package cveallowlist import ( "github.com/spf13/cobra" ) -func SystemCVEAllowlist() *cobra.Command { +func CVEAllowlist() *cobra.Command { cmd := &cobra.Command{ - Use: "systemcve", + Use: "cve-allowlist", Short: "Manage system CVE allowlist", Long: `Manage system level allowlist of CVE`, - Example: `harbor systemcve list`, + Example: `harbor cve-allowlist list`, } cmd.AddCommand( ListCveCommand(), - UpdateSystemCveCommand(), + AddCveAllowlistCommand(), ) return cmd diff --git a/cmd/harbor/root/systemcve/list.go b/cmd/harbor/root/cveallowlist/list.go similarity index 97% rename from cmd/harbor/root/systemcve/list.go rename to cmd/harbor/root/cveallowlist/list.go index 0068391d..6d7272cf 100644 --- a/cmd/harbor/root/systemcve/list.go +++ b/cmd/harbor/root/cveallowlist/list.go @@ -1,4 +1,4 @@ -package systemcve +package cveallowlist import ( "github.com/goharbor/harbor-cli/pkg/api" diff --git a/pkg/api/systemcve_handler.go b/pkg/api/systemcve_handler.go index 0cc36dbf..94d0f472 100644 --- a/pkg/api/systemcve_handler.go +++ b/pkg/api/systemcve_handler.go @@ -53,7 +53,7 @@ func UpdateSystemCve(opts update.UpdateView) error { } if response != nil { - log.Info("system cveallowlist updated successfully") + log.Info("cveallowlist added successfully") } return nil } From d9f1352938157171f7bb2093a998b9ab92e880b5 Mon Sep 17 00:00:00 2001 From: ALTHAF <114910365+Althaf66@users.noreply.github.com> Date: Sat, 2 Nov 2024 01:51:01 +0530 Subject: [PATCH 4/7] Update cmd.go Signed-off-by: ALTHAF <114910365+Althaf66@users.noreply.github.com> --- cmd/harbor/root/cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/harbor/root/cmd.go b/cmd/harbor/root/cmd.go index 58afb78b..02a67103 100644 --- a/cmd/harbor/root/cmd.go +++ b/cmd/harbor/root/cmd.go @@ -110,7 +110,7 @@ harbor help repositry.Repository(), user.User(), artifact.Artifact(), - HealthCommand(), + HealthCommand(), cveallowlist.CVEAllowlist(), ) From 7a97b8851728d86274ccf0fa67089be26b7f7e87 Mon Sep 17 00:00:00 2001 From: ALTHAF Date: Sat, 2 Nov 2024 02:02:12 +0530 Subject: [PATCH 5/7] fix lint issue Signed-off-by: ALTHAF --- cmd/harbor/root/cmd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/harbor/root/cmd.go b/cmd/harbor/root/cmd.go index 02a67103..fec32f9d 100644 --- a/cmd/harbor/root/cmd.go +++ b/cmd/harbor/root/cmd.go @@ -6,10 +6,10 @@ import ( "os" "github.com/goharbor/harbor-cli/cmd/harbor/root/artifact" + "github.com/goharbor/harbor-cli/cmd/harbor/root/cveallowlist" "github.com/goharbor/harbor-cli/cmd/harbor/root/project" "github.com/goharbor/harbor-cli/cmd/harbor/root/registry" repositry "github.com/goharbor/harbor-cli/cmd/harbor/root/repository" - "github.com/goharbor/harbor-cli/cmd/harbor/root/cveallowlist" "github.com/goharbor/harbor-cli/cmd/harbor/root/user" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/spf13/cobra" @@ -110,7 +110,7 @@ harbor help repositry.Repository(), user.User(), artifact.Artifact(), - HealthCommand(), + HealthCommand(), cveallowlist.CVEAllowlist(), ) From 5d8d094773ca11d01f3d9a9316c2fa567b9737f6 Mon Sep 17 00:00:00 2001 From: ALTHAF Date: Fri, 22 Nov 2024 23:49:36 +0530 Subject: [PATCH 6/7] changed date to iso format Signed-off-by: ALTHAF --- pkg/api/systemcve_handler.go | 2 +- pkg/views/systemcve/update/view.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/api/systemcve_handler.go b/pkg/api/systemcve_handler.go index 94d0f472..94a7c6a8 100644 --- a/pkg/api/systemcve_handler.go +++ b/pkg/api/systemcve_handler.go @@ -32,7 +32,7 @@ func UpdateSystemCve(opts update.UpdateView) error { } var unixTimestamp int64 if opts.IsExpire { - expiresAt, err := time.Parse("01/02/2006", opts.ExpireDate) + expiresAt, err := time.Parse("2006/01/02", opts.ExpireDate) if err != nil { return err } diff --git a/pkg/views/systemcve/update/view.go b/pkg/views/systemcve/update/view.go index 94163278..adcb682d 100644 --- a/pkg/views/systemcve/update/view.go +++ b/pkg/views/systemcve/update/view.go @@ -30,7 +30,7 @@ func UpdateCveView(updateView *UpdateView) { huh.NewConfirm(). Title("Expires"). Value(&updateView.IsExpire). - Affirmative("yes"). + Affirmative("Date"). Negative("never"), ), huh.NewGroup( @@ -41,7 +41,7 @@ func UpdateCveView(updateView *UpdateView) { } return nil }). - Description("Expire Date in the format MM/DD/YYYY"). + Description("Expire Date in the format YYYY/MM/DD"). Title("Expire Date"). Value(&updateView.ExpireDate), ).WithHideFunc(func() bool { From 26b6fe10312d5fb0904f3e20b5ef9c666695f65e Mon Sep 17 00:00:00 2001 From: ALTHAF Date: Tue, 17 Dec 2024 19:13:00 +0530 Subject: [PATCH 7/7] modified cveallowlist cmd Signed-off-by: ALTHAF --- cmd/harbor/root/cveallowlist/add.go | 9 +++++---- cmd/harbor/root/cveallowlist/cmd.go | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/harbor/root/cveallowlist/add.go b/cmd/harbor/root/cveallowlist/add.go index 749f0ec0..f0ee38b9 100644 --- a/cmd/harbor/root/cveallowlist/add.go +++ b/cmd/harbor/root/cveallowlist/add.go @@ -12,7 +12,8 @@ func AddCveAllowlistCommand() *cobra.Command { cmd := &cobra.Command{ Use: "add", - Short: "add cve allowlist", + Short: "Add cve allowlist", + Long: "Create allowlists of CVEs to ignore during vulnerability scanning", Run: func(cmd *cobra.Command, args []string) { var err error updateView := &update.UpdateView{ @@ -29,9 +30,9 @@ func AddCveAllowlistCommand() *cobra.Command { } flags := cmd.Flags() - flags.BoolVarP(&opts.IsExpire, "isexpire", "i", false, "Systemcve allowlist expire or not") - flags.StringVarP(&opts.CveId, "cveid", "n", "", "CVE ids seperate with commas") - flags.StringVarP(&opts.ExpireDate, "expiredate", "d", "", "If it expire,give Expiry date in the format MM/DD/YYYY") + flags.BoolVarP(&opts.IsExpire, "isexpire", "i", false, "Indicates whether the CVE entries should have an expiration date. Set to true to specify an expiration date") + flags.StringVarP(&opts.CveId, "cveid", "n", "", "Comma-separated list of CVE IDs to be added to the allowlist") + flags.StringVarP(&opts.ExpireDate, "expiredate", "d", "", "Specifies the expiration date for the CVE entries in the format 'YYYY-MM-DD'") return cmd } diff --git a/cmd/harbor/root/cveallowlist/cmd.go b/cmd/harbor/root/cveallowlist/cmd.go index dd4a6b51..0799e6d2 100644 --- a/cmd/harbor/root/cveallowlist/cmd.go +++ b/cmd/harbor/root/cveallowlist/cmd.go @@ -8,7 +8,7 @@ func CVEAllowlist() *cobra.Command { cmd := &cobra.Command{ Use: "cve-allowlist", Short: "Manage system CVE allowlist", - Long: `Manage system level allowlist of CVE`, + Long: `Managing CVE lists that are intentionally excluded from vulnerability scanning`, Example: `harbor cve-allowlist list`, } cmd.AddCommand(