packer-cn/builder/oneandone/step_create_server.go

143 lines
3.3 KiB
Go
Raw Permalink Normal View History

2016-11-13 17:34:36 -05:00
package oneandone
import (
"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"
2020-12-17 16:29:25 -05:00
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
2016-11-13 17:34:36 -05:00
)
type stepCreateServer struct{}
func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packersdk.Ui)
2016-11-13 17:34:36 -05:00
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
}
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)
// 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").(packersdk.Ui)
2016-11-13 17:34:36 -05:00
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
}
}