2018-01-11 04:57:53 -05:00
|
|
|
package ncloud
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2018-01-29 08:41:22 -05:00
|
|
|
"context"
|
2018-01-11 04:57:53 -05:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
|
|
|
|
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
|
2020-11-17 19:31:03 -05:00
|
|
|
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
|
2020-11-19 14:54:31 -05:00
|
|
|
packersdk "github.com/hashicorp/packer/packer-plugin-sdk/packer"
|
2018-01-11 04:57:53 -05:00
|
|
|
"github.com/olekukonko/tablewriter"
|
|
|
|
)
|
|
|
|
|
2018-03-13 23:24:51 -04:00
|
|
|
//StepValidateTemplate : struct for Validation a template
|
2018-01-11 04:57:53 -05:00
|
|
|
type StepValidateTemplate struct {
|
2020-02-03 08:55:01 -05:00
|
|
|
Conn *NcloudAPIClient
|
2018-01-29 04:35:43 -05:00
|
|
|
Validate func() error
|
|
|
|
Say func(message string)
|
|
|
|
Error func(e error)
|
|
|
|
Config *Config
|
|
|
|
zoneNo string
|
|
|
|
regionNo string
|
|
|
|
FeeSystemTypeCode string
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
2018-03-13 23:24:51 -04:00
|
|
|
// NewStepValidateTemplate : function for Validation a template
|
2020-11-19 14:54:31 -05:00
|
|
|
func NewStepValidateTemplate(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepValidateTemplate {
|
2018-01-11 04:57:53 -05:00
|
|
|
var step = &StepValidateTemplate{
|
|
|
|
Conn: conn,
|
|
|
|
Say: func(message string) { ui.Say(message) },
|
|
|
|
Error: func(e error) { ui.Error(e.Error()) },
|
|
|
|
Config: config,
|
|
|
|
}
|
|
|
|
|
|
|
|
step.Validate = step.validateTemplate
|
|
|
|
|
|
|
|
return step
|
|
|
|
}
|
|
|
|
|
|
|
|
// getZoneNo : get zoneNo
|
|
|
|
func (s *StepValidateTemplate) getZoneNo() error {
|
|
|
|
if s.Config.Region == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
regionList, err := s.Conn.server.V2Api.GetRegionList(&server.GetRegionListRequest{})
|
2018-01-11 04:57:53 -05:00
|
|
|
if err != nil {
|
2018-01-11 20:12:47 -05:00
|
|
|
return err
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
var regionNo string
|
|
|
|
for _, region := range regionList.RegionList {
|
2020-02-03 08:55:01 -05:00
|
|
|
if strings.EqualFold(*region.RegionName, s.Config.Region) {
|
|
|
|
regionNo = *region.RegionNo
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if regionNo == "" {
|
|
|
|
return fmt.Errorf("region %s is invalid", s.Config.Region)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.regionNo = regionNo
|
|
|
|
|
|
|
|
// Get ZoneNo
|
2020-02-03 08:55:01 -05:00
|
|
|
resp, err := s.Conn.server.V2Api.GetZoneList(&server.GetZoneListRequest{RegionNo: ®ionNo})
|
2018-01-11 04:57:53 -05:00
|
|
|
if err != nil {
|
2018-01-11 20:12:47 -05:00
|
|
|
return err
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
if len(resp.ZoneList) > 0 {
|
|
|
|
s.zoneNo = *resp.ZoneList[0].ZoneNo
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *StepValidateTemplate) validateMemberServerImage() error {
|
|
|
|
var serverImageName = s.Config.ServerImageName
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
reqParams := new(server.GetMemberServerImageListRequest)
|
|
|
|
reqParams.RegionNo = &s.regionNo
|
2018-01-11 04:57:53 -05:00
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
memberServerImageList, err := s.Conn.server.V2Api.GetMemberServerImageList(reqParams)
|
2018-01-11 04:57:53 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var isExistMemberServerImageNo = false
|
|
|
|
for _, image := range memberServerImageList.MemberServerImageList {
|
|
|
|
// Check duplicate server_image_name
|
2020-02-03 08:55:01 -05:00
|
|
|
if *image.MemberServerImageName == serverImageName {
|
2018-01-11 04:57:53 -05:00
|
|
|
return fmt.Errorf("server_image_name %s is exists", serverImageName)
|
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
if *image.MemberServerImageNo == s.Config.MemberServerImageNo {
|
2018-01-11 04:57:53 -05:00
|
|
|
isExistMemberServerImageNo = true
|
|
|
|
if s.Config.ServerProductCode == "" {
|
2020-02-03 08:55:01 -05:00
|
|
|
s.Config.ServerProductCode = *image.OriginalServerProductCode
|
|
|
|
s.Say("server_product_code for member server image '" + *image.OriginalServerProductCode + "' is configured automatically")
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
2020-02-03 08:55:01 -05:00
|
|
|
s.Config.ServerImageProductCode = *image.OriginalServerImageProductCode
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if s.Config.MemberServerImageNo != "" && !isExistMemberServerImageNo {
|
|
|
|
return fmt.Errorf("member_server_image_no %s does not exist", s.Config.MemberServerImageNo)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *StepValidateTemplate) validateServerImageProduct() error {
|
|
|
|
var serverImageProductCode = s.Config.ServerImageProductCode
|
|
|
|
if serverImageProductCode == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
reqParams := new(server.GetServerImageProductListRequest)
|
|
|
|
reqParams.RegionNo = &s.regionNo
|
2018-01-11 04:57:53 -05:00
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
serverImageProductList, err := s.Conn.server.V2Api.GetServerImageProductList(reqParams)
|
2018-01-11 04:57:53 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var isExistServerImage = false
|
|
|
|
var buf bytes.Buffer
|
|
|
|
var productName string
|
|
|
|
table := tablewriter.NewWriter(&buf)
|
|
|
|
table.SetHeader([]string{"Name", "Code"})
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
for _, product := range serverImageProductList.ProductList {
|
2018-01-11 04:57:53 -05:00
|
|
|
// Check exist server image product code
|
2020-02-03 08:55:01 -05:00
|
|
|
if *product.ProductCode == serverImageProductCode {
|
2018-01-11 04:57:53 -05:00
|
|
|
isExistServerImage = true
|
2020-02-03 08:55:01 -05:00
|
|
|
productName = *product.ProductName
|
2018-01-11 04:57:53 -05:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
table.Append([]string{*product.ProductName, *product.ProductCode})
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if !isExistServerImage {
|
2020-02-03 08:55:01 -05:00
|
|
|
reqParams.BlockStorageSize = ncloud.Int32(100)
|
2018-01-11 04:57:53 -05:00
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
serverImageProductList, err := s.Conn.server.V2Api.GetServerImageProductList(reqParams)
|
2018-01-11 04:57:53 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
for _, product := range serverImageProductList.ProductList {
|
2018-01-11 04:57:53 -05:00
|
|
|
// Check exist server image product code
|
2020-02-03 08:55:01 -05:00
|
|
|
if *product.ProductCode == serverImageProductCode {
|
2018-01-11 04:57:53 -05:00
|
|
|
isExistServerImage = true
|
2020-02-03 08:55:01 -05:00
|
|
|
productName = *product.ProductName
|
2018-01-11 04:57:53 -05:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
table.Append([]string{*product.ProductName, *product.ProductCode})
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !isExistServerImage {
|
|
|
|
table.Render()
|
|
|
|
s.Say(buf.String())
|
|
|
|
|
|
|
|
return fmt.Errorf("server_image_product_code %s does not exist", serverImageProductCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.Contains(productName, "mssql") {
|
2018-01-29 04:35:43 -05:00
|
|
|
s.FeeSystemTypeCode = "FXSUM"
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *StepValidateTemplate) validateServerProductCode() error {
|
|
|
|
var serverImageProductCode = s.Config.ServerImageProductCode
|
|
|
|
var productCode = s.Config.ServerProductCode
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
reqParams := new(server.GetServerProductListRequest)
|
|
|
|
reqParams.ServerImageProductCode = &serverImageProductCode
|
|
|
|
reqParams.RegionNo = &s.regionNo
|
2018-01-11 04:57:53 -05:00
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
resp, err := s.Conn.server.V2Api.GetServerProductList(reqParams)
|
2018-01-11 04:57:53 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var isExistProductCode = false
|
2020-02-03 08:55:01 -05:00
|
|
|
for _, product := range resp.ProductList {
|
2018-01-11 04:57:53 -05:00
|
|
|
// Check exist server image product code
|
2020-02-03 08:55:01 -05:00
|
|
|
if *product.ProductCode == productCode {
|
2018-01-11 04:57:53 -05:00
|
|
|
isExistProductCode = true
|
2020-02-03 08:55:01 -05:00
|
|
|
if strings.Contains(*product.ProductName, "mssql") {
|
2018-01-29 04:35:43 -05:00
|
|
|
s.FeeSystemTypeCode = "FXSUM"
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
|
2020-02-03 08:55:01 -05:00
|
|
|
if *product.ProductType.Code == "VDS" {
|
2018-01-11 04:57:53 -05:00
|
|
|
return errors.New("You cannot create my server image for VDS servers")
|
|
|
|
}
|
|
|
|
|
|
|
|
break
|
2020-02-03 08:55:01 -05:00
|
|
|
} else if productCode == "" && *product.ProductType.Code == "STAND" {
|
2018-01-11 04:57:53 -05:00
|
|
|
isExistProductCode = true
|
2020-02-03 08:55:01 -05:00
|
|
|
s.Config.ServerProductCode = *product.ProductCode
|
|
|
|
s.Say("server_product_code '" + *product.ProductCode + "' is configured automatically")
|
2018-01-11 04:57:53 -05:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !isExistProductCode {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
table := tablewriter.NewWriter(&buf)
|
|
|
|
table.SetHeader([]string{"Name", "Code"})
|
2020-02-03 08:55:01 -05:00
|
|
|
for _, product := range resp.ProductList {
|
|
|
|
table.Append([]string{*product.ProductName, *product.ProductCode})
|
2018-01-11 04:57:53 -05:00
|
|
|
}
|
|
|
|
table.Render()
|
|
|
|
|
|
|
|
s.Say(buf.String())
|
|
|
|
|
|
|
|
return fmt.Errorf("server_product_code %s does not exist", productCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check ImageName / Product Code / Server Image Product Code / Server Product Code...
|
|
|
|
func (s *StepValidateTemplate) validateTemplate() error {
|
|
|
|
// Get RegionNo, ZoneNo
|
|
|
|
if err := s.getZoneNo(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate member_server_image_no and member_server_image_no
|
|
|
|
if err := s.validateMemberServerImage(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate server_image_product_code
|
|
|
|
if err := s.validateServerImageProduct(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate server_product_code
|
|
|
|
return s.validateServerProductCode()
|
|
|
|
}
|
|
|
|
|
2018-03-13 03:52:02 -04:00
|
|
|
// Run : main function for validation a template
|
2019-03-29 11:50:02 -04:00
|
|
|
func (s *StepValidateTemplate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
2018-01-11 04:57:53 -05:00
|
|
|
s.Say("Validating deployment template ...")
|
|
|
|
|
|
|
|
err := s.Validate()
|
|
|
|
|
|
|
|
state.Put("ZoneNo", s.zoneNo)
|
|
|
|
|
2018-01-29 04:35:43 -05:00
|
|
|
if s.FeeSystemTypeCode != "" {
|
|
|
|
state.Put("FeeSystemTypeCode", s.FeeSystemTypeCode)
|
|
|
|
}
|
|
|
|
|
2018-01-11 04:57:53 -05:00
|
|
|
return processStepResult(err, s.Error, state)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cleanup : cleanup on error
|
|
|
|
func (s *StepValidateTemplate) Cleanup(multistep.StateBag) {
|
|
|
|
}
|