diff --git a/cmd/harbor/root/artifact/delete.go b/cmd/harbor/root/artifact/delete.go index 215233528..c0550e78c 100644 --- a/cmd/harbor/root/artifact/delete.go +++ b/cmd/harbor/root/artifact/delete.go @@ -39,7 +39,7 @@ func DeleteArtifactCommand() *cobra.Command { } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) reference = prompt.GetReferenceFromUser(repoName, projectName) diff --git a/cmd/harbor/root/artifact/scan.go b/cmd/harbor/root/artifact/scan.go index bb3e75e76..946494627 100644 --- a/cmd/harbor/root/artifact/scan.go +++ b/cmd/harbor/root/artifact/scan.go @@ -79,20 +79,19 @@ func StopScanArtifactCommand() *cobra.Command { Short: "Stop a scan of an artifact", Long: `Stop a scan of an artifact in Harbor Repository`, Example: `harbor artifact scan stop //`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName, repoName, reference string if len(args) > 0 { projectName, repoName, reference, err = utils.ParseProjectRepoReference(args[0]) if err != nil { - log.Errorf("failed to parse project/repo/reference: %v", err) + return fmt.Errorf("failed to parse project/repo/reference: %w", err) } } else { - var projectName string projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) reference = prompt.GetReferenceFromUser(repoName, projectName) @@ -100,8 +99,9 @@ func StopScanArtifactCommand() *cobra.Command { err = api.StopScanArtifact(projectName, repoName, reference) if err != nil { - log.Errorf("failed to stop scan of artifact: %v", err) + return fmt.Errorf("failed to stop scan of artifact: %w", err) } + return nil }, } return cmd diff --git a/cmd/harbor/root/artifact/tags.go b/cmd/harbor/root/artifact/tags.go index 4f9a60f50..4b8636481 100644 --- a/cmd/harbor/root/artifact/tags.go +++ b/cmd/harbor/root/artifact/tags.go @@ -14,13 +14,14 @@ package artifact import ( + "fmt" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/artifact" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/artifact/tags/create" "github.com/goharbor/harbor-cli/pkg/views/artifact/tags/list" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -46,20 +47,23 @@ func CreateTagsCmd() *cobra.Command { Use: "create", Short: "Create a tag of an artifact", Example: `harbor artifact tags create // `, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName, repoName, reference string var tagName string if len(args) > 0 { projectName, repoName, reference, err = utils.ParseProjectRepoReference(args[0]) if err != nil { - log.Errorf("failed to parse project/repo/reference: %v", err) + return fmt.Errorf("failed to parse project/repo/reference: %w", err) + } + if len(args) < 2 { + return fmt.Errorf("missing tag argument") } tagName = args[1] } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) reference = prompt.GetReferenceFromUser(repoName, projectName) @@ -67,8 +71,9 @@ func CreateTagsCmd() *cobra.Command { } err = api.CreateTag(projectName, repoName, reference, tagName) if err != nil { - log.Errorf("failed to create tag: %v", err) + return fmt.Errorf("failed to create tag: %w", err) } + return nil }, } @@ -80,7 +85,7 @@ func ListTagsCmd() *cobra.Command { Use: "list", Short: "List tags of an artifact", Example: `harbor artifact tags list //`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var tags *artifact.ListTagsOK var projectName, repoName, reference string @@ -88,16 +93,16 @@ func ListTagsCmd() *cobra.Command { if len(args) > 0 { projectName, repoName, reference, err = utils.ParseProjectRepoReference(args[0]) if err != nil { - log.Errorf("failed to parse project/repo/reference: %v", err) + return fmt.Errorf("failed to parse project/repo/reference: %w", err) } } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) if repoName == "" { - return + return fmt.Errorf("repository name is required") } reference = prompt.GetReferenceFromUser(repoName, projectName) } @@ -105,20 +110,19 @@ func ListTagsCmd() *cobra.Command { tags, err = api.ListTags(projectName, repoName, reference) if err != nil { - log.Errorf("failed to list tags: %v", err) - return + return fmt.Errorf("failed to list tags: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(tags, FormatFlag) if err != nil { - log.Error(err) - return + return fmt.Errorf("failed to print format: %w", err) } } else { list.ListTags(tags.Payload) } + return nil }, } @@ -130,20 +134,23 @@ func DeleteTagsCmd() *cobra.Command { Use: "delete", Short: "Delete a tag of an artifact", Example: `harbor artifact tags delete // `, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName, repoName, reference string var tagName string if len(args) > 0 { projectName, repoName, reference, err = utils.ParseProjectRepoReference(args[0]) if err != nil { - log.Errorf("failed to parse project/repo/reference: %v", err) + return fmt.Errorf("failed to parse project/repo/reference: %w", err) + } + if len(args) < 2 { + return fmt.Errorf("missing tag argument") } tagName = args[1] } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) reference = prompt.GetReferenceFromUser(repoName, projectName) @@ -151,8 +158,9 @@ func DeleteTagsCmd() *cobra.Command { } err = api.DeleteTag(projectName, repoName, reference, tagName) if err != nil { - log.Errorf("failed to delete tag: %v", err) + return fmt.Errorf("failed to delete tag: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/artifact/view.go b/cmd/harbor/root/artifact/view.go index 0b5a4065d..3c15dc652 100644 --- a/cmd/harbor/root/artifact/view.go +++ b/cmd/harbor/root/artifact/view.go @@ -14,12 +14,13 @@ package artifact import ( + "fmt" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/artifact" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/artifact/view" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -30,7 +31,7 @@ func ViewArtifactCommmand() *cobra.Command { Short: "Get information of an artifact", Long: `Get information of an artifact`, Example: `harbor artifact view /: OR harbor artifact view /@`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName, repoName, reference string var artifact *artifact.GetArtifactOK @@ -38,13 +39,12 @@ func ViewArtifactCommmand() *cobra.Command { if len(args) > 0 { projectName, repoName, reference, err = utils.ParseProjectRepoReference(args[0]) if err != nil { - log.Errorf("failed to parse project/repo/reference: %v", err) + return fmt.Errorf("failed to parse project/repo/reference: %w", err) } } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) - return + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) reference = prompt.GetReferenceFromUser(repoName, projectName) @@ -52,29 +52,28 @@ func ViewArtifactCommmand() *cobra.Command { if reference == "" { if len(args) > 0 { - log.Errorf("Invalid artifact reference format: %s", args[0]) + return fmt.Errorf("invalid artifact reference format: %s", args[0]) } else { - log.Error("Invalid artifact reference format: no arguments provided") + return fmt.Errorf("invalid artifact reference format: no arguments provided") } } artifact, err = api.ViewArtifact(projectName, repoName, reference, false) if err != nil { - log.Errorf("failed to get info of an artifact: %v", err) - return + return fmt.Errorf("failed to get info of an artifact: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(artifact, FormatFlag) if err != nil { - log.Error(err) - return + return fmt.Errorf("failed to print format: %w", err) } } else { view.ViewArtifact(artifact.Payload) } + return nil }, } diff --git a/cmd/harbor/root/cve/add.go b/cmd/harbor/root/cve/add.go index 1073529be..70f98f08c 100644 --- a/cmd/harbor/root/cve/add.go +++ b/cmd/harbor/root/cve/add.go @@ -14,9 +14,10 @@ package cve import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/views/cveallowlist/update" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -27,7 +28,7 @@ func AddCveAllowlistCommand() *cobra.Command { Use: "add", Short: "Add cve allowlist", Long: "Create allowlist of CVEs to ignore during vulnerability scanning", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error updateView := &update.UpdateView{ CveId: opts.CveId, @@ -37,8 +38,9 @@ func AddCveAllowlistCommand() *cobra.Command { err = updatecveView(updateView) if err != nil { - log.Errorf("failed to add cveallowlist: %v", err) + return fmt.Errorf("failed to add cveallowlist: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/instance/create.go b/cmd/harbor/root/instance/create.go index 532f6667d..4f75455d9 100644 --- a/cmd/harbor/root/instance/create.go +++ b/cmd/harbor/root/instance/create.go @@ -14,9 +14,10 @@ package instance import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/views/instance/create" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -31,7 +32,7 @@ The instance can be an external service such as Dragonfly, Kraken, or any custom You will need to provide the instance's name, vendor, endpoint, and optionally other details such as authentication and security options.`, Example: ` harbor-cli instance create --name my-instance --provider Dragonfly --url http://dragonfly.local --description "My preheat provider instance" --enable=true`, Args: cobra.NoArgs, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error createView := &create.CreateView{ Name: opts.Name, @@ -51,8 +52,9 @@ You will need to provide the instance's name, vendor, endpoint, and optionally o } if err != nil { - log.Errorf("failed to create instance: %v", err) + return fmt.Errorf("failed to create instance: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/instance/delete.go b/cmd/harbor/root/instance/delete.go index efa1c5791..52fae784b 100644 --- a/cmd/harbor/root/instance/delete.go +++ b/cmd/harbor/root/instance/delete.go @@ -14,9 +14,10 @@ package instance import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -30,15 +31,14 @@ If no argument is provided, you will be prompted to select an instance from a li Example: ` harbor-cli instance delete my-instance harbor-cli instance delete 12345`, Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var instanceName string if instanceID != -1 { instanceName, err = api.GetInstanceNameByID(instanceID) if err != nil { - log.Errorf("%v", err) - return + return fmt.Errorf("failed to get instance name by id: %w", err) } } else if len(args) > 0 { instanceName = args[0] @@ -47,8 +47,9 @@ If no argument is provided, you will be prompted to select an instance from a li } err = api.DeleteInstance(instanceName) if err != nil { - log.Errorf("failed to delete instance: %v", err) + return fmt.Errorf("failed to delete instance: %w", err) } + return nil }, } cmd.Flags().Int64VarP(&instanceID, "id", "i", -1, "ID of the instance to delete") diff --git a/cmd/harbor/root/instance/list.go b/cmd/harbor/root/instance/list.go index cdaefdd27..099dfc56c 100644 --- a/cmd/harbor/root/instance/list.go +++ b/cmd/harbor/root/instance/list.go @@ -14,10 +14,11 @@ package instance import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/instance/list" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -33,21 +34,22 @@ filter them using a query string, and sort them in ascending or descending order This command provides an easy way to view all instances along with their details.`, Example: ` harbor-cli instance list --page 1 --page-size 10 harbor-cli instance list --query "name=my-instance" --sort "asc"`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { instance, err := api.ListInstance(opts) if err != nil { - log.Fatalf("failed to get instance list: %v", err) + return fmt.Errorf("failed to get instance list: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(instance, FormatFlag) if err != nil { - log.Errorf("Failed to print config: %v", err) + return fmt.Errorf("failed to print config: %w", err) } } else { list.ListInstance(instance.Payload) } + return nil }, } diff --git a/cmd/harbor/root/labels/create.go b/cmd/harbor/root/labels/create.go index dea855c28..92826a4b1 100644 --- a/cmd/harbor/root/labels/create.go +++ b/cmd/harbor/root/labels/create.go @@ -33,7 +33,7 @@ func CreateLabelCommand() *cobra.Command { Long: "create label in harbor", Example: "harbor label create", Args: cobra.ExactArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error createView := &create.CreateView{ Name: opts.Name, @@ -50,8 +50,9 @@ func CreateLabelCommand() *cobra.Command { } if err != nil { - log.Errorf("failed to create label: %v", err) + return fmt.Errorf("failed to create label: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/logs.go b/cmd/harbor/root/logs.go index 03c4760f9..0f0bb44e6 100644 --- a/cmd/harbor/root/logs.go +++ b/cmd/harbor/root/logs.go @@ -47,7 +47,7 @@ harbor-cli logs --page 1 --page-size 10 --query "operation=push" --sort "op_time harbor-cli logs --follow --refresh-interval 2s harbor-cli logs --output-format json`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if refreshInterval != "" && !follow { fmt.Println("The --refresh-interval flag is only applicable when using --follow. It will be ignored.") } @@ -58,14 +58,15 @@ harbor-cli logs --output-format json`, if refreshInterval != "" { interval, err = time.ParseDuration(refreshInterval) if err != nil { - log.Fatalf("invalid refresh interval: %v", err) + return fmt.Errorf("invalid refresh interval: %w", err) } } followLogs(opts, interval) + return nil } else { logs, err := api.AuditLogs(opts) if err != nil { - log.Fatalf("failed to retrieve audit logs: %v", err) + return fmt.Errorf("failed to retrieve audit logs: %w", err) } formatFlag := viper.GetString("output-format") @@ -73,11 +74,12 @@ harbor-cli logs --output-format json`, log.WithField("output_format", formatFlag).Debug("Output format selected") err = utils.PrintFormat(logs.Payload, formatFlag) if err != nil { - return + return fmt.Errorf("failed to print format: %w", err) } } else { list.ListLogs(logs.Payload) } + return nil } }, } diff --git a/cmd/harbor/root/project/robot/list.go b/cmd/harbor/root/project/robot/list.go index 69aba2c17..089506ddc 100644 --- a/cmd/harbor/root/project/robot/list.go +++ b/cmd/harbor/root/project/robot/list.go @@ -14,6 +14,7 @@ package robot import ( + "fmt" "strconv" "github.com/goharbor/harbor-cli/pkg/api" @@ -72,7 +73,7 @@ Examples: if len(args) > 0 { project, err := api.GetProject(args[0], false) if err != nil { - log.Errorf("Invalid Project Name: %v", err) + return fmt.Errorf("invalid project name: %w", err) } opts.ProjectID = int64(project.Payload.ProjectID) opts.Q = projectQString + strconv.FormatInt(opts.ProjectID, 10) @@ -83,14 +84,14 @@ Examples: } else { projectID, err := prompt.GetProjectIDFromUser() if err != nil { - log.Fatalf("failed to get project by id %d: %v", projectID, utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project by id %d: %w", projectID, err) } opts.Q = projectQString + strconv.FormatInt(projectID, 10) } robots, err := api.ListRobot(opts) if err != nil { - log.Errorf("failed to get robots list: %v", err) + return fmt.Errorf("failed to get robots list: %w", err) } formatFlag := viper.GetString("output-format") diff --git a/cmd/harbor/root/quota/list.go b/cmd/harbor/root/quota/list.go index 8e8fa1d1a..958105259 100644 --- a/cmd/harbor/root/quota/list.go +++ b/cmd/harbor/root/quota/list.go @@ -14,10 +14,11 @@ package quota import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/quota/list" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -30,28 +31,26 @@ func ListQuotaCommand() *cobra.Command { Use: "list", Short: "list quotas", Long: "list quotas specified for each project", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if opts.PageSize > 100 { - log.Errorf("page size should be less than or equal to 100") - return + return fmt.Errorf("page size should be less than or equal to 100") } quota, err := api.ListQuota(opts) if err != nil { - log.Errorf("failed to get quota list: %v", err) - return + return fmt.Errorf("failed to get quota list: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(quota, FormatFlag) if err != nil { - log.Errorf("failed to get quota list: %v", err) - return + return fmt.Errorf("failed to get quota list: %w", err) } } else { list.ListQuotas(quota.Payload) } + return nil }, } diff --git a/cmd/harbor/root/quota/update.go b/cmd/harbor/root/quota/update.go index 389aa97e8..da5a3b890 100644 --- a/cmd/harbor/root/quota/update.go +++ b/cmd/harbor/root/quota/update.go @@ -45,15 +45,14 @@ func UpdateQuotaCommand() *cobra.Command { Use: "update [QuotaID]", Short: "update quotas for projects", Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var storageValue int64 // get quota id with quota quota, err := GetQuotaFromUser(args, opts) if err != nil { - log.Errorf("error: %v", err) - return + return fmt.Errorf("failed to get quota: %w", err) } if storage != "" { @@ -62,16 +61,14 @@ func UpdateQuotaCommand() *cobra.Command { } else { storageValue, err = utils.StorageStringToBytes(storage) if err != nil { - log.Errorf("failed to parse storage: %v", err) - os.Exit(1) + return fmt.Errorf("failed to parse storage: %w", err) } } } else { storage = update.UpdateQuotaView(quota) storageValue, err = utils.StorageStringToBytes(storage) if err != nil { - log.Errorf("failed to parse storage: %v", err) - os.Exit(1) + return fmt.Errorf("failed to parse storage: %w", err) } } @@ -81,11 +78,11 @@ func UpdateQuotaCommand() *cobra.Command { err = api.UpdateQuota(quota.ID, hardlimit) if err != nil { - log.Errorf("failed to update quota: %v", err) - os.Exit(1) + return fmt.Errorf("failed to update quota: %w", err) } log.Infof("quota updated successfully!") + return nil }, } diff --git a/cmd/harbor/root/quota/view.go b/cmd/harbor/root/quota/view.go index 46e82ed39..226583dfb 100644 --- a/cmd/harbor/root/quota/view.go +++ b/cmd/harbor/root/quota/view.go @@ -14,11 +14,12 @@ package quota import ( + "fmt" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/quota/list" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -30,27 +31,26 @@ func ViewQuotaCommand() *cobra.Command { Use: "view [quotaID]", Short: "get quota by quota ID", Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var quota *models.Quota // get quota id with quota quota, err = GetQuotaFromUser(args, opts) if err != nil { - log.Errorf("error: %v", err) - return + return fmt.Errorf("failed to get quota: %w", err) } quotas := []*models.Quota{quota} FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(quota, FormatFlag) if err != nil { - log.Errorf("failed to get quota list: %v", err) - return + return fmt.Errorf("failed to get quota list: %w", err) } } else { list.ListQuotas(quotas) } + return nil }, } flags := cmd.Flags() diff --git a/cmd/harbor/root/registry/create.go b/cmd/harbor/root/registry/create.go index df1c19528..eefb58d1e 100644 --- a/cmd/harbor/root/registry/create.go +++ b/cmd/harbor/root/registry/create.go @@ -14,9 +14,10 @@ package registry import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/views/registry/create" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -28,7 +29,7 @@ func CreateRegistryCommand() *cobra.Command { Short: "create registry", Example: "harbor registry create", Args: cobra.ExactArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error createView := &api.CreateRegView{ Name: opts.Name, @@ -50,8 +51,9 @@ func CreateRegistryCommand() *cobra.Command { } if err != nil { - log.Errorf("failed to create registry: %v", err) + return fmt.Errorf("failed to create registry: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/registry/delete.go b/cmd/harbor/root/registry/delete.go index 8a0f7ab6a..4bca5f18e 100644 --- a/cmd/harbor/root/registry/delete.go +++ b/cmd/harbor/root/registry/delete.go @@ -14,11 +14,11 @@ package registry import ( + "fmt" "sync" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -28,12 +28,15 @@ func DeleteRegistryCommand() *cobra.Command { Short: "delete registry by name or id", Example: "harbor registry delete [registryname]", Args: cobra.MinimumNArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var wg sync.WaitGroup errChan := make(chan error, len(args)) if len(args) > 0 { for _, arg := range args { - registryID, _ := api.GetRegistryIdByName(arg) + registryID, err := api.GetRegistryIdByName(arg) + if err != nil { + return fmt.Errorf("failed to get registry id for '%s': %w", arg, err) + } wg.Add(1) go func(registryID int64) { defer wg.Done() @@ -46,8 +49,9 @@ func DeleteRegistryCommand() *cobra.Command { registryId := prompt.GetRegistryNameFromUser() err := api.DeleteRegistry(registryId) if err != nil { - log.Errorf("failed to delete registry: %v", err) + return fmt.Errorf("failed to delete registry: %w", err) } + return nil } // Wait for all goroutines to finish @@ -62,13 +66,15 @@ func DeleteRegistryCommand() *cobra.Command { if finalErr == nil { finalErr = err } else { - log.Errorf("Error: %v", err) + // Multiple errors occurred, but return the first one + // Additional errors are logged by the caller if needed } } if finalErr != nil { - log.Errorf("failed to delete registry: %v", finalErr) + return fmt.Errorf("failed to delete registry: %w", finalErr) } + return nil }, } diff --git a/cmd/harbor/root/registry/update.go b/cmd/harbor/root/registry/update.go index 85a7f3f72..d71465856 100644 --- a/cmd/harbor/root/registry/update.go +++ b/cmd/harbor/root/registry/update.go @@ -14,11 +14,12 @@ package registry import ( + "fmt" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/views/registry/update" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -31,15 +32,14 @@ func UpdateRegistryCommand() *cobra.Command { Use: "update [registry_name]", Short: "update registry", Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var registryId int64 if len(args) > 0 { registryId, err = api.GetRegistryIdByName(args[0]) if err != nil { - log.Errorf("failed to get registry id: %v", err) - return + return fmt.Errorf("failed to get registry id: %w", err) } } else { registryId = prompt.GetRegistryNameFromUser() @@ -47,12 +47,10 @@ func UpdateRegistryCommand() *cobra.Command { existingRegistry, err := api.GetRegistryResponse(registryId) if err != nil { - log.Errorf("failed to get registry with ID %d: %v", registryId, err) - return + return fmt.Errorf("failed to get registry with ID %d: %w", registryId, err) } if existingRegistry == nil { - log.Errorf("registry is not found") - return + return fmt.Errorf("registry is not found") } updateView := &models.Registry{ @@ -97,9 +95,9 @@ func UpdateRegistryCommand() *cobra.Command { update.UpdateRegistryView(updateView) err = api.UpdateRegistry(updateView, registryId) if err != nil { - log.Errorf("failed to update registry: %v", err) - return + return fmt.Errorf("failed to update registry: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/registry/view.go b/cmd/harbor/root/registry/view.go index 1c8b8e784..2973a5dca 100644 --- a/cmd/harbor/root/registry/view.go +++ b/cmd/harbor/root/registry/view.go @@ -14,12 +14,13 @@ package registry import ( + "fmt" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/registry" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/registry/view" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -30,7 +31,7 @@ func ViewRegistryCommand() *cobra.Command { Short: "get registry information", Example: "harbor registry view [registryName]", Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var registryId int64 var registry *registry.GetRegistryOK @@ -38,8 +39,7 @@ func ViewRegistryCommand() *cobra.Command { if len(args) > 0 { registryId, err = api.GetRegistryIdByName(args[0]) if err != nil { - log.Errorf("failed to get registry name by id: %v", err) - return + return fmt.Errorf("failed to get registry name by id: %w", err) } } else { registryId = prompt.GetRegistryNameFromUser() @@ -47,19 +47,19 @@ func ViewRegistryCommand() *cobra.Command { registry, err = api.ViewRegistry(registryId) if err != nil { - log.Errorf("failed to get registry info: %v", err) - return + return fmt.Errorf("failed to get registry info: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(registry, FormatFlag) if err != nil { - log.Error(err) + return fmt.Errorf("failed to print format: %w", err) } } else { view.ViewRegistry(registry.Payload) } + return nil }, } diff --git a/cmd/harbor/root/repository/delete.go b/cmd/harbor/root/repository/delete.go index 336b21968..18503b85b 100644 --- a/cmd/harbor/root/repository/delete.go +++ b/cmd/harbor/root/repository/delete.go @@ -14,10 +14,11 @@ package repository import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -27,27 +28,27 @@ func RepoDeleteCmd() *cobra.Command { Short: "Delete a repository", Example: ` harbor repository delete [project_name]/[repository_name]`, Long: `Delete a repository within a project in Harbor`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName string var repoName string if len(args) > 0 { projectName, repoName, err = utils.ParseProjectRepo(args[0]) if err != nil { - log.Errorf("failed to parse project/repo: %v", err) - return + return fmt.Errorf("failed to parse project/repo: %w", err) } } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) } err = api.RepoDelete(projectName, repoName, false) if err != nil { - log.Errorf("failed to delete repository: %v", err) + return fmt.Errorf("failed to delete repository: %w", err) } + return nil }, } return cmd diff --git a/cmd/harbor/root/repository/view.go b/cmd/harbor/root/repository/view.go index 92bf5ed2b..a4e385844 100644 --- a/cmd/harbor/root/repository/view.go +++ b/cmd/harbor/root/repository/view.go @@ -14,12 +14,13 @@ package repository import ( + "fmt" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/repository" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/repository/view" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -30,7 +31,7 @@ func RepoViewCmd() *cobra.Command { Short: "Get repository information", Example: ` harbor repo view /`, Long: `Get information of a particular repository in a project`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName, repoName string var repo *repository.GetRepositoryOK @@ -38,33 +39,31 @@ func RepoViewCmd() *cobra.Command { if len(args) > 0 { projectName, repoName, err = utils.ParseProjectRepo(args[0]) if err != nil { - log.Errorf("failed to parse project/repo: %v", err) - return + return fmt.Errorf("failed to parse project/repo: %w", err) } } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } repoName = prompt.GetRepoNameFromUser(projectName) } repo, err = api.RepoView(projectName, repoName) if err != nil { - log.Errorf("failed to get repository information: %v", err) - return + return fmt.Errorf("failed to get repository information: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { err = utils.PrintFormat(repo, FormatFlag) if err != nil { - log.Error(err) - return + return fmt.Errorf("failed to print format: %w", err) } } else { view.ViewRepository(repo.Payload) } + return nil }, } diff --git a/cmd/harbor/root/robot/list.go b/cmd/harbor/root/robot/list.go index 80b4427d9..0280b9b07 100644 --- a/cmd/harbor/root/robot/list.go +++ b/cmd/harbor/root/robot/list.go @@ -14,10 +14,11 @@ package robot import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/robot/list" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -61,21 +62,22 @@ Examples: # Get robot details in JSON format harbor-cli robot list --output-format json`, Args: cobra.MaximumNArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { robots, err := api.ListRobot(opts) if err != nil { - log.Errorf("failed to get robots list: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get robots list: %w", err) } formatFlag := viper.GetString("output-format") if formatFlag != "" { err = utils.PrintFormat(robots, formatFlag) if err != nil { - log.Errorf("Invalid Print Format: %v", err) + return fmt.Errorf("invalid print format: %w", err) } } else { list.ListRobots(robots.Payload) } + return nil }, } diff --git a/cmd/harbor/root/tag/immutable/create.go b/cmd/harbor/root/tag/immutable/create.go index 4fd3eecc1..07a5cce71 100644 --- a/cmd/harbor/root/tag/immutable/create.go +++ b/cmd/harbor/root/tag/immutable/create.go @@ -14,11 +14,12 @@ package immutable import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/immutable/create" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -31,7 +32,7 @@ func CreateImmutableCommand() *cobra.Command { Long: "create immutable tag rule to the project in harbor", Args: cobra.MaximumNArgs(1), Example: "harbor tag immutable create", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName string createView := &create.CreateView{ @@ -49,14 +50,15 @@ func CreateImmutableCommand() *cobra.Command { } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } } err = createImmutableView(createView, projectName) if err != nil { - log.Errorf("failed to create immutable tag rule: %v", err) + return fmt.Errorf("failed to create immutable tag rule: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/tag/immutable/delete.go b/cmd/harbor/root/tag/immutable/delete.go index e2d4943ff..9d3eeaef3 100644 --- a/cmd/harbor/root/tag/immutable/delete.go +++ b/cmd/harbor/root/tag/immutable/delete.go @@ -14,10 +14,11 @@ package immutable import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -26,7 +27,7 @@ func DeleteImmutableCommand() *cobra.Command { Use: "delete", Short: "delete immutable rule", Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var projectName string var immutableId int64 @@ -36,14 +37,15 @@ func DeleteImmutableCommand() *cobra.Command { } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) + return fmt.Errorf("failed to get project name: %w", err) } immutableId = prompt.GetImmutableTagRule(projectName) } err = api.DeleteImmutable(projectName, immutableId) if err != nil { - log.Errorf("failed to delete immutable tag rules: %v", err) + return fmt.Errorf("failed to delete immutable tag rules: %w", err) } + return nil }, } return cmd diff --git a/cmd/harbor/root/tag/immutable/list.go b/cmd/harbor/root/tag/immutable/list.go index 46cf335fe..371304618 100644 --- a/cmd/harbor/root/tag/immutable/list.go +++ b/cmd/harbor/root/tag/immutable/list.go @@ -41,7 +41,7 @@ You can specify the project name as an argument or, if omitted, you will be prom harbor tag immutable list `, Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var resp immutable.ListImmuRulesOK var projectName string @@ -51,26 +51,26 @@ You can specify the project name as an argument or, if omitted, you will be prom } else { projectName, err = prompt.GetProjectNameFromUser() if err != nil { - log.Errorf("failed to get project name: %v", utils.ParseHarborErrorMsg(err)) - return + return fmt.Errorf("failed to get project name: %w", err) } } resp, err = api.ListImmutable(projectName) if err != nil { - log.Errorf("failed to list immutablility rule: %v", err) + return fmt.Errorf("failed to list immutablility rule: %w", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { utils.PrintPayloadInJSONFormat(resp) - return + return nil } if len(resp.Payload) == 0 { fmt.Println("No immutable tag rules found.") - return + return nil } list.ListImmuRules(resp.Payload) + return nil }, } return cmd diff --git a/cmd/harbor/root/user/create.go b/cmd/harbor/root/user/create.go index bd705e3d9..e676dd9c1 100644 --- a/cmd/harbor/root/user/create.go +++ b/cmd/harbor/root/user/create.go @@ -14,11 +14,10 @@ package user import ( + "fmt" "strings" "github.com/goharbor/harbor-cli/pkg/api" - log "github.com/sirupsen/logrus" - "github.com/goharbor/harbor-cli/pkg/views/user/create" "github.com/spf13/cobra" ) @@ -30,7 +29,7 @@ func UserCreateCmd() *cobra.Command { Use: "create", Short: "create user", Args: cobra.ExactArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error createView := &create.CreateView{ Email: opts.Email, @@ -50,11 +49,11 @@ func UserCreateCmd() *cobra.Command { if err != nil { if isUnauthorizedError(err) { - log.Error("Permission denied: Admin privileges are required to execute this command.") - } else { - log.Errorf("failed to create user: %v", err) + return fmt.Errorf("permission denied: admin privileges are required to execute this command") } + return fmt.Errorf("failed to create user: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/user/delete.go b/cmd/harbor/root/user/delete.go index eaa2b1f4c..4142a5c92 100644 --- a/cmd/harbor/root/user/delete.go +++ b/cmd/harbor/root/user/delete.go @@ -14,11 +14,11 @@ package user import ( + "fmt" "sync" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -28,7 +28,7 @@ func UserDeleteCmd() *cobra.Command { Use: "delete", Short: "delete user by name or id", Args: cobra.MinimumNArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { // If there are command line arguments, process them concurrently. if len(args) > 0 { var wg sync.WaitGroup @@ -38,8 +38,7 @@ func UserDeleteCmd() *cobra.Command { // Retrieve user ID by name. userID, err := api.GetUsersIdByName(arg) if err != nil { - log.Errorf("failed to get user id for '%s': %v", arg, err) - continue + return fmt.Errorf("failed to get user id for '%s': %w", arg, err) } wg.Add(1) go func(userID int64) { @@ -57,23 +56,30 @@ func UserDeleteCmd() *cobra.Command { }() // Process errors from the goroutines. + var finalErr error for err := range errChan { - if isUnauthorizedError(err) { - log.Error("Permission denied: Admin privileges are required to execute this command.") - } else { - log.Errorf("failed to delete user: %v", err) + if finalErr == nil { + finalErr = err + } + } + + if finalErr != nil { + if isUnauthorizedError(finalErr) { + return fmt.Errorf("permission denied: admin privileges are required to execute this command") } + return fmt.Errorf("failed to delete user: %w", finalErr) } + return nil } else { // Interactive mode: get the user ID from the prompt. userID := prompt.GetUserIdFromUser() if err := api.DeleteUser(userID); err != nil { if isUnauthorizedError(err) { - log.Error("Permission denied: Admin privileges are required to execute this command.") - } else { - log.Errorf("failed to delete user: %v", err) + return fmt.Errorf("permission denied: admin privileges are required to execute this command") } + return fmt.Errorf("failed to delete user: %w", err) } + return nil } }, } diff --git a/cmd/harbor/root/user/elevate.go b/cmd/harbor/root/user/elevate.go index 060f83805..eef4e2cd0 100644 --- a/cmd/harbor/root/user/elevate.go +++ b/cmd/harbor/root/user/elevate.go @@ -14,10 +14,11 @@ package user import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/views" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -27,40 +28,36 @@ func ElevateUserCmd() *cobra.Command { Short: "elevate user", Long: "elevate user to admin role", Args: cobra.MaximumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var err error var userId int64 if len(args) > 0 { userId, err = api.GetUsersIdByName(args[0]) if err != nil { - log.Errorf("failed to get user id for '%s': %v", args[0], err) - return + return fmt.Errorf("failed to get user id for '%s': %w", args[0], err) } if userId == 0 { - log.Errorf("User with name '%s' not found", args[0]) - return + return fmt.Errorf("user with name '%s' not found", args[0]) } } else { userId = prompt.GetUserIdFromUser() } confirm, err := views.ConfirmElevation() if err != nil { - log.Errorf("failed to confirm elevation: %v", err) - return + return fmt.Errorf("failed to confirm elevation: %w", err) } if !confirm { - log.Error("User did not confirm elevation. Aborting command.") - return + return fmt.Errorf("user did not confirm elevation. aborting command") } err = api.ElevateUser(userId) if err != nil { if isUnauthorizedError(err) { - log.Error("Permission denied: Admin privileges are required to execute this command.") - } else { - log.Errorf("failed to elevate user: %v", err) + return fmt.Errorf("permission denied: admin privileges are required to execute this command") } + return fmt.Errorf("failed to elevate user: %w", err) } + return nil }, } diff --git a/cmd/harbor/root/user/password.go b/cmd/harbor/root/user/password.go index 34a6ce98a..2c9b9f63a 100644 --- a/cmd/harbor/root/user/password.go +++ b/cmd/harbor/root/user/password.go @@ -15,10 +15,11 @@ package user import ( + "fmt" + "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/views/password/reset" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -30,7 +31,7 @@ func UserPasswordChangeCmd() *cobra.Command { Short: "Reset user password by name or id", Long: "Allows admin to reset the password for a specified user or select interactively if no username is provided.", Args: cobra.MinimumNArgs(0), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var userId int64 var err error resetView := &reset.PasswordChangeView{ @@ -41,12 +42,10 @@ func UserPasswordChangeCmd() *cobra.Command { if len(args) > 0 { userId, err = api.GetUsersIdByName(args[0]) if err != nil { - log.Errorf("failed to get user id for '%s': %v", args[0], err) - return + return fmt.Errorf("failed to get user id for '%s': %w", args[0], err) } if userId == 0 { - log.Errorf("User with name '%s' not found", args[0]) - return + return fmt.Errorf("user with name '%s' not found", args[0]) } } else { userId = prompt.GetUserIdFromUser() @@ -57,11 +56,11 @@ func UserPasswordChangeCmd() *cobra.Command { err = api.ResetPassword(userId, opts) if err != nil { if isUnauthorizedError(err) { - log.Error("Permission denied: Admin privileges are required to execute this command.") - } else { - log.Errorf("failed to reset user password: %v", err) + return fmt.Errorf("permission denied: admin privileges are required to execute this command") } + return fmt.Errorf("failed to reset user password: %w", err) } + return nil }, } return cmd