Support run and destroy

This commit is contained in:
Quentin 2021-09-23 10:22:19 +02:00
parent a8b9a43c02
commit e03b09b68f

107
main.go
View file

@ -3,15 +3,17 @@ package main
import ( import (
"bytes" "bytes"
"io" "io"
"io/ioutil" "net"
"os" "os"
"fmt" "fmt"
"errors" "errors"
"time" "time"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"github.com/pkg/sftp" "github.com/pkg/sftp"
"github.com/scaleway/scaleway-sdk-go/scw" "github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1"
) )
@ -256,7 +258,42 @@ func (dt *destroyer) onInstance(zone, machine, image, name string) error {
type runner struct { action } type runner struct { action }
func (r *runner) onInstance(zone, machine, image, name string) error { func (r *runner) connect(zone, name string) (*ssh.Client, error) {
// Connect to the remote
z, err := scw.ParseZone(zone)
if err != nil {
return nil, err
}
targetServer, err := r.getInstanceByName(z, name)
if err != nil {
return nil, err
}
if targetServer.PublicIP == nil {
return nil, errors.New("run failed: this instance has no public ip.")
}
ip := targetServer.PublicIP.Address
socket := os.Getenv("SSH_AUTH_SOCK")
conn, err := net.Dial("unix", socket)
if err != nil {
return nil, err
}
agentClient := agent.NewClient(conn)
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.PublicKeysCallback(agentClient.Signers),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
return ssh.Dial("tcp", ip.String()+":22", config)
}
func (r *runner) send(sshClient *ssh.Client) error {
// Source script // Source script
if len(os.Args) < 3 { if len(os.Args) < 3 {
return errors.New("Missing script to run on the command line") return errors.New("Missing script to run on the command line")
@ -268,47 +305,6 @@ func (r *runner) onInstance(zone, machine, image, name string) error {
} }
defer src.Close() defer src.Close()
// Connect to the remote
z, err := scw.ParseZone(zone)
if err != nil {
return err
}
targetServer, err := r.getInstanceByName(z, name)
if err != nil {
return err
}
if targetServer.PublicIP == nil {
return errors.New("run failed: this instance has no public ip.")
}
ip := targetServer.PublicIP.Address
var hostKey ssh.PublicKey
key, err := ioutil.ReadFile(os.Getenv("HOME") + "/.ssh/id_rsa")
if err != nil {
return err
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
return err
}
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.FixedHostKey(hostKey),
}
sshClient, err := ssh.Dial("tcp", ip.String()+":22", config)
if err != nil {
return err
}
defer sshClient.Close()
// Send our script to the destination // Send our script to the destination
sftpClient, err := sftp.NewClient(sshClient) sftpClient, err := sftp.NewClient(sshClient)
if err != nil { if err != nil {
@ -328,10 +324,10 @@ func (r *runner) onInstance(zone, machine, image, name string) error {
} }
_, err = io.Copy(dst, src) _, err = io.Copy(dst, src)
if err != nil {
return err return err
} }
func (r *runner) exec(sshClient *ssh.Client) error {
// Run the script // Run the script
session, err := sshClient.NewSession() session, err := sshClient.NewSession()
if err != nil { if err != nil {
@ -345,7 +341,7 @@ func (r *runner) onInstance(zone, machine, image, name string) error {
err = session.Run("/tmp/nuage") err = session.Run("/tmp/nuage")
if os.Getenv("VERBOSE") != "" { if os.Getenv("VERBOSE") != "" {
fmt.Fprintf(os.Stdout, "logs for %v\n", name) fmt.Fprintf(os.Stdout, "logs\n")
io.Copy(os.Stdout, &sshStdout) io.Copy(os.Stdout, &sshStdout)
io.Copy(os.Stderr, &sshStderr) io.Copy(os.Stderr, &sshStderr)
} }
@ -356,6 +352,27 @@ func (r *runner) onInstance(zone, machine, image, name string) error {
return nil return nil
} }
func (r *runner) onInstance(zone, machine, image, name string) error {
sshClient, err := r.connect(zone, name)
if err != nil {
return err
}
defer sshClient.Close()
err = r.send(sshClient)
if err != nil {
return err
}
err = r.exec(sshClient)
if err != nil {
return err
}
fmt.Fprintf(os.Stdout, "✅ Successfully ran the script on %v (zone %v)\n", name, zone)
return nil
}
/** /**
* Commands * Commands