1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
package ncloud
import (
"context"
"fmt"
"log"
"time"
ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type StepCreatePublicIPInstance struct {
Conn *ncloud.Conn
CreatePublicIPInstance func(serverInstanceNo string) (*ncloud.PublicIPInstance, error)
WaiterAssociatePublicIPToServerInstance func(serverInstanceNo string, publicIP string) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepCreatePublicIPInstance(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepCreatePublicIPInstance {
var step = &StepCreatePublicIPInstance{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
step.CreatePublicIPInstance = step.createPublicIPInstance
step.WaiterAssociatePublicIPToServerInstance = step.waiterAssociatePublicIPToServerInstance
return step
}
func (s *StepCreatePublicIPInstance) waiterAssociatePublicIPToServerInstance(serverInstanceNo string, publicIP string) error {
reqParams := new(ncloud.RequestGetServerInstanceList)
reqParams.ServerInstanceNoList = []string{serverInstanceNo}
c1 := make(chan error, 1)
go func() {
for {
serverInstanceList, err := s.Conn.GetServerInstanceList(reqParams)
if err != nil {
c1 <- err
return
}
if publicIP == serverInstanceList.ServerInstanceList[0].PublicIP {
c1 <- nil
return
}
s.Say("Wait to associate public ip serverInstance")
time.Sleep(time.Second * 3)
}
}()
select {
case res := <-c1:
return res
case <-time.After(time.Second * 60):
return fmt.Errorf("TIMEOUT : association public ip[%s] to server instance[%s] Failed", publicIP, serverInstanceNo)
}
}
func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo string) (*ncloud.PublicIPInstance, error) {
reqParams := new(ncloud.RequestCreatePublicIPInstance)
reqParams.ServerInstanceNo = serverInstanceNo
publicIPInstanceList, err := s.Conn.CreatePublicIPInstance(reqParams)
if err != nil {
return nil, err
}
publicIPInstance := publicIPInstanceList.PublicIPInstanceList[0]
publicIP := publicIPInstance.PublicIP
s.Say(fmt.Sprintf("Public IP Instance [%s:%s] is created", publicIPInstance.PublicIPInstanceNo, publicIP))
err = s.waiterAssociatePublicIPToServerInstance(serverInstanceNo, publicIP)
return &publicIPInstance, nil
}
func (s *StepCreatePublicIPInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create Public IP Instance")
serverInstanceNo := state.Get("InstanceNo").(string)
publicIPInstance, err := s.CreatePublicIPInstance(serverInstanceNo)
if err == nil {
state.Put("PublicIP", publicIPInstance.PublicIP)
state.Put("PublicIPInstance", publicIPInstance)
}
return processStepResult(err, s.Error, state)
}
func (s *StepCreatePublicIPInstance) Cleanup(state multistep.StateBag) {
publicIPInstance, ok := state.GetOk("PublicIPInstance")
if !ok {
return
}
s.Say("Clean up Public IP Instance")
publicIPInstanceNo := publicIPInstance.(*ncloud.PublicIPInstance).PublicIPInstanceNo
s.waitPublicIPInstanceStatus(publicIPInstanceNo, "USED")
log.Println("Disassociate Public IP Instance ", publicIPInstanceNo)
s.Conn.DisassociatePublicIP(publicIPInstanceNo)
s.waitPublicIPInstanceStatus(publicIPInstanceNo, "CREAT")
reqParams := new(ncloud.RequestDeletePublicIPInstances)
reqParams.PublicIPInstanceNoList = []string{publicIPInstanceNo}
log.Println("Delete Public IP Instance ", publicIPInstanceNo)
s.Conn.DeletePublicIPInstances(reqParams)
}
func (s *StepCreatePublicIPInstance) waitPublicIPInstanceStatus(publicIPInstanceNo string, status string) {
c1 := make(chan error, 1)
go func() {
reqParams := new(ncloud.RequestPublicIPInstanceList)
reqParams.PublicIPInstanceNoList = []string{publicIPInstanceNo}
for {
resp, err := s.Conn.GetPublicIPInstanceList(reqParams)
if err != nil {
log.Printf(err.Error())
c1 <- err
return
}
if resp.TotalRows == 0 {
c1 <- nil
return
}
instance := resp.PublicIPInstanceList[0]
if instance.PublicIPInstanceStatus.Code == status && instance.PublicIPInstanceOperation.Code == "NULL" {
c1 <- nil
return
}
time.Sleep(time.Second * 2)
}
}()
select {
case <-c1:
return
case <-time.After(time.Second * 60):
return
}
}
|