package cmd import ( "fmt" "strings" "syscall" "github.com/mirivlad/sshkeeper/internal/model" "github.com/spf13/cobra" "golang.org/x/term" ) var editCmd = &cobra.Command{ Use: "edit ", Short: "Edit a server profile", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { alias := args[0] server, err := appDB.GetServer(alias) if err != nil { return fmt.Errorf("server not found: %s", alias) } oldAuthMethod := server.AuthMethod if parsedHost != "" { server.Host = parsedHost } if parsedPort != 0 { server.Port = parsedPort } if parsedUser != "" { server.User = parsedUser } if parsedAuth != "" { server.AuthMethod = model.AuthMethod(parsedAuth) } if parsedIdentity != "" { server.IdentityFile = parsedIdentity } if parsedProxyJump != "" { server.ProxyJump = parsedProxyJump } if parsedGroup != "" { server.GroupName = parsedGroup } if parsedDisplayName != "" { server.DisplayName = parsedDisplayName } if parsedNotes != "" { server.Notes = parsedNotes } if parsedStartup != "" { server.StartupCommand = parsedStartup } tagsChanged := cmd.Flags().Changed("tags") if tagsChanged { server.Tags = strings.Split(parsedTags, ",") } if parsedAuth != "" && oldAuthMethod != server.AuthMethod { v := getOrCreateVault() if v.IsUnlocked() { var secret string if server.AuthMethod == model.AuthPassword { fmt.Print("Enter new password (stored in vault, input hidden): ") pw, err := term.ReadPassword(int(syscall.Stdin)) fmt.Println() if err != nil { return fmt.Errorf("read password: %w", err) } if len(pw) > 0 { secret = string(pw) } } else if server.AuthMethod == model.AuthKeyPassphrase { fmt.Print("Enter key passphrase (stored in vault, input hidden): ") pw, err := term.ReadPassword(int(syscall.Stdin)) fmt.Println() if err != nil { return fmt.Errorf("read passphrase: %w", err) } if len(pw) > 0 { secret = string(pw) } } if err := syncServerSecrets(v, alias, server, secret); err != nil { return fmt.Errorf("sync vault secrets: %w", err) } if err := v.Save(); err != nil { return fmt.Errorf("save vault: %w", err) } } } if err := appDB.UpdateServer(server); err != nil { return fmt.Errorf("update server: %w", err) } if tagsChanged { if err := appDB.SetServerTags(server.ID, server.Tags); err != nil { return fmt.Errorf("set tags: %w", err) } } fmt.Println("Saved.") return nil }, } var ( parsedHost string parsedPort int parsedUser string parsedAuth string parsedIdentity string parsedProxyJump string parsedGroup string parsedDisplayName string parsedNotes string parsedStartup string parsedTags string ) func init() { editCmd.Flags().StringVar(&parsedHost, "host", "", "Server hostname or IP") editCmd.Flags().IntVar(&parsedPort, "port", 0, "SSH port") editCmd.Flags().StringVar(&parsedUser, "user", "", "SSH username") editCmd.Flags().StringVar(&parsedAuth, "auth", "", "Auth method") editCmd.Flags().StringVar(&parsedIdentity, "identity-file", "", "Path to SSH private key") editCmd.Flags().StringVar(&parsedProxyJump, "proxy-jump", "", "ProxyJump host") editCmd.Flags().StringVar(&parsedGroup, "group", "", "Server group") editCmd.Flags().StringVar(&parsedDisplayName, "display-name", "", "Display name") editCmd.Flags().StringVar(&parsedNotes, "notes", "", "Notes") editCmd.Flags().StringVar(&parsedStartup, "startup-command", "", "Command to run after connecting") editCmd.Flags().StringVar(&parsedTags, "tags", "", "Comma-separated tags") }