mirror of
https://github.com/Gu1llaum-3/sshm.git
synced 2025-10-21 18:37:23 +02:00
Merge 8f502e54fefbc05550c1fb9ee78ca76ffd4a7b14 into 825c534ebe1b5683a57522329e26ad37a182bead
This commit is contained in:
commit
9e901e486f
@ -44,7 +44,7 @@ SSHM is a beautiful command-line tool that transforms how you manage and connect
|
|||||||
- **🔄 Automatic Conversion** - Seamlessly converts between command-line and config formats
|
- **🔄 Automatic Conversion** - Seamlessly converts between command-line and config formats
|
||||||
- **🔄 Automatic Backups** - Backup configurations automatically before changes
|
- **🔄 Automatic Backups** - Backup configurations automatically before changes
|
||||||
- **✅ Validation** - Prevent configuration errors with built-in validation
|
- **✅ Validation** - Prevent configuration errors with built-in validation
|
||||||
- **🔗 ProxyJump Support** - Secure connection tunneling through bastion hosts
|
- **🔗 ProxyJump/ProxyCommand Support** - Secure connection tunneling through bastion hosts
|
||||||
- **⌨️ Keyboard Shortcuts** - Power user navigation with vim-like shortcuts
|
- **⌨️ Keyboard Shortcuts** - Power user navigation with vim-like shortcuts
|
||||||
- **🌐 Cross-platform** - Supports Linux, macOS (Intel & Apple Silicon), and Windows
|
- **🌐 Cross-platform** - Supports Linux, macOS (Intel & Apple Silicon), and Windows
|
||||||
- **⚡ Lightweight** - Single binary with no dependencies, zero configuration required
|
- **⚡ Lightweight** - Single binary with no dependencies, zero configuration required
|
||||||
@ -129,6 +129,7 @@ The interactive forms will guide you through configuration:
|
|||||||
- **Port** - SSH port (default: 22)
|
- **Port** - SSH port (default: 22)
|
||||||
- **Identity File** - Private key path
|
- **Identity File** - Private key path
|
||||||
- **ProxyJump** - Jump server for connection tunneling
|
- **ProxyJump** - Jump server for connection tunneling
|
||||||
|
- **ProxyCommand** - Jump command for connection tunneling
|
||||||
- **SSH Options** - Additional SSH options in `-o` format (e.g., `-o Compression=yes -o ServerAliveInterval=60`)
|
- **SSH Options** - Additional SSH options in `-o` format (e.g., `-o Compression=yes -o ServerAliveInterval=60`)
|
||||||
- **Tags** - Comma-separated tags for organization
|
- **Tags** - Comma-separated tags for organization
|
||||||
|
|
||||||
@ -504,6 +505,7 @@ Host backend-prod
|
|||||||
User app
|
User app
|
||||||
Port 22
|
Port 22
|
||||||
ProxyJump bastion.company.com
|
ProxyJump bastion.company.com
|
||||||
|
ProxyCommand ssh -W %h:%p Jumphost
|
||||||
IdentityFile ~/.ssh/production_key
|
IdentityFile ~/.ssh/production_key
|
||||||
Compression yes
|
Compression yes
|
||||||
ServerAliveInterval 300
|
ServerAliveInterval 300
|
||||||
@ -520,6 +522,7 @@ SSHM supports all standard SSH configuration options:
|
|||||||
- `Port` - SSH port number
|
- `Port` - SSH port number
|
||||||
- `IdentityFile` - Path to private key file
|
- `IdentityFile` - Path to private key file
|
||||||
- `ProxyJump` - Jump server for connection tunneling (e.g., `user@jumphost:port`)
|
- `ProxyJump` - Jump server for connection tunneling (e.g., `user@jumphost:port`)
|
||||||
|
- `ProxyCommand` - Jump command for connection tunneling (e.g, `ssh -W %h:%p Jumphost`)
|
||||||
- `Tags` - Custom tags (SSHM extension)
|
- `Tags` - Custom tags (SSHM extension)
|
||||||
|
|
||||||
**Additional SSH Options:**
|
**Additional SSH Options:**
|
||||||
|
@ -205,6 +205,7 @@ func outputJSON(hosts []config.SSHHost) {
|
|||||||
fmt.Printf(" \"port\": \"%s\",\n", escapeJSON(host.Port))
|
fmt.Printf(" \"port\": \"%s\",\n", escapeJSON(host.Port))
|
||||||
fmt.Printf(" \"identity\": \"%s\",\n", escapeJSON(host.Identity))
|
fmt.Printf(" \"identity\": \"%s\",\n", escapeJSON(host.Identity))
|
||||||
fmt.Printf(" \"proxy_jump\": \"%s\",\n", escapeJSON(host.ProxyJump))
|
fmt.Printf(" \"proxy_jump\": \"%s\",\n", escapeJSON(host.ProxyJump))
|
||||||
|
fmt.Printf(" \"proxy_command\": \"%s\",\n", escapeJSON(host.ProxyCommand))
|
||||||
fmt.Printf(" \"options\": \"%s\",\n", escapeJSON(host.Options))
|
fmt.Printf(" \"options\": \"%s\",\n", escapeJSON(host.Options))
|
||||||
fmt.Printf(" \"tags\": [")
|
fmt.Printf(" \"tags\": [")
|
||||||
for j, tag := range host.Tags {
|
for j, tag := range host.Tags {
|
||||||
|
@ -19,6 +19,7 @@ type SSHHost struct {
|
|||||||
Port string
|
Port string
|
||||||
Identity string
|
Identity string
|
||||||
ProxyJump string
|
ProxyJump string
|
||||||
|
ProxyCommand string
|
||||||
Options string
|
Options string
|
||||||
RemoteCommand string // Command to execute after SSH connection
|
RemoteCommand string // Command to execute after SSH connection
|
||||||
RequestTTY string // Request TTY (yes, no, force, auto)
|
RequestTTY string // Request TTY (yes, no, force, auto)
|
||||||
@ -328,6 +329,10 @@ func parseSSHConfigFileWithProcessedFiles(configPath string, processedFiles map[
|
|||||||
if currentHost != nil {
|
if currentHost != nil {
|
||||||
currentHost.ProxyJump = value
|
currentHost.ProxyJump = value
|
||||||
}
|
}
|
||||||
|
case "proxycommand":
|
||||||
|
if currentHost != nil {
|
||||||
|
currentHost.ProxyCommand = value
|
||||||
|
}
|
||||||
case "remotecommand":
|
case "remotecommand":
|
||||||
if currentHost != nil {
|
if currentHost != nil {
|
||||||
currentHost.RemoteCommand = value
|
currentHost.RemoteCommand = value
|
||||||
@ -613,6 +618,13 @@ func AddSSHHostToFile(host SSHHost, configPath string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if host.ProxyCommand != "" {
|
||||||
|
_, err = file.WriteString(fmt.Sprintf(" ProxyCommand=%s\n", host.ProxyCommand))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if host.RemoteCommand != "" {
|
if host.RemoteCommand != "" {
|
||||||
_, err = file.WriteString(fmt.Sprintf(" RemoteCommand %s\n", host.RemoteCommand))
|
_, err = file.WriteString(fmt.Sprintf(" RemoteCommand %s\n", host.RemoteCommand))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1044,6 +1056,9 @@ func UpdateSSHHostInFile(oldName string, newHost SSHHost, configPath string) err
|
|||||||
if newHost.ProxyJump != "" {
|
if newHost.ProxyJump != "" {
|
||||||
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
||||||
}
|
}
|
||||||
|
if newHost.ProxyCommand != "" {
|
||||||
|
newLines = append(newLines, " ProxyCommand="+newHost.ProxyCommand)
|
||||||
|
}
|
||||||
if newHost.RemoteCommand != "" {
|
if newHost.RemoteCommand != "" {
|
||||||
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
||||||
}
|
}
|
||||||
@ -1098,6 +1113,9 @@ func UpdateSSHHostInFile(oldName string, newHost SSHHost, configPath string) err
|
|||||||
if newHost.ProxyJump != "" {
|
if newHost.ProxyJump != "" {
|
||||||
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
||||||
}
|
}
|
||||||
|
if newHost.ProxyCommand != "" {
|
||||||
|
newLines = append(newLines, " ProxyCommand="+newHost.ProxyCommand)
|
||||||
|
}
|
||||||
if newHost.RemoteCommand != "" {
|
if newHost.RemoteCommand != "" {
|
||||||
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
||||||
}
|
}
|
||||||
@ -1188,6 +1206,9 @@ func UpdateSSHHostInFile(oldName string, newHost SSHHost, configPath string) err
|
|||||||
if newHost.ProxyJump != "" {
|
if newHost.ProxyJump != "" {
|
||||||
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
||||||
}
|
}
|
||||||
|
if newHost.ProxyCommand != "" {
|
||||||
|
newLines = append(newLines, " ProxyCommand="+newHost.ProxyCommand)
|
||||||
|
}
|
||||||
if newHost.RemoteCommand != "" {
|
if newHost.RemoteCommand != "" {
|
||||||
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
||||||
}
|
}
|
||||||
@ -1242,6 +1263,9 @@ func UpdateSSHHostInFile(oldName string, newHost SSHHost, configPath string) err
|
|||||||
if newHost.ProxyJump != "" {
|
if newHost.ProxyJump != "" {
|
||||||
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
newLines = append(newLines, " ProxyJump "+newHost.ProxyJump)
|
||||||
}
|
}
|
||||||
|
if newHost.ProxyCommand != "" {
|
||||||
|
newLines = append(newLines, " ProxyCommand="+newHost.ProxyCommand)
|
||||||
|
}
|
||||||
if newHost.RemoteCommand != "" {
|
if newHost.RemoteCommand != "" {
|
||||||
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
newLines = append(newLines, " RemoteCommand "+newHost.RemoteCommand)
|
||||||
}
|
}
|
||||||
@ -1742,6 +1766,9 @@ func UpdateMultiHostBlock(originalHosts, newHosts []string, commonProperties SSH
|
|||||||
if commonProperties.ProxyJump != "" {
|
if commonProperties.ProxyJump != "" {
|
||||||
newLines = append(newLines, " ProxyJump "+commonProperties.ProxyJump)
|
newLines = append(newLines, " ProxyJump "+commonProperties.ProxyJump)
|
||||||
}
|
}
|
||||||
|
if commonProperties.ProxyCommand != "" {
|
||||||
|
newLines = append(newLines, " ProxyCommand="+commonProperties.ProxyCommand)
|
||||||
|
}
|
||||||
if commonProperties.RemoteCommand != "" {
|
if commonProperties.RemoteCommand != "" {
|
||||||
newLines = append(newLines, " RemoteCommand "+commonProperties.RemoteCommand)
|
newLines = append(newLines, " RemoteCommand "+commonProperties.RemoteCommand)
|
||||||
}
|
}
|
||||||
@ -1828,6 +1855,9 @@ func UpdateMultiHostBlock(originalHosts, newHosts []string, commonProperties SSH
|
|||||||
if commonProperties.ProxyJump != "" {
|
if commonProperties.ProxyJump != "" {
|
||||||
newLines = append(newLines, " ProxyJump "+commonProperties.ProxyJump)
|
newLines = append(newLines, " ProxyJump "+commonProperties.ProxyJump)
|
||||||
}
|
}
|
||||||
|
if commonProperties.ProxyCommand != "" {
|
||||||
|
newLines = append(newLines, " ProxyCommand="+commonProperties.ProxyCommand)
|
||||||
|
}
|
||||||
if commonProperties.RemoteCommand != "" {
|
if commonProperties.RemoteCommand != "" {
|
||||||
newLines = append(newLines, " RemoteCommand "+commonProperties.RemoteCommand)
|
newLines = append(newLines, " RemoteCommand "+commonProperties.RemoteCommand)
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func NewAddForm(hostname string, styles Styles, width, height int, configFile st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputs := make([]textinput.Model, 10) // Increased from 9 to 10 for RequestTTY
|
inputs := make([]textinput.Model, 11)
|
||||||
|
|
||||||
// Name input
|
// Name input
|
||||||
inputs[nameInput] = textinput.New()
|
inputs[nameInput] = textinput.New()
|
||||||
@ -91,6 +91,12 @@ func NewAddForm(hostname string, styles Styles, width, height int, configFile st
|
|||||||
inputs[proxyJumpInput].CharLimit = 200
|
inputs[proxyJumpInput].CharLimit = 200
|
||||||
inputs[proxyJumpInput].Width = 50
|
inputs[proxyJumpInput].Width = 50
|
||||||
|
|
||||||
|
// ProxyCommand input
|
||||||
|
inputs[proxyCommandInput] = textinput.New()
|
||||||
|
inputs[proxyCommandInput].Placeholder = "ssh -W %h:%p Jumphost"
|
||||||
|
inputs[proxyCommandInput].CharLimit = 200
|
||||||
|
inputs[proxyCommandInput].Width = 50
|
||||||
|
|
||||||
// SSH Options input
|
// SSH Options input
|
||||||
inputs[optionsInput] = textinput.New()
|
inputs[optionsInput] = textinput.New()
|
||||||
inputs[optionsInput].Placeholder = "-o Compression=yes -o ServerAliveInterval=60"
|
inputs[optionsInput].Placeholder = "-o Compression=yes -o ServerAliveInterval=60"
|
||||||
@ -138,6 +144,7 @@ const (
|
|||||||
portInput
|
portInput
|
||||||
identityInput
|
identityInput
|
||||||
proxyJumpInput
|
proxyJumpInput
|
||||||
|
proxyCommandInput
|
||||||
tagsInput
|
tagsInput
|
||||||
// Advanced tab inputs
|
// Advanced tab inputs
|
||||||
optionsInput
|
optionsInput
|
||||||
@ -229,11 +236,11 @@ func (m *addFormModel) getFirstInputForTab(tab int) int {
|
|||||||
func (m *addFormModel) getInputsForCurrentTab() []int {
|
func (m *addFormModel) getInputsForCurrentTab() []int {
|
||||||
switch m.currentTab {
|
switch m.currentTab {
|
||||||
case tabGeneral:
|
case tabGeneral:
|
||||||
return []int{nameInput, hostnameInput, userInput, portInput, identityInput, proxyJumpInput, tagsInput}
|
return []int{nameInput, hostnameInput, userInput, portInput, identityInput, proxyJumpInput, proxyCommandInput, tagsInput}
|
||||||
case tabAdvanced:
|
case tabAdvanced:
|
||||||
return []int{optionsInput, remoteCommandInput, requestTTYInput}
|
return []int{optionsInput, remoteCommandInput, requestTTYInput}
|
||||||
default:
|
default:
|
||||||
return []int{nameInput, hostnameInput, userInput, portInput, identityInput, proxyJumpInput, tagsInput}
|
return []int{nameInput, hostnameInput, userInput, portInput, identityInput, proxyJumpInput, proxyCommandInput, tagsInput}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,6 +408,7 @@ func (m *addFormModel) renderGeneralTab() string {
|
|||||||
{portInput, "Port"},
|
{portInput, "Port"},
|
||||||
{identityInput, "Identity File"},
|
{identityInput, "Identity File"},
|
||||||
{proxyJumpInput, "ProxyJump"},
|
{proxyJumpInput, "ProxyJump"},
|
||||||
|
{proxyCommandInput, "ProxyCommand"},
|
||||||
{tagsInput, "Tags (comma-separated)"},
|
{tagsInput, "Tags (comma-separated)"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,6 +497,7 @@ func (m *addFormModel) submitForm() tea.Cmd {
|
|||||||
port := strings.TrimSpace(m.inputs[portInput].Value())
|
port := strings.TrimSpace(m.inputs[portInput].Value())
|
||||||
identity := strings.TrimSpace(m.inputs[identityInput].Value())
|
identity := strings.TrimSpace(m.inputs[identityInput].Value())
|
||||||
proxyJump := strings.TrimSpace(m.inputs[proxyJumpInput].Value())
|
proxyJump := strings.TrimSpace(m.inputs[proxyJumpInput].Value())
|
||||||
|
proxyCommand := strings.TrimSpace(m.inputs[proxyCommandInput].Value())
|
||||||
options := strings.TrimSpace(m.inputs[optionsInput].Value())
|
options := strings.TrimSpace(m.inputs[optionsInput].Value())
|
||||||
remoteCommand := strings.TrimSpace(m.inputs[remoteCommandInput].Value())
|
remoteCommand := strings.TrimSpace(m.inputs[remoteCommandInput].Value())
|
||||||
requestTTY := strings.TrimSpace(m.inputs[requestTTYInput].Value())
|
requestTTY := strings.TrimSpace(m.inputs[requestTTYInput].Value())
|
||||||
@ -526,6 +535,7 @@ func (m *addFormModel) submitForm() tea.Cmd {
|
|||||||
Port: port,
|
Port: port,
|
||||||
Identity: identity,
|
Identity: identity,
|
||||||
ProxyJump: proxyJump,
|
ProxyJump: proxyJump,
|
||||||
|
ProxyCommand: proxyCommand,
|
||||||
Options: config.ParseSSHOptionsFromCommand(options),
|
Options: config.ParseSSHOptionsFromCommand(options),
|
||||||
RemoteCommand: remoteCommand,
|
RemoteCommand: remoteCommand,
|
||||||
RequestTTY: requestTTY,
|
RequestTTY: requestTTY,
|
||||||
|
@ -91,7 +91,7 @@ func NewEditForm(hostName string, styles Styles, width, height int, configFile s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputs := make([]textinput.Model, 9) // Increased from 8 to 9 for RequestTTY
|
inputs := make([]textinput.Model, 10)
|
||||||
|
|
||||||
// Hostname input
|
// Hostname input
|
||||||
inputs[0] = textinput.New()
|
inputs[0] = textinput.New()
|
||||||
@ -128,37 +128,44 @@ func NewEditForm(hostName string, styles Styles, width, height int, configFile s
|
|||||||
inputs[4].Width = 30
|
inputs[4].Width = 30
|
||||||
inputs[4].SetValue(host.ProxyJump)
|
inputs[4].SetValue(host.ProxyJump)
|
||||||
|
|
||||||
// Options input
|
// ProxyCommand input
|
||||||
inputs[5] = textinput.New()
|
inputs[5] = textinput.New()
|
||||||
inputs[5].Placeholder = "-o StrictHostKeyChecking=no"
|
inputs[5].Placeholder = "ssh -W %h:%p Jumphost"
|
||||||
inputs[5].CharLimit = 200
|
inputs[5].CharLimit = 200
|
||||||
inputs[5].Width = 50
|
inputs[5].Width = 50
|
||||||
|
inputs[5].SetValue(host.ProxyCommand)
|
||||||
|
|
||||||
|
// Options input
|
||||||
|
inputs[6] = textinput.New()
|
||||||
|
inputs[6].Placeholder = "-o StrictHostKeyChecking=no"
|
||||||
|
inputs[6].CharLimit = 200
|
||||||
|
inputs[6].Width = 50
|
||||||
if host.Options != "" {
|
if host.Options != "" {
|
||||||
inputs[5].SetValue(config.FormatSSHOptionsForCommand(host.Options))
|
inputs[6].SetValue(config.FormatSSHOptionsForCommand(host.Options))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags input
|
// Tags input
|
||||||
inputs[6] = textinput.New()
|
inputs[7] = textinput.New()
|
||||||
inputs[6].Placeholder = "production, web, database"
|
inputs[7].Placeholder = "production, web, database"
|
||||||
inputs[6].CharLimit = 200
|
inputs[7].CharLimit = 200
|
||||||
inputs[6].Width = 50
|
inputs[7].Width = 50
|
||||||
if len(host.Tags) > 0 {
|
if len(host.Tags) > 0 {
|
||||||
inputs[6].SetValue(strings.Join(host.Tags, ", "))
|
inputs[7].SetValue(strings.Join(host.Tags, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remote Command input
|
// Remote Command input
|
||||||
inputs[7] = textinput.New()
|
inputs[8] = textinput.New()
|
||||||
inputs[7].Placeholder = "ls -la, htop, bash"
|
inputs[8].Placeholder = "ls -la, htop, bash"
|
||||||
inputs[7].CharLimit = 300
|
inputs[8].CharLimit = 300
|
||||||
inputs[7].Width = 70
|
inputs[8].Width = 70
|
||||||
inputs[7].SetValue(host.RemoteCommand)
|
inputs[8].SetValue(host.RemoteCommand)
|
||||||
|
|
||||||
// RequestTTY input
|
// RequestTTY input
|
||||||
inputs[8] = textinput.New()
|
inputs[9] = textinput.New()
|
||||||
inputs[8].Placeholder = "yes, no, force, auto"
|
inputs[9].Placeholder = "yes, no, force, auto"
|
||||||
inputs[8].CharLimit = 10
|
inputs[9].CharLimit = 10
|
||||||
inputs[8].Width = 30
|
inputs[9].Width = 30
|
||||||
inputs[8].SetValue(host.RequestTTY)
|
inputs[9].SetValue(host.RequestTTY)
|
||||||
|
|
||||||
return &editFormModel{
|
return &editFormModel{
|
||||||
hostInputs: hostInputs,
|
hostInputs: hostInputs,
|
||||||
@ -253,19 +260,19 @@ func (m *editFormModel) updateFocus() tea.Cmd {
|
|||||||
func (m *editFormModel) getPropertiesForCurrentTab() []int {
|
func (m *editFormModel) getPropertiesForCurrentTab() []int {
|
||||||
switch m.currentTab {
|
switch m.currentTab {
|
||||||
case 0: // General
|
case 0: // General
|
||||||
return []int{0, 1, 2, 3, 4, 6} // hostname, user, port, identity, proxyjump, tags
|
return []int{0, 1, 2, 3, 4, 5, 7} // hostname, user, port, identity, proxyjump, proxycommand, tags
|
||||||
case 1: // Advanced
|
case 1: // Advanced
|
||||||
return []int{5, 7, 8} // options, remotecommand, requesttty
|
return []int{6, 8, 9} // options, remotecommand, requesttty
|
||||||
default:
|
default:
|
||||||
return []int{0, 1, 2, 3, 4, 6}
|
return []int{0, 1, 2, 3, 4, 5, 7}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFirstPropertyForTab returns the first property index for a given tab
|
// getFirstPropertyForTab returns the first property index for a given tab
|
||||||
func (m *editFormModel) getFirstPropertyForTab(tab int) int {
|
func (m *editFormModel) getFirstPropertyForTab(tab int) int {
|
||||||
properties := []int{0, 1, 2, 3, 4, 6} // General tab
|
properties := []int{0, 1, 2, 3, 4, 5, 7} // General tab
|
||||||
if tab == 1 {
|
if tab == 1 {
|
||||||
properties = []int{5, 7, 8} // Advanced tab
|
properties = []int{6, 8, 9} // Advanced tab
|
||||||
}
|
}
|
||||||
if len(properties) > 0 {
|
if len(properties) > 0 {
|
||||||
return properties[0]
|
return properties[0]
|
||||||
@ -580,7 +587,8 @@ func (m *editFormModel) renderEditGeneralTab() string {
|
|||||||
{2, "Port"},
|
{2, "Port"},
|
||||||
{3, "Identity File"},
|
{3, "Identity File"},
|
||||||
{4, "Proxy Jump"},
|
{4, "Proxy Jump"},
|
||||||
{6, "Tags (comma-separated)"},
|
{5, "Proxy Command"},
|
||||||
|
{7, "Tags (comma-separated)"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
@ -683,9 +691,10 @@ func (m *editFormModel) submitEditForm() tea.Cmd {
|
|||||||
port := strings.TrimSpace(m.inputs[2].Value()) // portInput
|
port := strings.TrimSpace(m.inputs[2].Value()) // portInput
|
||||||
identity := strings.TrimSpace(m.inputs[3].Value()) // identityInput
|
identity := strings.TrimSpace(m.inputs[3].Value()) // identityInput
|
||||||
proxyJump := strings.TrimSpace(m.inputs[4].Value()) // proxyJumpInput
|
proxyJump := strings.TrimSpace(m.inputs[4].Value()) // proxyJumpInput
|
||||||
options := strings.TrimSpace(m.inputs[5].Value()) // optionsInput
|
proxyCommand := strings.TrimSpace(m.inputs[5].Value()) // proxyCommandInput
|
||||||
remoteCommand := strings.TrimSpace(m.inputs[7].Value()) // remoteCommandInput
|
options := strings.TrimSpace(m.inputs[6].Value()) // optionsInput
|
||||||
requestTTY := strings.TrimSpace(m.inputs[8].Value()) // requestTTYInput
|
remoteCommand := strings.TrimSpace(m.inputs[8].Value()) // remoteCommandInput
|
||||||
|
requestTTY := strings.TrimSpace(m.inputs[9].Value()) // requestTTYInput
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
if port == "" {
|
if port == "" {
|
||||||
@ -723,6 +732,7 @@ func (m *editFormModel) submitEditForm() tea.Cmd {
|
|||||||
Port: port,
|
Port: port,
|
||||||
Identity: identity,
|
Identity: identity,
|
||||||
ProxyJump: proxyJump,
|
ProxyJump: proxyJump,
|
||||||
|
ProxyCommand: proxyCommand,
|
||||||
Options: options,
|
Options: options,
|
||||||
RemoteCommand: remoteCommand,
|
RemoteCommand: remoteCommand,
|
||||||
RequestTTY: requestTTY,
|
RequestTTY: requestTTY,
|
||||||
|
@ -97,6 +97,7 @@ func (m *infoFormModel) View() string {
|
|||||||
{"Port", formatOptionalValue(m.host.Port)},
|
{"Port", formatOptionalValue(m.host.Port)},
|
||||||
{"Identity File", formatOptionalValue(m.host.Identity)},
|
{"Identity File", formatOptionalValue(m.host.Identity)},
|
||||||
{"ProxyJump", formatOptionalValue(m.host.ProxyJump)},
|
{"ProxyJump", formatOptionalValue(m.host.ProxyJump)},
|
||||||
|
{"ProxyCommand", formatOptionalValue(m.host.ProxyCommand)},
|
||||||
{"SSH Options", formatSSHOptions(m.host.Options)},
|
{"SSH Options", formatSSHOptions(m.host.Options)},
|
||||||
{"Tags", formatTags(m.host.Tags)},
|
{"Tags", formatTags(m.host.Tags)},
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user