0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00

feat(provider): add support for ssh-agent on Windows (#1270)

* feat(provider): add support for `ssh-agent` on Windows

Signed-off-by: Brian Karshick <Sparta142@users.noreply.github.com>
This commit is contained in:
Brian 2024-05-09 23:00:44 -04:00 committed by GitHub
parent 6ae9b581df
commit ccf4834c16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 11 deletions

View File

@ -116,9 +116,11 @@ This allows the provider to use the SSH agent configured by the user, and to sup
You can find more details on the SSH Agent [here](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys#adding-your-ssh-keys-to-an-ssh-agent-to-avoid-typing-the-passphrase).
The SSH agent authentication takes precedence over the `private_key` and `password` authentication.
-> By default on Windows, the provider will assume the SSH agent is at `\\.\pipe\openssh-ssh-agent`.
### SSH Private Key
In some cases where SSH agent is not available, for example when running Terraform from a Windows machine, or when using a CI/CD pipeline that does not support SSH agent forwarding,
In some cases where SSH agent is not available, for example when using a CI/CD pipeline that does not support SSH agent forwarding,
you can use the `private_key` argument in the `ssh` block (or alternatively `PROXMOX_VE_SSH_PRIVATE_KEY` environment variable) to provide the private key for the SSH connection.
The private key mut not be encrypted, and must be in PEM format.

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.22
toolchain go1.22.3
require (
github.com/Microsoft/go-winio v0.6.2
github.com/avast/retry-go/v4 v4.6.0
github.com/brianvoe/gofakeit/v7 v7.0.3
github.com/google/go-cmp v0.6.0

4
go.sum
View File

@ -1,7 +1,7 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.1.0-alpha.0 h1:nHGfwXmFvJrSR9xu8qL7BkO4DqTHXE9N5vPhgY2I+j0=
github.com/ProtonMail/go-crypto v1.1.0-alpha.0/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=

View File

@ -78,9 +78,13 @@ func NewClient(
socks5Server string, socks5Username string, socks5Password string,
nodeResolver NodeResolver,
) (Client, error) {
if agent && runtime.GOOS != "linux" && runtime.GOOS != "darwin" && runtime.GOOS != "freebsd" {
if agent &&
runtime.GOOS != "linux" &&
runtime.GOOS != "darwin" &&
runtime.GOOS != "freebsd" &&
runtime.GOOS != "windows" {
return nil, errors.New(
"the ssh agent flag is only supported on POSIX systems, please set it to 'false'" +
"the ssh agent flag is only supported on POSIX and Windows systems, please set it to 'false'" +
" or remove it from your provider configuration",
)
}
@ -531,12 +535,7 @@ func (c *client) createSSHClientAgent(
kh knownhosts.HostKeyCallback,
sshHost string,
) (*ssh.Client, error) {
if c.agentSocket == "" {
return nil, errors.New("failed connecting to SSH agent socket: the socket file is not defined, " +
"authentication will fall back to password")
}
conn, err := net.Dial("unix", c.agentSocket)
conn, err := dialSocket(c.agentSocket)
if err != nil {
return nil, fmt.Errorf("failed connecting to SSH auth socket '%s': %w", c.agentSocket, err)
}

View File

@ -0,0 +1,24 @@
//go:build !windows
package ssh
import (
"errors"
"fmt"
"net"
)
// dialSocket dials a Unix domain socket.
func dialSocket(address string) (net.Conn, error) {
if address == "" {
return nil, errors.New("failed connecting to SSH agent socket: the socket file is not defined, " +
"authentication will fall back to password")
}
conn, err := net.Dial("unix", address)
if err != nil {
return nil, fmt.Errorf("error dialing unix socket: %w", err)
}
return conn, nil
}

View File

@ -0,0 +1,24 @@
//go:build windows
package ssh
import (
"fmt"
"net"
"github.com/Microsoft/go-winio"
)
// dialSocket dials a Windows named pipe. If address is empty, it dials the default ssh-agent pipe.
func dialSocket(address string) (net.Conn, error) {
if address == "" {
address = `\\.\pipe\openssh-ssh-agent`
}
conn, err := winio.DialPipe(address, nil)
if err != nil {
return nil, fmt.Errorf("error dialing named pipe: %w", err)
}
return conn, nil
}