2016-11-13 17:34:36 -05:00
|
|
|
package oneandone
|
|
|
|
|
|
|
|
import (
|
2018-01-22 18:32:33 -05:00
|
|
|
"context"
|
2016-11-13 17:34:36 -05:00
|
|
|
"fmt"
|
2018-01-22 20:21:10 -05:00
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2016-11-13 17:34:36 -05:00
|
|
|
"github.com/1and1/oneandone-cloudserver-sdk-go"
|
2018-01-19 19:18:44 -05:00
|
|
|
"github.com/hashicorp/packer/helper/multistep"
|
2017-04-04 16:39:01 -04:00
|
|
|
"github.com/hashicorp/packer/packer"
|
2016-11-13 17:34:36 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type stepCreateServer struct{}
|
|
|
|
|
2019-03-29 11:50:02 -04:00
|
|
|
func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
2016-11-13 17:34:36 -05:00
|
|
|
ui := state.Get("ui").(packer.Ui)
|
|
|
|
c := state.Get("config").(*Config)
|
|
|
|
|
|
|
|
token := oneandone.SetToken(c.Token)
|
2016-11-15 18:17:30 -05:00
|
|
|
|
2016-11-13 17:34:36 -05:00
|
|
|
//Create an API client
|
|
|
|
api := oneandone.New(token, c.Url)
|
|
|
|
|
|
|
|
// List server appliances
|
|
|
|
saps, _ := api.ListServerAppliances()
|
|
|
|
|
|
|
|
time.Sleep(time.Second * 10)
|
|
|
|
|
|
|
|
var sa oneandone.ServerAppliance
|
|
|
|
for _, a := range saps {
|
|
|
|
|
|
|
|
if a.Type == "IMAGE" && strings.Contains(strings.ToLower(a.Name), strings.ToLower(c.Image)) {
|
|
|
|
sa = a
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.DiskSize < sa.MinHddSize {
|
|
|
|
ui.Error(fmt.Sprintf("Minimum required disk size %d", sa.MinHddSize))
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.Say("Creating Server...")
|
|
|
|
|
|
|
|
// Create a server
|
|
|
|
req := oneandone.ServerRequest{
|
|
|
|
Name: c.SnapshotName,
|
|
|
|
Description: "Example server description.",
|
|
|
|
ApplianceId: sa.Id,
|
|
|
|
PowerOn: true,
|
|
|
|
Hardware: oneandone.Hardware{
|
|
|
|
Vcores: 1,
|
|
|
|
CoresPerProcessor: 1,
|
|
|
|
Ram: 2,
|
|
|
|
Hdds: []oneandone.Hdd{
|
|
|
|
{
|
|
|
|
Size: c.DiskSize,
|
|
|
|
IsMain: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2016-11-15 18:17:30 -05:00
|
|
|
if c.DataCenterId != "" {
|
|
|
|
req.DatacenterId = c.DataCenterId
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Comm.SSHPassword != "" {
|
|
|
|
req.Password = c.Comm.SSHPassword
|
2016-11-13 17:34:36 -05:00
|
|
|
}
|
2018-08-29 08:01:55 -04:00
|
|
|
if len(c.Comm.SSHPublicKey) != 0 {
|
|
|
|
req.SSHKey = string(c.Comm.SSHPublicKey)
|
2016-11-15 18:17:30 -05:00
|
|
|
}
|
|
|
|
|
2016-11-13 17:34:36 -05:00
|
|
|
server_id, server, err := api.CreateServer(&req)
|
2019-10-28 11:25:48 -04:00
|
|
|
if err != nil {
|
|
|
|
ui.Error(err.Error())
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
2016-11-13 17:34:36 -05:00
|
|
|
|
2019-10-28 11:25:48 -04:00
|
|
|
// Wait until server is created and powered on for at most 60 x 10 seconds
|
|
|
|
err = api.WaitForState(server, "POWERED_ON", 10, c.Retries)
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Timeout waiting for server: %s", server_id))
|
2016-11-13 17:34:36 -05:00
|
|
|
ui.Error(err.Error())
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get a server
|
|
|
|
server, err = api.GetServer(server_id)
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(err.Error())
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
|
|
|
|
state.Put("server_id", server_id)
|
2019-12-13 14:57:01 -05:00
|
|
|
// instance_id is the generic term used so that users can have access to the
|
|
|
|
// instance id inside of the provisioners, used in step_provision.
|
|
|
|
state.Put("instance_id", server_id)
|
2016-11-13 17:34:36 -05:00
|
|
|
|
|
|
|
state.Put("server_ip", server.Ips[0].Ip)
|
|
|
|
|
|
|
|
return multistep.ActionContinue
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *stepCreateServer) Cleanup(state multistep.StateBag) {
|
|
|
|
c := state.Get("config").(*Config)
|
|
|
|
ui := state.Get("ui").(packer.Ui)
|
|
|
|
|
|
|
|
ui.Say("Removing Server...")
|
|
|
|
|
|
|
|
token := oneandone.SetToken(c.Token)
|
|
|
|
//Create an API client
|
|
|
|
api := oneandone.New(token, oneandone.BaseUrl)
|
|
|
|
|
2016-11-15 18:17:30 -05:00
|
|
|
var serverId string
|
|
|
|
if temp, ok := state.GetOk("server_id"); ok {
|
|
|
|
serverId = temp.(string)
|
2016-11-13 17:34:36 -05:00
|
|
|
}
|
|
|
|
|
2016-11-15 18:17:30 -05:00
|
|
|
if serverId != "" {
|
|
|
|
server, err := api.ShutdownServer(serverId, false)
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Error shutting down 1and1 server. Please destroy it manually: %s", serverId))
|
|
|
|
ui.Error(err.Error())
|
|
|
|
}
|
|
|
|
err = api.WaitForState(server, "POWERED_OFF", 10, c.Retries)
|
2019-10-28 11:25:48 -04:00
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf(
|
|
|
|
"Error waiting for 1and1 POWERED_OFF state. Please destroy it manually: %s",
|
|
|
|
serverId))
|
|
|
|
ui.Error(err.Error())
|
|
|
|
}
|
2016-11-13 17:34:36 -05:00
|
|
|
|
2019-10-28 11:25:48 -04:00
|
|
|
_, err = api.DeleteServer(server.Id, false)
|
2016-11-15 18:17:30 -05:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
ui.Error(fmt.Sprintf("Error deleting 1and1 server. Please destroy it manually: %s", serverId))
|
|
|
|
ui.Error(err.Error())
|
|
|
|
}
|
2016-11-13 17:34:36 -05:00
|
|
|
}
|
|
|
|
}
|