161 lines
3.7 KiB
Go
161 lines
3.7 KiB
Go
package common
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"net/http"
|
|
|
|
"github.com/antihax/optional"
|
|
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
|
|
"github.com/outscale/osc-sdk-go/osc"
|
|
)
|
|
|
|
type oscDescriber interface {
|
|
ReadVms(ctx context.Context, localVarOptionals *osc.ReadVmsOpts) (osc.ReadVmsResponse, *http.Response, error)
|
|
}
|
|
|
|
var (
|
|
// modified in tests
|
|
sshHostSleepDuration = time.Second
|
|
)
|
|
|
|
// SSHHost returns a function that can be given to the SSH communicator
|
|
// for determining the SSH address based on the vm DNS name.
|
|
func SSHHost(e oscDescriber, sshInterface string) func(multistep.StateBag) (string, error) {
|
|
return func(state multistep.StateBag) (string, error) {
|
|
const tries = 2
|
|
// <= with current structure to check result of describing `tries` times
|
|
for j := 0; j <= tries; j++ {
|
|
var host string
|
|
i := state.Get("vm").(osc.Vm)
|
|
|
|
if sshInterface != "" {
|
|
switch sshInterface {
|
|
case "public_ip":
|
|
if i.PublicIp != "" {
|
|
host = i.PublicIp
|
|
}
|
|
case "public_dns":
|
|
if i.PublicDnsName != "" {
|
|
host = i.PublicDnsName
|
|
}
|
|
case "private_ip":
|
|
if i.PrivateIp != "" {
|
|
host = i.PrivateIp
|
|
}
|
|
case "private_dns":
|
|
if i.PrivateDnsName != "" {
|
|
host = i.PrivateDnsName
|
|
}
|
|
default:
|
|
panic(fmt.Sprintf("Unknown interface type: %s", sshInterface))
|
|
}
|
|
} else if i.NetId != "" {
|
|
if i.PublicIp != "" {
|
|
host = i.PublicIp
|
|
} else if i.PrivateIp != "" {
|
|
host = i.PrivateIp
|
|
}
|
|
} else if i.PublicDnsName != "" {
|
|
host = i.PublicDnsName
|
|
}
|
|
|
|
if host != "" {
|
|
return host, nil
|
|
}
|
|
|
|
r, _, err := e.ReadVms(context.Background(), &osc.ReadVmsOpts{
|
|
ReadVmsRequest: optional.NewInterface(osc.ReadVmsRequest{
|
|
Filters: osc.FiltersVm{
|
|
VmIds: []string{i.VmId},
|
|
},
|
|
}),
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if len(r.Vms) == 0 {
|
|
return "", fmt.Errorf("vm not found: %s", i.VmId)
|
|
}
|
|
|
|
state.Put("vm", r.Vms[0])
|
|
time.Sleep(sshHostSleepDuration)
|
|
}
|
|
|
|
return "", errors.New("couldn't determine address for vm")
|
|
}
|
|
}
|
|
|
|
// SSHHost returns a function that can be given to the SSH communicator
|
|
// for determining the SSH address based on the vm DNS name.
|
|
func OscSSHHost(e oscDescriber, sshInterface string) func(multistep.StateBag) (string, error) {
|
|
return func(state multistep.StateBag) (string, error) {
|
|
const tries = 2
|
|
// <= with current structure to check result of describing `tries` times
|
|
for j := 0; j <= tries; j++ {
|
|
var host string
|
|
i := state.Get("vm").(osc.Vm)
|
|
|
|
if sshInterface != "" {
|
|
switch sshInterface {
|
|
case "public_ip":
|
|
if i.PublicIp != "" {
|
|
host = i.PublicIp
|
|
}
|
|
case "public_dns":
|
|
if i.PublicDnsName != "" {
|
|
host = i.PublicDnsName
|
|
}
|
|
case "private_ip":
|
|
if i.PrivateIp != "" {
|
|
host = i.PrivateIp
|
|
}
|
|
case "private_dns":
|
|
if i.PrivateDnsName != "" {
|
|
host = i.PrivateDnsName
|
|
}
|
|
default:
|
|
panic(fmt.Sprintf("Unknown interface type: %s", sshInterface))
|
|
}
|
|
} else if i.NetId != "" {
|
|
if i.PublicIp != "" {
|
|
host = i.PublicIp
|
|
} else if i.PrivateIp != "" {
|
|
host = i.PrivateIp
|
|
}
|
|
} else if i.PublicDnsName != "" {
|
|
host = i.PublicDnsName
|
|
}
|
|
|
|
if host != "" {
|
|
return host, nil
|
|
}
|
|
|
|
r, _, err := e.ReadVms(context.Background(), &osc.ReadVmsOpts{
|
|
ReadVmsRequest: optional.NewInterface(osc.ReadVmsRequest{
|
|
Filters: osc.FiltersVm{
|
|
VmIds: []string{i.VmId},
|
|
},
|
|
}),
|
|
})
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if len(r.Vms) == 0 {
|
|
return "", fmt.Errorf("vm not found: %s", i.VmId)
|
|
}
|
|
|
|
state.Put("vm", r.Vms[0])
|
|
time.Sleep(sshHostSleepDuration)
|
|
}
|
|
|
|
return "", errors.New("couldn't determine address for vm")
|
|
}
|
|
}
|