feat: add identity_file field to config connections config

This commit is contained in:
Connor Edwards
2025-02-08 15:56:18 +00:00
parent e3a310397b
commit ac48b8bee6
5 changed files with 57 additions and 11 deletions
+8 -2
View File
@@ -4,15 +4,17 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/charmbracelet/huh"
"google.golang.org/protobuf/types/known/emptypb"
"net/netip" "net/netip"
"uncloud/internal/cli/client" "uncloud/internal/cli/client"
"uncloud/internal/cli/client/connector" "uncloud/internal/cli/client/connector"
"uncloud/internal/cli/config" "uncloud/internal/cli/config"
"uncloud/internal/fs"
"uncloud/internal/machine" "uncloud/internal/machine"
"uncloud/internal/machine/api/pb" "uncloud/internal/machine/api/pb"
"uncloud/internal/sshexec" "uncloud/internal/sshexec"
"github.com/charmbracelet/huh"
"google.golang.org/protobuf/types/known/emptypb"
) )
const defaultClusterName = "default" const defaultClusterName = "default"
@@ -89,10 +91,14 @@ func (cli *CLI) ConnectCluster(ctx context.Context, clusterName string) (*client
if err != nil { if err != nil {
return nil, fmt.Errorf("parse SSH connection %q: %w", conn.SSH, err) return nil, fmt.Errorf("parse SSH connection %q: %w", conn.SSH, err)
} }
keyPath := fs.ExpandHomeDir(conn.IdentityFile)
sshConfig := &connector.SSHConnectorConfig{ sshConfig := &connector.SSHConnectorConfig{
User: user, User: user,
Host: host, Host: host,
Port: port, Port: port,
KeyPath: keyPath,
} }
return client.New(ctx, connector.NewSSHConnector(sshConfig)) return client.New(ctx, connector.NewSSHConnector(sshConfig))
} else if conn.TCP.IsValid() { } else if conn.TCP.IsValid() {
+1
View File
@@ -18,6 +18,7 @@ type MachineConnection struct {
TCP netip.AddrPort `toml:"tcp,omitempty"` TCP netip.AddrPort `toml:"tcp,omitempty"`
Host string `toml:"host,omitempty"` Host string `toml:"host,omitempty"`
PublicKey secret.Secret `toml:"public_key,omitempty"` PublicKey secret.Secret `toml:"public_key,omitempty"`
IdentityFile string `toml:"identity_file,omitempty"`
} }
// SSHDestination represents an SSH destination string in the canonical form of "user@host:port". // SSHDestination represents an SSH destination string in the canonical form of "user@host:port".
+13
View File
@@ -5,8 +5,21 @@ import (
"os" "os"
"os/user" "os/user"
"strconv" "strconv"
"strings"
) )
func ExpandHomeDir(path string) string {
if len(path) == 0 {
return path
}
if path[0] == '~' {
// TODO: Improve compat with other OSes
path = strings.Replace(path, "~", "${HOME}", 1)
return os.ExpandEnv(path)
}
return path
}
// LookupUIDGID returns the user and group IDs for the given username. // LookupUIDGID returns the user and group IDs for the given username.
func LookupUIDGID(username string) (uid, gid int, err error) { func LookupUIDGID(username string) (uid, gid int, err error) {
usr, err := user.Lookup(username) usr, err := user.Lookup(username)
+22
View File
@@ -0,0 +1,22 @@
package fs
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestExpandHomeDir(t *testing.T) {
t.Run("empty", func(t *testing.T) {
assert.Equal(t, "", ExpandHomeDir(""))
})
t.Run("no home", func(t *testing.T) {
assert.Equal(t, "/path", ExpandHomeDir("/path"))
})
t.Run("home", func(t *testing.T) {
t.Setenv("HOME", "/home/user")
assert.Equal(t, "/home/user/path", ExpandHomeDir("~/path"))
})
}
+6 -2
View File
@@ -2,12 +2,13 @@ package sshexec
import ( import (
"fmt" "fmt"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"net" "net"
"os" "os"
"strconv" "strconv"
"time" "time"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
) )
func Connect(user, host string, port int, sshKeyPath string) (*ssh.Client, error) { func Connect(user, host string, port int, sshKeyPath string) (*ssh.Client, error) {
@@ -34,6 +35,9 @@ func Connect(user, host string, port int, sshKeyPath string) (*ssh.Client, error
} }
keyAuth, err := privateKeyAuth(sshKeyPath) keyAuth, err := privateKeyAuth(sshKeyPath)
if err != nil {
return nil, err
}
config := &ssh.ClientConfig{ config := &ssh.ClientConfig{
User: user, User: user,
Auth: []ssh.AuthMethod{keyAuth}, Auth: []ssh.AuthMethod{keyAuth},