builder/osc: fix ssh host detection in Public Cloud and Nets

This commit is contained in:
Aurélien Guillaume 2019-11-26 17:46:00 +01:00
parent 29d6c05ef8
commit 1a397b9fcd
7 changed files with 107 additions and 59 deletions

View File

@ -128,6 +128,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Comm: &b.config.RunConfig.Comm,
DebugKeyPath: fmt.Sprintf("oapi_%s", b.config.PackerBuildName),
},
&osccommon.StepPublicIp{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
Debug: b.config.PackerDebug,
},
&osccommon.StepSecurityGroup{
SecurityGroupFilter: b.config.SecurityGroupFilter,
SecurityGroupIds: b.config.SecurityGroupIds,
@ -138,7 +142,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
BlockDevices: b.config.BlockDevices,
},
&osccommon.StepRunSourceVm{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,

View File

@ -149,6 +149,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Comm: &b.config.RunConfig.Comm,
DebugKeyPath: fmt.Sprintf("oapi_%s", b.config.PackerBuildName),
},
&osccommon.StepPublicIp{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
Debug: b.config.PackerDebug,
},
&osccommon.StepSecurityGroup{
SecurityGroupFilter: b.config.SecurityGroupFilter,
SecurityGroupIds: b.config.SecurityGroupIds,
@ -159,7 +163,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
BlockDevices: b.config.BlockDevices,
},
&osccommon.StepRunSourceVm{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,

View File

@ -109,7 +109,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
log.Printf("[DEBUG] launch block devices %#v", b.config.launchBlockDevices)
instanceStep := &osccommon.StepRunSourceVm{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.launchBlockDevices,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,
@ -146,6 +145,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Comm: &b.config.RunConfig.Comm,
DebugKeyPath: fmt.Sprintf("oapi_%s.pem", b.config.PackerBuildName),
},
&osccommon.StepPublicIp{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
Debug: b.config.PackerDebug,
},
&osccommon.StepSecurityGroup{
SecurityGroupFilter: b.config.SecurityGroupFilter,
SecurityGroupIds: b.config.SecurityGroupIds,

View File

@ -3,7 +3,6 @@ package common
import (
"errors"
"fmt"
"sort"
"time"
"github.com/hashicorp/packer/helper/multistep"
@ -29,41 +28,35 @@ func SSHHost(e oapiDescriber, sshInterface string) func(multistep.StateBag) (str
var host string
i := state.Get("vm").(oapi.Vm)
if len(i.Nics) <= 0 {
return "", errors.New("couldn't determine address for vm, nics are empty")
}
nic := i.Nics[0]
if sshInterface != "" {
switch sshInterface {
case "public_ip":
if nic.LinkPublicIp.PublicIp != "" {
host = nic.LinkPublicIp.PublicIp
if i.PublicIp != "" {
host = i.PublicIp
}
case "public_dns":
if nic.LinkPublicIp.PublicDnsName != "" {
host = nic.LinkPublicIp.PublicDnsName
if i.PublicDnsName != "" {
host = i.PublicDnsName
}
case "private_ip":
if privateIP, err := getPrivateIP(nic); err != nil {
host = privateIP.PrivateIp
if i.PrivateIp != "" {
host = i.PrivateIp
}
case "private_dns":
if privateIP, err := getPrivateIP(nic); err != nil {
host = privateIP.PrivateDnsName
if i.PrivateDnsName != "" {
host = i.PrivateDnsName
}
default:
panic(fmt.Sprintf("Unknown interface type: %s", sshInterface))
}
} else if i.NetId != "" {
if nic.LinkPublicIp.PublicIp != "" {
host = nic.LinkPublicIp.PublicIp
} else if privateIP, err := getPrivateIP(nic); err != nil {
host = privateIP.PrivateIp
if i.PublicIp != "" {
host = i.PublicIp
} else if i.PrivateIp != "" {
host = i.PrivateIp
}
} else if nic.LinkPublicIp.PublicDnsName != "" {
host = nic.LinkPublicIp.PublicDnsName
} else if i.PublicDnsName != "" {
host = i.PublicDnsName
}
if host != "" {
@ -90,20 +83,3 @@ func SSHHost(e oapiDescriber, sshInterface string) func(multistep.StateBag) (str
return "", errors.New("couldn't determine address for vm")
}
}
func getPrivateIP(nic oapi.NicLight) (oapi.PrivateIpLightForVm, error) {
isPrimary := true
i := sort.Search(len(nic.PrivateIps), func(i int) bool { return nic.PrivateIps[i].IsPrimary == isPrimary })
if i < len(nic.PrivateIps) && nic.PrivateIps[i].IsPrimary == isPrimary {
return nic.PrivateIps[i], nil
}
if len(nic.PrivateIps) > 0 {
return nic.PrivateIps[0], nil
}
return oapi.PrivateIpLightForVm{}, fmt.Errorf("couldn't determine private address for vm")
}

View File

@ -88,7 +88,7 @@ func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) e
func waitUntilVmStateFunc(conn *oapi.Client, id string) stateRefreshFunc {
return func() (string, error) {
log.Printf("[Debug] Check if SG with id %s exists", id)
log.Printf("[Debug] Retrieving state for VM with id %s", id)
resp, err := conn.POST_ReadVms(oapi.ReadVmsRequest{
Filters: oapi.FiltersVm{
VmIds: []string{id},
@ -102,7 +102,7 @@ func waitUntilVmStateFunc(conn *oapi.Client, id string) stateRefreshFunc {
}
if resp.OK == nil {
return "", fmt.Errorf("Vm with ID %s. Not Found", id)
return "", fmt.Errorf("Vm with ID %s not Found", id)
}
if len(resp.OK.Vms) == 0 {

View File

@ -0,0 +1,68 @@
package common
import (
"context"
"fmt"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/outscale/osc-go/oapi"
)
type StepPublicIp struct {
AssociatePublicIpAddress bool
Comm *communicator.Config
publicIpId string
Debug bool
doCleanup bool
}
func (s *StepPublicIp) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
oapiconn := state.Get("oapi").(*oapi.Client)
netId := state.Get("net_id").(string)
subnetId := state.Get("subnet_id").(string)
if netId == "" || subnetId == "" || !s.AssociatePublicIpAddress {
// In this case, we are in the public Cloud, so we'll
// not explicitely allocate a public IP.
return multistep.ActionContinue
}
ui.Say(fmt.Sprintf("Creating temporary PublicIp for instance in subnet %s (net %s)", subnetId, netId))
publicIpResp, err := oapiconn.POST_CreatePublicIp(oapi.CreatePublicIpRequest{})
if err != nil {
state.Put("error", fmt.Errorf("Error creating temporary PublicIp: %s", err))
return multistep.ActionHalt
}
// From there, we have a Public Ip to destroy.
s.doCleanup = true
// Set some data for use in future steps
s.publicIpId = publicIpResp.OK.PublicIp.PublicIpId
state.Put("publicip_id", publicIpResp.OK.PublicIp.PublicIpId)
return multistep.ActionContinue
}
func (s *StepPublicIp) Cleanup(state multistep.StateBag) {
if !s.doCleanup {
return
}
oapiconn := state.Get("oapi").(*oapi.Client)
ui := state.Get("ui").(packer.Ui)
// Remove the Public IP
ui.Say("Deleting temporary PublicIp...")
_, err := oapiconn.POST_DeletePublicIp(oapi.DeletePublicIpRequest{PublicIpId: s.publicIpId})
if err != nil {
ui.Error(fmt.Sprintf(
"Error cleaning up PublicIp. Please delete the PublicIp manually: %s", s.publicIpId))
}
}

View File

@ -23,7 +23,6 @@ const (
)
type StepRunSourceVm struct {
AssociatePublicIpAddress bool
BlockDevices BlockDevices
Comm *communicator.Config
Ctx interpolate.Context
@ -158,20 +157,8 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul
subnetId := state.Get("subnet_id").(string)
if subnetId != "" && s.AssociatePublicIpAddress {
runOpts.Nics = []oapi.NicForVmCreation{
{
DeviceNumber: 0,
//AssociatePublicIpAddress: s.AssociatePublicIpAddress,
SubnetId: subnetId,
SecurityGroupIds: securityGroupIds,
DeleteOnVmDeletion: true,
},
}
} else {
runOpts.SubnetId = subnetId
runOpts.SecurityGroupIds = securityGroupIds
}
runOpts.SubnetId = subnetId
runOpts.SecurityGroupIds = securityGroupIds
if s.ExpectedRootDevice == "bsu" {
runOpts.VmInitiatedShutdownBehavior = s.VmInitiatedShutdownBehavior
@ -224,7 +211,15 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul
}
}
//TODO: LinkPublicIp i
if publicip_id, ok := state.Get("publicip_id").(string); ok {
ui.Say(fmt.Sprintf("Linking temporary PublicIp %s to instance %s", publicip_id, vmId))
_, err := oapiconn.POST_LinkPublicIp(oapi.LinkPublicIpRequest{PublicIpId: publicip_id, VmId: vmId})
if err != nil {
state.Put("error", fmt.Errorf("Error linking PublicIp to VM: %s", err))
ui.Error(err.Error())
return multistep.ActionHalt
}
}
resp, err := oapiconn.POST_ReadVms(request)