This commit substitutes the now-deprecated gosdc library for the newer triton-go library. This is transparent from a user perspective, except for the fact that key material can now be ommitted and requests can be signed with an SSH agent. This allows for both encrypted keys and ECDSA keys to be used. In addition, a fix is made to not pass in an empty array of networks if none are specified in configuration, thus honouring the API default of putting instances with no explicit networks specified on the Joyent public and internal shared networks.
89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package triton
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
packerssh "github.com/hashicorp/packer/communicator/ssh"
|
|
"github.com/mitchellh/multistep"
|
|
"golang.org/x/crypto/ssh"
|
|
"golang.org/x/crypto/ssh/agent"
|
|
"io/ioutil"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
)
|
|
|
|
func commHost(state multistep.StateBag) (string, error) {
|
|
driver := state.Get("driver").(Driver)
|
|
machineID := state.Get("machine").(string)
|
|
|
|
machine, err := driver.GetMachineIP(machineID)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return machine, nil
|
|
}
|
|
|
|
// SSHConfig returns a function that can be used for the SSH communicator
|
|
// config for connecting to the instance created over SSH using the private key
|
|
// or password.
|
|
func sshConfig(useAgent bool, username, privateKeyPath, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
|
|
return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
|
|
|
|
if useAgent {
|
|
log.Println("Configuring SSH agent.")
|
|
|
|
authSock := os.Getenv("SSH_AUTH_SOCK")
|
|
if authSock == "" {
|
|
return nil, fmt.Errorf("SSH_AUTH_SOCK is not set")
|
|
}
|
|
|
|
sshAgent, err := net.Dial("unix", authSock)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Cannot connect to SSH Agent socket %q: %s", authSock, err)
|
|
}
|
|
|
|
return &ssh.ClientConfig{
|
|
User: username,
|
|
Auth: []ssh.AuthMethod{
|
|
ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
hasKey := privateKeyPath != ""
|
|
|
|
if hasKey {
|
|
log.Printf("Configuring SSH private key '%s'.", privateKeyPath)
|
|
|
|
privateKeyBytes, err := ioutil.ReadFile(privateKeyPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Unable to read SSH private key: %s", err)
|
|
}
|
|
|
|
signer, err := ssh.ParsePrivateKey(privateKeyBytes)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
|
}
|
|
|
|
return &ssh.ClientConfig{
|
|
User: username,
|
|
Auth: []ssh.AuthMethod{
|
|
ssh.PublicKeys(signer),
|
|
},
|
|
}, nil
|
|
} else {
|
|
log.Println("Configuring SSH keyboard interactive.")
|
|
|
|
return &ssh.ClientConfig{
|
|
User: username,
|
|
Auth: []ssh.AuthMethod{
|
|
ssh.Password(password),
|
|
ssh.KeyboardInteractive(
|
|
packerssh.PasswordKeyboardInteractive(password)),
|
|
}}, nil
|
|
}
|
|
}
|
|
}
|