github.phpd.cn/hashicorp/packer@v1.3.2/builder/ncloud/step_create_public_ip_instance.go (about)

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