diff --git a/Dockerfile b/Dockerfile index de426c8b..3f176367 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine as build +FROM golang:1.21-alpine AS build WORKDIR /go/src/github.com/uselagoon/lagoon-cli/ COPY . . diff --git a/cmd/config.go b/cmd/config.go index 6bd0c2c5..dde5bfa4 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -39,7 +39,7 @@ func parseLagoonConfig(flags pflag.FlagSet) LagoonConfigFlags { }) jsonStr, _ := json.Marshal(configMap) parsedFlags := LagoonConfigFlags{} - json.Unmarshal(jsonStr, &parsedFlags) + _ = json.Unmarshal(jsonStr, &parsedFlags) return parsedFlags } @@ -55,12 +55,10 @@ var configDefaultCmd = &cobra.Command{ Use: "default", Aliases: []string{"d"}, Short: "Set the default Lagoon to use", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { lagoonConfig := parseLagoonConfig(*cmd.Flags()) if lagoonConfig.Lagoon == "" { - fmt.Println("Not enough arguments") - cmd.Help() - os.Exit(1) + return fmt.Errorf("not enough arguments") } lagoonCLIConfig.Default = strings.TrimSpace(string(lagoonConfig.Lagoon)) contextExists := false @@ -70,8 +68,7 @@ var configDefaultCmd = &cobra.Command{ } } if !contextExists { - fmt.Println(fmt.Printf("Chosen context '%s' doesn't exist in config file", lagoonCLIConfig.Current)) - os.Exit(1) + return fmt.Errorf("chosen context '%s' doesn't exist in config file", lagoonCLIConfig.Current) } err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)) handleError(err) @@ -84,6 +81,7 @@ var configDefaultCmd = &cobra.Command{ } r := output.RenderResult(resultData, outputOptions) fmt.Fprintf(cmd.OutOrStdout(), "%s", r) + return nil }, } diff --git a/cmd/helpers_test.go b/cmd/helpers_test.go index 762d632a..54e18460 100644 --- a/cmd/helpers_test.go +++ b/cmd/helpers_test.go @@ -157,7 +157,11 @@ func Test_flagStringNullValueOrNil(t *testing.T) { for k, v := range tt.args.flags { flags.StringP(k, "", "", "") if v != nil { - flags.Set(k, v.(string)) + err := flags.Set(k, v.(string)) + if (err != nil) != tt.wantErr { + t.Errorf("flagStringNullValueOrNil() error setting flags = %v, wantErr %v", err, tt.wantErr) + return + } } } got, err := flagStringNullValueOrNil(flags, tt.args.flag) diff --git a/cmd/list.go b/cmd/list.go index f0416a0a..78fc76ee 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -1081,7 +1081,7 @@ var listOrganizationDeployTargetsCmd = &cobra.Command{ }, } -var ListOrganizationUsersCmd = &cobra.Command{ +var listOrganizationUsersCmd = &cobra.Command{ Use: "organization-users", Aliases: []string{"org-u"}, Short: "List users in an organization", @@ -1264,7 +1264,7 @@ func init() { listCmd.AddCommand(listAllUsersCmd) listCmd.AddCommand(listUsersGroupsCmd) listCmd.AddCommand(listOrganizationProjectsCmd) - listCmd.AddCommand(ListOrganizationUsersCmd) + listCmd.AddCommand(listOrganizationUsersCmd) listCmd.AddCommand(listOrganizationAdminsCmd) listCmd.AddCommand(listOrganizationGroupsCmd) listCmd.AddCommand(listOrganizationDeployTargetsCmd) @@ -1277,7 +1277,7 @@ func init() { listGroupProjectsCmd.Flags().BoolP("all-projects", "", false, "All projects") listVariablesCmd.Flags().BoolP("reveal", "", false, "Reveal the variable values") listOrganizationProjectsCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated projects for") - ListOrganizationUsersCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated users for") + listOrganizationUsersCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated users for") listOrganizationAdminsCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated users for") listOrganizationGroupsCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated groups for") listOrganizationDeployTargetsCmd.Flags().StringP("organization-name", "O", "", "Name of the organization to list associated deploy targets for") diff --git a/cmd/login.go b/cmd/login.go index 1d84c3c7..5aa16b44 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -157,7 +157,12 @@ func retrieveTokenViaSsh() (string, error) { HostKeyCallback: hkcb, HostKeyAlgorithms: hkalgo, } - defer closeSSHAgent() + defer func() { + err = closeSSHAgent() + if err != nil { + fmt.Fprintf(os.Stderr, "error closing ssh agent:%v\n", err) + } + }() conn, err := ssh.Dial("tcp", sshHost, config) if err != nil { diff --git a/cmd/logs.go b/cmd/logs.go index 24dbbcfc..e484275f 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -163,7 +163,12 @@ var logsCmd = &cobra.Command{ if err != nil { return fmt.Errorf("couldn't get SSH client config: %v", err) } - defer closeSSHAgent() + defer func() { + err = closeSSHAgent() + if err != nil { + fmt.Fprintf(os.Stderr, "error closing ssh agent:%v\n", err) + } + }() // start SSH log streaming session err = lagoonssh.LogStream(sshConfig, sshHost, sshPort, argv) if err != nil { diff --git a/cmd/root.go b/cmd/root.go index dfa60cf3..af4711b3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -155,7 +155,7 @@ func init() { rootCmd.Flags().BoolVarP(&versionFlag, "version", "", false, "Version information") rootCmd.Flags().BoolVarP(&docsFlag, "docs", "", false, "Generate docs") - rootCmd.Flags().MarkHidden("docs") + _ = rootCmd.Flags().MarkHidden("docs") rootCmd.SetUsageTemplate(`Usage:{{if .Runnable}} {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} diff --git a/cmd/users.go b/cmd/users.go index 7fc9b640..dd963bc0 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -27,25 +27,25 @@ func parseSSHKeyFile(sshPubKey string, keyName string, keyValue string, userEmai var err error // will fail if value is not right - if strings.EqualFold(string(splitKey[0]), "ssh-rsa") { + switch splitKey[0] { + case "ssh-rsa": keyType = schema.SSHRsa - } else if strings.EqualFold(string(splitKey[0]), "ssh-ed25519") { + case "ssh-ed25519": keyType = schema.SSHEd25519 - } else if strings.EqualFold(string(splitKey[0]), "ecdsa-sha2-nistp256") { + case "ecdsa-sha2-nistp256": keyType = schema.SSHECDSA256 - } else if strings.EqualFold(string(splitKey[0]), "ecdsa-sha2-nistp384") { + case "ecdsa-sha2-nistp384": keyType = schema.SSHECDSA384 - } else if strings.EqualFold(string(splitKey[0]), "ecdsa-sha2-nistp521") { + case "ecdsa-sha2-nistp521": keyType = schema.SSHECDSA521 - } else { - // return error stating key type not supported + default: keyType = schema.SSHRsa - err = fmt.Errorf(fmt.Sprintf("SSH key type %s not supported", splitKey[0])) + err = fmt.Errorf("SSH key type %s not supported", splitKey[0]) } // if the sshkey has a comment/name in it, we can use that if keyName == "" && len(splitKey) == 3 { - //strip new line + // strip new line keyName = stripNewLines(splitKey[2]) } else if keyName == "" && len(splitKey) == 2 { keyName = userEmail @@ -373,7 +373,7 @@ var updateUserCmd = &cobra.Command{ } var getUserKeysCmd = &cobra.Command{ - //@TODO: once individual user interaction comes in, this will need to be adjusted + // @TODO: once individual user interaction comes in, this will need to be adjusted Use: "user-sshkeys", Aliases: []string{"us"}, Short: "Get a user's SSH keys", @@ -434,7 +434,7 @@ var getUserKeysCmd = &cobra.Command{ } var getAllUserKeysCmd = &cobra.Command{ - //@TODO: once individual user interaction comes in, this will need to be adjusted + // @TODO: once individual user interaction comes in, this will need to be adjusted Use: "all-user-sshkeys", Aliases: []string{"aus"}, Short: "Get all user SSH keys", @@ -479,10 +479,10 @@ var getAllUserKeysCmd = &cobra.Command{ var data []output.Data for _, userData := range userGroups { keyID := strconv.Itoa(int(userData.SSHKey.ID)) - userEmail := returnNonEmptyString(strings.Replace(userData.UserEmail, " ", "_", -1)) - keyName := returnNonEmptyString(strings.Replace(userData.SSHKey.Name, " ", "_", -1)) - keyValue := returnNonEmptyString(strings.Replace(userData.SSHKey.KeyValue, " ", "_", -1)) - keyType := returnNonEmptyString(strings.Replace(string(userData.SSHKey.KeyType), " ", "_", -1)) + userEmail := returnNonEmptyString(strings.ReplaceAll(userData.UserEmail, " ", "_")) + keyName := returnNonEmptyString(strings.ReplaceAll(userData.SSHKey.Name, " ", "_")) + keyValue := returnNonEmptyString(strings.ReplaceAll(userData.SSHKey.KeyValue, " ", "_")) + keyType := returnNonEmptyString(strings.ReplaceAll(string(userData.SSHKey.KeyType), " ", "_")) data = append(data, []string{ keyID, userEmail, diff --git a/pkg/app/app.go b/pkg/app/app.go index 9f4b8505..5a21e15f 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -43,7 +43,7 @@ func (project *LagoonProject) ReadConfig() error { } sourceCompose, _ := os.ReadFile(dockerComposeFilepath) var dockerCompose LagoonDockerCompose - yaml.Unmarshal(sourceCompose, &dockerCompose) + _ = yaml.Unmarshal(sourceCompose, &dockerCompose) // Reset the name based on the docker-compose.yml file. project.Name = dockerCompose.LagoonProject @@ -83,8 +83,8 @@ func getProjectFromPath(path string) (LagoonProject, error) { } app.Name = filepath.Base(appDir) app.Dir = appDir - app.ReadConfig() - return app, nil + err = app.ReadConfig() + return app, err } func findLocalProjectRoot(path string) (string, error) { diff --git a/pkg/lagoon/ssh/main.go b/pkg/lagoon/ssh/main.go index 882a6a34..ee938019 100644 --- a/pkg/lagoon/ssh/main.go +++ b/pkg/lagoon/ssh/main.go @@ -66,7 +66,12 @@ func InteractiveSSH(lagoon map[string]string, sshService string, sshContainer st if err != nil { return err } - defer term.Restore(fileDescriptor, originalState) + defer func() { + err = term.Restore(fileDescriptor, originalState) + if err != nil { + fmt.Fprintf(os.Stderr, "error restoring ssh terminal:%v\n", err) + } + }() termWidth, termHeight, err := term.GetSize(fileDescriptor) if err != nil { return err @@ -85,23 +90,22 @@ func InteractiveSSH(lagoon map[string]string, sshService string, sshContainer st } err = session.Start(connString) if err != nil { - return fmt.Errorf("Failed to start shell: " + err.Error()) + return fmt.Errorf("failed to start shell: %s", err.Error()) } - session.Wait() - return nil + return session.Wait() } // RunSSHCommand . func RunSSHCommand(lagoon map[string]string, sshService string, sshContainer string, command string, config *ssh.ClientConfig) error { client, err := ssh.Dial("tcp", lagoon["hostname"]+":"+lagoon["port"], config) if err != nil { - return fmt.Errorf("Failed to dial: " + err.Error() + "\nCheck that the project or environment you are trying to connect to exists") + return fmt.Errorf("failed to dial: %s\nCheck that the project or environment you are trying to connect to exists", err.Error()) } // start the session session, err := client.NewSession() if err != nil { - return fmt.Errorf("Failed to create session: " + err.Error()) + return fmt.Errorf("failed to create session: %s", err.Error()) } defer session.Close() session.Stdout = os.Stdout @@ -118,7 +122,12 @@ func RunSSHCommand(lagoon map[string]string, sshService string, sshContainer str if err != nil { return err } - defer term.Restore(fileDescriptor, originalState) + defer func() { + err = term.Restore(fileDescriptor, originalState) + if err != nil { + fmt.Fprintf(os.Stderr, "error restoring ssh terminal:%v\n", err) + } + }() termWidth, termHeight, err := term.GetSize(fileDescriptor) if err != nil { return err @@ -188,7 +197,7 @@ func InteractiveKnownHosts(userPath, host string, ignorehost, accept bool) (ssh. f, ferr := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0600) if ferr == nil { defer f.Close() - response := "n" + var response string if accept { response = "y" } else { diff --git a/pkg/output/main.go b/pkg/output/main.go index 35388a33..29c28e8e 100644 --- a/pkg/output/main.go +++ b/pkg/output/main.go @@ -118,7 +118,7 @@ func RenderOutput(data Table, opts Options) string { for _, dataValues := range data.Data { jsonData := make(map[string]interface{}) for indexID, dataValue := range dataValues { - dataHeader := strings.Replace(strings.ToLower(data.Header[indexID]), " ", "-", -1) + dataHeader := strings.ReplaceAll(strings.ToLower(data.Header[indexID]), " ", "-") jsonData[dataHeader] = dataValue } rawData = append(rawData, jsonData) diff --git a/pkg/output/main_test.go b/pkg/output/main_test.go index 2c295957..50a743b9 100644 --- a/pkg/output/main_test.go +++ b/pkg/output/main_test.go @@ -61,7 +61,7 @@ func TestRenderError(t *testing.T) { RenderError(testData, outputOptions) w.Close() var out bytes.Buffer - io.Copy(&out, r) + _, _ = io.Copy(&out, r) if out.String() != testSuccess { checkEqual(t, out.String(), testSuccess, " render error stdout processing failed") } @@ -87,7 +87,7 @@ func TestRenderInfo(t *testing.T) { RenderInfo(testData, outputOptions) w.Close() var out bytes.Buffer - io.Copy(&out, r) + _, _ = io.Copy(&out, r) if out.String() != testSuccess1 { checkEqual(t, out.String(), testSuccess1, " render info stdout processing failed") } @@ -109,7 +109,7 @@ func TestRenderOutput(t *testing.T) { } var dataMain Table - json.Unmarshal([]byte(testData), &dataMain) + _ = json.Unmarshal([]byte(testData), &dataMain) output := RenderOutput(dataMain, outputOptions) if output != testSuccess1 { diff --git a/pkg/updatecheck/updatecheck.go b/pkg/updatecheck/updatecheck.go index c5e3fc8b..81593ae5 100644 --- a/pkg/updatecheck/updatecheck.go +++ b/pkg/updatecheck/updatecheck.go @@ -79,10 +79,5 @@ func ResetUpdateTime(filepath string) error { // isReleaseVersion does a (very naive) check on whether a version string consistutes a release version or a dev build. func isReleaseVersion(version string) bool { parts := strings.Split(version, "-") - - if len(parts) > 1 { - return false - } - - return true + return len(parts) <= 1 } diff --git a/pkg/updatecheck/updatecheck_test.go b/pkg/updatecheck/updatecheck_test.go index 654be53d..0cd703ce 100644 --- a/pkg/updatecheck/updatecheck_test.go +++ b/pkg/updatecheck/updatecheck_test.go @@ -43,7 +43,7 @@ func CreateTmpDir(prefix string) string { func CleanupDir(dir string) { err := os.RemoveAll(dir) if err != nil { - log.Println(fmt.Sprintf("Failed to remove directory %s, err: %v", dir, err)) + log.Printf("Failed to remove directory %s, err: %v", dir, err) } }