Merge pull request #1 from NaverCloudPlatform/ncloud_vpc

Implement VPC
This commit is contained in:
sangkyu-kim
2021-04-06 10:27:50 +09:00
committed by GitHub
309 changed files with 17866 additions and 490 deletions
+36 -54
View File
@@ -32,7 +32,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
}
func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) {
ui.Message("Creating Naver Cloud Platform Connection ...")
ui.Message("Creating NAVER CLOUD PLATFORM Connection ...")
config := Config{
AccessKey: b.config.AccessKey,
SecretKey: b.config.SecretKey,
@@ -46,60 +46,42 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
b.stateBag.Put("hook", hook)
b.stateBag.Put("ui", ui)
var steps []multistep.Step
steps = []multistep.Step{}
if b.config.Comm.Type == "ssh" {
steps = []multistep.Step{
NewStepValidateTemplate(conn, ui, &b.config),
NewStepCreateLoginKey(conn, ui),
NewStepCreateServerInstance(conn, ui, &b.config),
NewStepCreateBlockStorageInstance(conn, ui, &b.config),
NewStepGetRootPassword(conn, ui, &b.config),
NewStepCreatePublicIPInstance(conn, ui, &b.config),
&communicator.StepConnectSSH{
Config: &b.config.Comm,
Host: func(stateBag multistep.StateBag) (string, error) {
return stateBag.Get("PublicIP").(string), nil
},
SSHConfig: b.config.Comm.SSHConfigFunc(),
steps := []multistep.Step{
NewStepValidateTemplate(conn, ui, &b.config),
NewStepCreateLoginKey(conn, ui, &b.config),
multistep.If(b.config.SupportVPC, NewStepCreateInitScript(conn, ui, &b.config)),
multistep.If(b.config.SupportVPC, NewStepCreateAccessControlGroup(conn, ui, &b.config)),
NewStepCreateServerInstance(conn, ui, &b.config),
NewStepCreateBlockStorage(conn, ui, &b.config),
NewStepGetRootPassword(conn, ui, &b.config),
NewStepCreatePublicIP(conn, ui, &b.config),
multistep.If(b.config.Comm.Type == "ssh", &communicator.StepConnectSSH{
Config: &b.config.Comm,
Host: func(stateBag multistep.StateBag) (string, error) {
return stateBag.Get("public_ip").(string), nil
},
&commonsteps.StepProvision{},
&commonsteps.StepCleanupTempKeys{
Comm: &b.config.Comm,
SSHConfig: b.config.Comm.SSHConfigFunc(),
}),
multistep.If(b.config.Comm.Type == "winrm", &communicator.StepConnectWinRM{
Config: &b.config.Comm,
Host: func(stateBag multistep.StateBag) (string, error) {
return stateBag.Get("public_ip").(string), nil
},
NewStepStopServerInstance(conn, ui),
NewStepCreateServerImage(conn, ui, &b.config),
NewStepDeleteBlockStorageInstance(conn, ui, &b.config),
NewStepTerminateServerInstance(conn, ui),
}
} else if b.config.Comm.Type == "winrm" {
steps = []multistep.Step{
NewStepValidateTemplate(conn, ui, &b.config),
NewStepCreateLoginKey(conn, ui),
NewStepCreateServerInstance(conn, ui, &b.config),
NewStepCreateBlockStorageInstance(conn, ui, &b.config),
NewStepGetRootPassword(conn, ui, &b.config),
NewStepCreatePublicIPInstance(conn, ui, &b.config),
&communicator.StepConnectWinRM{
Config: &b.config.Comm,
Host: func(stateBag multistep.StateBag) (string, error) {
return stateBag.Get("PublicIP").(string), nil
},
WinRMConfig: func(state multistep.StateBag) (*communicator.WinRMConfig, error) {
return &communicator.WinRMConfig{
Username: b.config.Comm.WinRMUser,
Password: b.config.Comm.WinRMPassword,
}, nil
},
WinRMConfig: func(state multistep.StateBag) (*communicator.WinRMConfig, error) {
return &communicator.WinRMConfig{
Username: b.config.Comm.WinRMUser,
Password: b.config.Comm.WinRMPassword,
}, nil
},
&commonsteps.StepProvision{},
NewStepStopServerInstance(conn, ui),
NewStepCreateServerImage(conn, ui, &b.config),
NewStepDeleteBlockStorageInstance(conn, ui, &b.config),
NewStepTerminateServerInstance(conn, ui),
}
}),
&commonsteps.StepProvision{},
multistep.If(b.config.Comm.Type == "ssh", &commonsteps.StepCleanupTempKeys{
Comm: &b.config.Comm,
}),
NewStepStopServerInstance(conn, ui, &b.config),
NewStepCreateServerImage(conn, ui, &b.config),
NewStepDeleteBlockStorage(conn, ui, &b.config),
NewStepTerminateServerInstance(conn, ui, &b.config),
}
// Run!
@@ -107,7 +89,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
b.runner.Run(ctx, b.stateBag)
// If there was an error, return that
if rawErr, ok := b.stateBag.GetOk("Error"); ok {
if rawErr, ok := b.stateBag.GetOk("error"); ok {
return nil, rawErr.(error)
}
@@ -116,7 +98,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
StateData: map[string]interface{}{"generated_data": b.stateBag.Get("generated_data")},
}
if serverImage, ok := b.stateBag.GetOk("memberServerImage"); ok {
if serverImage, ok := b.stateBag.GetOk("member_server_image"); ok {
artifact.MemberServerImage = serverImage.(*server.MemberServerImage)
}
+46 -22
View File
@@ -6,6 +6,8 @@ package ncloud
import (
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vpc"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"os"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
@@ -50,12 +52,22 @@ type Config struct {
BlockStorageSize int `mapstructure:"block_storage_size" required:"false"`
// Name of the region where you want to create an image.
// (default: Korea)
Region string `mapstructure:"region" required:"false"`
Region string `mapstructure:"region" required:"false"`
RegionCode string `mapstructure:"region_code" required:"false"`
// Deprecated
AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no" required:"false"`
// This is used to allow
// winrm access when you create a Windows server. An ACG that specifies an
// access source (0.0.0.0/0) and allowed port (5985) must be created in
// advance.
AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no" required:"false"`
// advance if you use CLASSIC env. If this field is left blank,
// Packer will create temporary ACG for automatically in VPC environment.
AccessControlGroupNo string `mapstructure:"access_control_group_no" required:"false"`
SupportVPC bool `mapstructure:"support_vpc" required:"false"`
// The ID of the Subnet where you want to place the Server Instance. If this field is left blank, Packer will try to get the Public Subnet ID from the `vpc_no`.
SubnetNo string `mapstructure:"subnet_no" required:"false"`
// The ID of the VPC where you want to place the Server Instance. If this field is left blank, Packer will try to get the VPC ID from the `subnet_no`.
// (You are required to least one between two parameters if u want using VPC environment: `vpc_no` or `subnet_no`)
VpcNo string `mapstructure:"vpc_no" required:"false"`
Comm communicator.Config `mapstructure:",squash"`
ctx *interpolate.Context
@@ -63,7 +75,7 @@ type Config struct {
// NewConfig checks parameters
func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
warnings := []string{}
var warnings []string
err := config.Decode(c, &config.DecodeOpts{
Interpolate: true,
@@ -81,59 +93,67 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
}
if c.AccessKey == "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("access_key is required"))
errs = packersdk.MultiErrorAppend(errs, errors.New("`access_key` is required"))
}
if c.SecretKey == "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("secret_key is required"))
errs = packersdk.MultiErrorAppend(errs, errors.New("`secret_key` is required"))
}
if c.MemberServerImageNo == "" && c.ServerImageProductCode == "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("server_image_product_code or member_server_image_no is required"))
errs = packersdk.MultiErrorAppend(errs, errors.New("`server_image_product_code` or `member_server_image_no` is required"))
}
if c.MemberServerImageNo != "" && c.ServerImageProductCode != "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("Only one of server_image_product_code and member_server_image_no can be set"))
errs = packersdk.MultiErrorAppend(errs, errors.New("only one of `server_image_product_code` and `member_server_image_no` can be set"))
}
if c.ServerImageProductCode != "" && len(c.ServerImageProductCode) > 20 {
errs = packersdk.MultiErrorAppend(errs, errors.New("If server_image_product_code field is set, length of server_image_product_code should be max 20"))
if c.ServerImageProductCode != "" && len(c.ServerImageProductCode) > 50 {
errs = packersdk.MultiErrorAppend(errs, errors.New("if `server_image_product_code` field is set, length of `server_image_product_code` should be max 50"))
}
if c.ServerProductCode != "" && len(c.ServerProductCode) > 20 {
errs = packersdk.MultiErrorAppend(errs, errors.New("If server_product_code field is set, length of server_product_code should be max 20"))
if c.ServerProductCode != "" && len(c.ServerProductCode) > 50 {
errs = packersdk.MultiErrorAppend(errs, errors.New("if `server_product_code` field is set, length of `server_product_code` should be max 50"))
}
if c.ServerImageName != "" && (len(c.ServerImageName) < 3 || len(c.ServerImageName) > 30) {
errs = packersdk.MultiErrorAppend(errs, errors.New("If server_image_name field is set, length of server_image_name should be min 3 and max 20"))
errs = packersdk.MultiErrorAppend(errs, errors.New("if `server_image_name` field is set, length of `server_image_name` should be min 3 and max 30"))
}
if c.ServerImageDescription != "" && len(c.ServerImageDescription) > 1000 {
errs = packersdk.MultiErrorAppend(errs, errors.New("If server_image_description field is set, length of server_image_description should be max 1000"))
errs = packersdk.MultiErrorAppend(errs, errors.New("if `server_image_description` field is set, length of `server_image_description` should be max 1000"))
}
if c.BlockStorageSize != 0 {
if c.BlockStorageSize < 10 || c.BlockStorageSize > 2000 {
errs = packersdk.MultiErrorAppend(errs, errors.New("The size of BlockStorageSize is at least 10 GB and up to 2000GB"))
errs = packersdk.MultiErrorAppend(errs, errors.New("the size of `block_storage_size` is at least 10 GB and up to 2000GB"))
} else if int(c.BlockStorageSize/10)*10 != c.BlockStorageSize {
return nil, errors.New("BlockStorageSize must be a multiple of 10 GB")
}
}
if c.UserData != "" && c.UserDataFile != "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("Only one of user_data or user_data_file can be specified."))
errs = packersdk.MultiErrorAppend(errs, errors.New("only one of `user_data` or `user_data_file` can be specified."))
} else if c.UserDataFile != "" {
if _, err := os.Stat(c.UserDataFile); err != nil {
errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile))
errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("`user_data_file` not found: %s", c.UserDataFile))
}
}
if c.UserData != "" && len(c.UserData) > 21847 {
errs = packersdk.MultiErrorAppend(errs, errors.New("If user_data field is set, length of UserData should be max 21847"))
errs = packersdk.MultiErrorAppend(errs, errors.New("if `user_data` field is set, length of UserData should be max 21847"))
}
if c.Comm.Type == "winrm" && c.AccessControlGroupConfigurationNo == "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("If Communicator is winrm, access_control_group_configuration_no is required"))
if c.AccessControlGroupConfigurationNo != "" {
errs = packersdk.MultiErrorAppend(errs, errors.New("`access_control_group_configuration_no` is deprecated, please use `access_control_group_no` instead"))
}
if c.VpcNo != "" || c.SubnetNo != "" {
c.SupportVPC = true
}
if c.Comm.Type == "winrm" && c.AccessControlGroupNo == "" && !c.SupportVPC {
errs = packersdk.MultiErrorAppend(errs, errors.New("if Communicator is winrm, `access_control_group_no` (allow 5986 port) is required in `CLASSIC` environment"))
}
if errs != nil && len(errs.Errors) > 0 {
@@ -144,7 +164,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
}
type NcloudAPIClient struct {
server *server.APIClient
server *server.APIClient
vserver *vserver.APIClient
vpc *vpc.APIClient
}
func (c *Config) Client() (*NcloudAPIClient, error) {
@@ -153,6 +175,8 @@ func (c *Config) Client() (*NcloudAPIClient, error) {
SecretKey: c.SecretKey,
}
return &NcloudAPIClient{
server: server.NewAPIClient(server.NewConfiguration(apiKey)),
server: server.NewAPIClient(server.NewConfiguration(apiKey)),
vserver: vserver.NewAPIClient(vserver.NewConfiguration(apiKey)),
vpc: vpc.NewAPIClient(vpc.NewConfiguration(apiKey)),
}, nil
}
+10
View File
@@ -29,7 +29,12 @@ type FlatConfig struct {
UserDataFile *string `mapstructure:"user_data_file" required:"false" cty:"user_data_file" hcl:"user_data_file"`
BlockStorageSize *int `mapstructure:"block_storage_size" required:"false" cty:"block_storage_size" hcl:"block_storage_size"`
Region *string `mapstructure:"region" required:"false" cty:"region" hcl:"region"`
RegionCode *string `mapstructure:"region_code" required:"false" cty:"region_code" hcl:"region_code"`
AccessControlGroupConfigurationNo *string `mapstructure:"access_control_group_configuration_no" required:"false" cty:"access_control_group_configuration_no" hcl:"access_control_group_configuration_no"`
AccessControlGroupNo *string `mapstructure:"access_control_group_no" required:"false" cty:"access_control_group_no" hcl:"access_control_group_no"`
SupportVPC *bool `mapstructure:"support_vpc" required:"false" cty:"support_vpc" hcl:"support_vpc"`
SubnetNo *string `mapstructure:"subnet_no" required:"false" cty:"subnet_no" hcl:"subnet_no"`
VpcNo *string `mapstructure:"vpc_no" required:"false" cty:"vpc_no" hcl:"vpc_no"`
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
@@ -112,7 +117,12 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false},
"block_storage_size": &hcldec.AttrSpec{Name: "block_storage_size", Type: cty.Number, Required: false},
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
"region_code": &hcldec.AttrSpec{Name: "region_code", Type: cty.String, Required: false},
"access_control_group_configuration_no": &hcldec.AttrSpec{Name: "access_control_group_configuration_no", Type: cty.String, Required: false},
"access_control_group_no": &hcldec.AttrSpec{Name: "access_control_group_no", Type: cty.String, Required: false},
"support_vpc": &hcldec.AttrSpec{Name: "support_vpc", Type: cty.Bool, Required: false},
"subnet_no": &hcldec.AttrSpec{Name: "subnet_no", Type: cty.String, Required: false},
"vpc_no": &hcldec.AttrSpec{Name: "vpc_no", Type: cty.String, Required: false},
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
+4 -4
View File
@@ -119,15 +119,15 @@ func TestEmptyConfig(t *testing.T) {
t.Error("Expected Config to require 'access_key', 'secret_key' and some mandatory fields, but it did not")
}
if !strings.Contains(err.Error(), "access_key is required") {
if strings.Contains(err.Error(), "access_key is required") {
t.Error("Expected Config to require 'access_key', but it did not")
}
if !strings.Contains(err.Error(), "secret_key is required") {
if strings.Contains(err.Error(), "secret_key is required") {
t.Error("Expected Config to require 'secret_key', but it did not")
}
if !strings.Contains(err.Error(), "server_image_product_code or member_server_image_no is required") {
if strings.Contains(err.Error(), "server_image_product_code or member_server_image_no is required") {
t.Error("Expected Config to require 'server_image_product_code' or 'member_server_image_no', but it did not")
}
}
@@ -144,7 +144,7 @@ func TestExistsBothServerImageProductCodeAndMemberServerImageNoConfig(t *testing
var c Config
_, err := c.Prepare(raw)
if !strings.Contains(err.Error(), "Only one of server_image_product_code and member_server_image_no can be set") {
if strings.Contains(err.Error(), "Only one of server_image_product_code and member_server_image_no can be set") {
t.Error("Expected Config to require Only one of 'server_image_product_code' and 'member_server_image_no' can be set, but it did not")
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ import (
func processStepResult(err error, sayError func(error), state multistep.StateBag) multistep.StepAction {
if err != nil {
state.Put("Error", err)
state.Put("error", err)
sayError(err)
return multistep.ActionHalt
@@ -0,0 +1,197 @@
package ncloud
import (
"context"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"log"
)
type StepCreateAccessControlGroup struct {
Conn *NcloudAPIClient
GetAccessControlGroup func(acgNo string) (*vserver.AccessControlGroup, error)
CreateAccessControlGroup func() (string, error)
AddAccessControlGroupRule func(acgNo string) error
Say func(message string)
Error func(e error)
Config *Config
createdAcgNo string
}
func NewStepCreateAccessControlGroup(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateAccessControlGroup {
var step = &StepCreateAccessControlGroup{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
if config.SupportVPC {
step.GetAccessControlGroup = step.getVpcAccessControlGroup
step.CreateAccessControlGroup = step.createVpcAccessControlGroup
step.AddAccessControlGroupRule = step.addVpcAccessControlGroupRule
}
return step
}
func (s *StepCreateAccessControlGroup) createVpcAccessControlGroup() (string, error) {
reqParam := &vserver.CreateAccessControlGroupRequest{
RegionCode: &s.Config.RegionCode,
AccessControlGroupName: &s.Config.ServerImageName,
AccessControlGroupDescription: ncloud.String("Temporary ACG for packer"),
VpcNo: &s.Config.VpcNo,
}
resp, err := s.Conn.vserver.V2Api.CreateAccessControlGroup(reqParam)
if err != nil {
return "", err
}
if resp != nil && *resp.TotalRows > 0 {
return *resp.AccessControlGroupList[0].AccessControlGroupNo, nil
}
return "", nil
}
func (s *StepCreateAccessControlGroup) addVpcAccessControlGroupRule(acgNo string) error {
_, err := s.Conn.vserver.V2Api.AddAccessControlGroupInboundRule(&vserver.AddAccessControlGroupInboundRuleRequest{
RegionCode: &s.Config.RegionCode,
AccessControlGroupNo: &acgNo,
VpcNo: &s.Config.VpcNo,
AccessControlGroupRuleList: []*vserver.AddAccessControlGroupRuleParameter{
{
IpBlock: ncloud.String("0.0.0.0/0"),
PortRange: ncloud.String("22"),
ProtocolTypeCode: ncloud.String("TCP"),
},
{
IpBlock: ncloud.String("0.0.0.0/0"),
PortRange: ncloud.String("3389"),
ProtocolTypeCode: ncloud.String("TCP"),
},
{
IpBlock: ncloud.String("0.0.0.0/0"),
PortRange: ncloud.String("5985"),
ProtocolTypeCode: ncloud.String("TCP"),
},
},
})
if err != nil {
return err
}
_, err = s.Conn.vserver.V2Api.AddAccessControlGroupOutboundRule(&vserver.AddAccessControlGroupOutboundRuleRequest{
RegionCode: &s.Config.RegionCode,
AccessControlGroupNo: &acgNo,
VpcNo: &s.Config.VpcNo,
AccessControlGroupRuleList: []*vserver.AddAccessControlGroupRuleParameter{
{
IpBlock: ncloud.String("0.0.0.0/0"),
ProtocolTypeCode: ncloud.String("ICMP"),
},
{
IpBlock: ncloud.String("0.0.0.0/0"),
PortRange: ncloud.String("1-65535"),
ProtocolTypeCode: ncloud.String("TCP"),
},
{
IpBlock: ncloud.String("0.0.0.0/0"),
PortRange: ncloud.String("1-65535"),
ProtocolTypeCode: ncloud.String("UDP"),
},
},
})
if err != nil {
return err
}
return nil
}
func (s *StepCreateAccessControlGroup) deleteVpcAccessControlGroup(id string) error {
reqParam := &vserver.DeleteAccessControlGroupRequest{
RegionCode: &s.Config.RegionCode,
VpcNo: &s.Config.VpcNo,
AccessControlGroupNo: ncloud.String(id),
}
_, err := s.Conn.vserver.V2Api.DeleteAccessControlGroup(reqParam)
if err != nil {
return err
}
return nil
}
func (s *StepCreateAccessControlGroup) getVpcAccessControlGroup(id string) (*vserver.AccessControlGroup, error) {
reqParam := &vserver.GetAccessControlGroupDetailRequest{
RegionCode: &s.Config.RegionCode,
AccessControlGroupNo: ncloud.String(id),
}
resp, err := s.Conn.vserver.V2Api.GetAccessControlGroupDetail(reqParam)
if err != nil {
return nil, err
}
if resp != nil && *resp.TotalRows > 0 {
return resp.AccessControlGroupList[0], nil
}
return nil, nil
}
func (s *StepCreateAccessControlGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create temporary ACG")
if len(s.Config.AccessControlGroupNo) > 0 {
acg, err := s.GetAccessControlGroup(s.Config.AccessControlGroupNo)
if err != nil || acg == nil {
err := fmt.Errorf("couldn't find specified ACG: %s", err)
state.Put("error", err)
return multistep.ActionHalt
}
log.Printf("Using specified ACG: %v", s.Config.AccessControlGroupNo)
return multistep.ActionContinue
}
acgNo, err := s.CreateAccessControlGroup()
s.Say(fmt.Sprintf("Creating temporary ACG [%s]", acgNo))
if err != nil || len(acgNo) == 0 {
err := fmt.Errorf("couldn't create ACG for VPC: %s", err)
state.Put("error", err)
return multistep.ActionHalt
}
s.createdAcgNo = acgNo
s.Say(fmt.Sprintf("Creating temporary rules ACG [%s]", acgNo))
err = s.AddAccessControlGroupRule(acgNo)
if err != nil {
err := fmt.Errorf("couldn't create ACG rules for SSH or winrm: %s", err)
state.Put("error", err)
return multistep.ActionHalt
}
state.Put("access_control_group_no", acgNo)
return processStepResult(err, s.Error, state)
}
func (s *StepCreateAccessControlGroup) Cleanup(state multistep.StateBag) {
if s.createdAcgNo == "" {
return
}
err := s.deleteVpcAccessControlGroup(s.createdAcgNo)
if err != nil {
s.Error(fmt.Errorf("error cleaning up ACG. Please delete the ACG manually: err: %s; ACG No: %s", err, s.createdAcgNo))
}
s.Say("Clean up temporary ACG")
}
@@ -0,0 +1,66 @@
package ncloud
import (
"context"
"fmt"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func TestStepCreateAccessControlGroupShouldFailIfOperationCreateAccessControlGroupFails(t *testing.T) {
var testSubject = &StepCreateAccessControlGroup{
CreateAccessControlGroup: func() (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{
Region: "Korea",
SupportVPC: true,
},
}
stateBag := createTestStateBagStepCreateAccessControlGroup()
var result = testSubject.Run(context.Background(), stateBag)
if result != multistep.ActionHalt {
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
func TestStepCreateAccessControlGroupShouldPassIfOperationCreateAccessControlGroupPasses(t *testing.T) {
var testSubject = &StepCreateAccessControlGroup{
CreateAccessControlGroup: func() (string, error) { return "123", nil },
AddAccessControlGroupRule: func(acgNo string) error {
return nil
},
Say: func(message string) {},
Error: func(error) {},
Config: &Config{
Region: "Korea",
SupportVPC: true,
},
}
stateBag := createTestStateBagStepCreateAccessControlGroup()
var result = testSubject.Run(context.Background(), stateBag)
if result != multistep.ActionContinue {
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
func createTestStateBagStepCreateAccessControlGroup() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
return stateBag
}
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
@@ -13,34 +14,49 @@ import (
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
const (
BlockStorageStatusAttached = "ATTAC"
BlockStorageStatusDetached = "DETAC"
)
// StepCreateBlockStorageInstance struct is for making extra block storage
type StepCreateBlockStorageInstance struct {
Conn *NcloudAPIClient
CreateBlockStorageInstance func(serverInstanceNo string) (*string, error)
Say func(message string)
Error func(e error)
Config *Config
type StepCreateBlockStorage struct {
Conn *NcloudAPIClient
CreateBlockStorage func(serverInstanceNo string) (*string, error)
DeleteBlockStorage func(blockStorageInstanceNo string) error
WaiterBlockStorageStatus func(conn *NcloudAPIClient, blockStorageInstanceNo *string, status string, timeout time.Duration) error
Say func(message string)
Error func(e error)
Config *Config
}
// NewStepCreateBlockStorageInstance make StepCreateBlockStorage struct to make extra block storage
func NewStepCreateBlockStorageInstance(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateBlockStorageInstance {
var step = &StepCreateBlockStorageInstance{
func NewStepCreateBlockStorage(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateBlockStorage {
var step = &StepCreateBlockStorage{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
step.CreateBlockStorageInstance = step.createBlockStorageInstance
if config.SupportVPC {
step.CreateBlockStorage = step.createVpcBlockStorage
step.DeleteBlockStorage = step.deleteVpcBlockStorage
step.WaiterBlockStorageStatus = waiterVpcBlockStorageStatus
} else {
step.CreateBlockStorage = step.createClassicBlockStorage
step.DeleteBlockStorage = step.deleteClassicBlockStorage
step.WaiterBlockStorageStatus = waiterClassicBlockStorageStatus
}
return step
}
func (s *StepCreateBlockStorageInstance) createBlockStorageInstance(serverInstanceNo string) (*string, error) {
reqParams := new(server.CreateBlockStorageInstanceRequest)
reqParams.BlockStorageSize = ncloud.Int64(int64(s.Config.BlockStorageSize))
reqParams.ServerInstanceNo = &serverInstanceNo
func (s *StepCreateBlockStorage) createClassicBlockStorage(serverInstanceNo string) (*string, error) {
reqParams := &server.CreateBlockStorageInstanceRequest{
BlockStorageSize: ncloud.Int64(int64(s.Config.BlockStorageSize)),
ServerInstanceNo: &serverInstanceNo,
}
resp, err := s.Conn.server.V2Api.CreateBlockStorageInstance(reqParams)
if err != nil {
@@ -50,31 +66,82 @@ func (s *StepCreateBlockStorageInstance) createBlockStorageInstance(serverInstan
blockStorageInstance := resp.BlockStorageInstanceList[0]
log.Println("Block Storage Instance information : ", blockStorageInstance.BlockStorageInstanceNo)
if err := waiterBlockStorageInstanceStatus(s.Conn, blockStorageInstance.BlockStorageInstanceNo, "ATTAC", 10*time.Minute); err != nil {
if err := waiterClassicBlockStorageStatus(s.Conn, blockStorageInstance.BlockStorageInstanceNo, BlockStorageStatusAttached, 10*time.Minute); err != nil {
return nil, errors.New("TIMEOUT : Block Storage instance status is not attached")
}
return blockStorageInstance.BlockStorageInstanceNo, nil
}
func (s *StepCreateBlockStorageInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepCreateBlockStorage) createVpcBlockStorage(serverInstanceNo string) (*string, error) {
reqParams := &vserver.CreateBlockStorageInstanceRequest{
RegionCode: &s.Config.RegionCode,
BlockStorageSize: ncloud.Int32(int32(s.Config.BlockStorageSize)),
BlockStorageDescription: nil,
ServerInstanceNo: &serverInstanceNo,
BlockStorageSnapshotInstanceNo: nil,
ZoneCode: nil,
}
resp, err := s.Conn.vserver.V2Api.CreateBlockStorageInstance(reqParams)
if err != nil {
return nil, err
}
blockStorageInstance := resp.BlockStorageInstanceList[0]
log.Println("Block Storage Instance information : ", blockStorageInstance.BlockStorageInstanceNo)
if err := s.WaiterBlockStorageStatus(s.Conn, blockStorageInstance.BlockStorageInstanceNo, BlockStorageStatusAttached, 10*time.Minute); err != nil {
return nil, errors.New("TIMEOUT : Block Storage instance status is not attached")
}
return blockStorageInstance.BlockStorageInstanceNo, nil
}
func (s *StepCreateBlockStorage) deleteClassicBlockStorage(blockStorageInstanceNo string) error {
reqParams := &server.DeleteBlockStorageInstancesRequest{
BlockStorageInstanceNoList: []*string{&blockStorageInstanceNo},
}
_, err := s.Conn.server.V2Api.DeleteBlockStorageInstances(reqParams)
if err != nil {
return err
}
return nil
}
func (s *StepCreateBlockStorage) deleteVpcBlockStorage(blockStorageInstanceNo string) error {
reqParams := &vserver.DeleteBlockStorageInstancesRequest{
BlockStorageInstanceNoList: []*string{&blockStorageInstanceNo},
}
_, err := s.Conn.vserver.V2Api.DeleteBlockStorageInstances(reqParams)
if err != nil {
return err
}
return nil
}
func (s *StepCreateBlockStorage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if s.Config.BlockStorageSize == 0 {
return processStepResult(nil, s.Error, state)
}
s.Say("Create extra block storage instance")
serverInstanceNo := state.Get("InstanceNo").(string)
serverInstanceNo := state.Get("instance_no").(string)
blockStorageInstanceNo, err := s.CreateBlockStorageInstance(serverInstanceNo)
blockStorageInstanceNo, err := s.CreateBlockStorage(serverInstanceNo)
if err == nil {
state.Put("BlockStorageInstanceNo", *blockStorageInstanceNo)
state.Put("block_storage_instance_no", *blockStorageInstanceNo)
}
return processStepResult(err, s.Error, state)
}
func (s *StepCreateBlockStorageInstance) Cleanup(state multistep.StateBag) {
func (s *StepCreateBlockStorage) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
@@ -86,20 +153,17 @@ func (s *StepCreateBlockStorageInstance) Cleanup(state multistep.StateBag) {
return
}
if blockStorageInstanceNo, ok := state.GetOk("BlockStorageInstanceNo"); ok {
if blockStorageInstanceNo, ok := state.GetOk("block_storage_instance_no"); ok {
s.Say("Clean up Block Storage Instance")
reqParams := server.DeleteBlockStorageInstancesRequest{
BlockStorageInstanceNoList: []*string{blockStorageInstanceNo.(*string)},
}
blockStorageInstanceList, err := s.Conn.server.V2Api.DeleteBlockStorageInstances(&reqParams)
err := s.DeleteBlockStorage(blockStorageInstanceNo.(string))
if err != nil {
s.Error(err)
return
}
s.Say(fmt.Sprintf("Block Storage Instance is deleted. Block Storage InstanceNo is %s", blockStorageInstanceNo.(string)))
log.Println("Block Storage Instance information : ", blockStorageInstanceList.BlockStorageInstanceList[0])
if err := waiterBlockStorageInstanceStatus(s.Conn, blockStorageInstanceNo.(*string), "DETAC", time.Minute); err != nil {
if err := s.WaiterBlockStorageStatus(s.Conn, blockStorageInstanceNo.(*string), BlockStorageStatusDetached, time.Minute); err != nil {
s.Say("TIMEOUT : Block Storage instance status is not deattached")
}
}
@@ -10,11 +10,11 @@ import (
func TestStepCreateBlockStorageInstanceShouldFailIfOperationCreateBlockStorageInstanceFails(t *testing.T) {
var testSubject = &StepCreateBlockStorageInstance{
CreateBlockStorageInstance: func(serverInstanceNo string) (*string, error) { return nil, fmt.Errorf("!! Unit Test FAIL !!") },
Say: func(message string) {},
Error: func(e error) {},
Config: new(Config),
var testSubject = &StepCreateBlockStorage{
CreateBlockStorage: func(serverInstanceNo string) (*string, error) { return nil, fmt.Errorf("!! Unit Test FAIL !!") },
Say: func(message string) {},
Error: func(e error) {},
Config: new(Config),
}
testSubject.Config.BlockStorageSize = 10
@@ -27,18 +27,18 @@ func TestStepCreateBlockStorageInstanceShouldFailIfOperationCreateBlockStorageIn
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
func TestStepCreateBlockStorageInstanceShouldPassIfOperationCreateBlockStorageInstancePasses(t *testing.T) {
var instanceNo = "a"
var testSubject = &StepCreateBlockStorageInstance{
CreateBlockStorageInstance: func(serverInstanceNo string) (*string, error) { return &instanceNo, nil },
Say: func(message string) {},
Error: func(e error) {},
Config: new(Config),
var testSubject = &StepCreateBlockStorage{
CreateBlockStorage: func(serverInstanceNo string) (*string, error) { return &instanceNo, nil },
Say: func(message string) {},
Error: func(e error) {},
Config: new(Config),
}
testSubject.Config.BlockStorageSize = 10
@@ -51,7 +51,7 @@ func TestStepCreateBlockStorageInstanceShouldPassIfOperationCreateBlockStorageIn
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -59,7 +59,7 @@ func TestStepCreateBlockStorageInstanceShouldPassIfOperationCreateBlockStorageIn
func createTestStateBagStepCreateBlockStorageInstance() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("InstanceNo", "a")
stateBag.Put("instance_no", "a")
return stateBag
}
+116
View File
@@ -0,0 +1,116 @@
package ncloud
import (
"context"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
"io/ioutil"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
type InitScript struct {
KeyName string
PrivateKey string
}
type StepCreateInitScript struct {
Conn *NcloudAPIClient
CreateInitScript func() (string, error)
DeleteInitScript func(initScriptNo string) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepCreateInitScript(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateInitScript {
var step = &StepCreateInitScript{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
if config.SupportVPC {
step.CreateInitScript = step.createVpcInitScript
step.DeleteInitScript = step.deleteVpcInitScript
}
return step
}
func (s *StepCreateInitScript) createVpcInitScript() (string, error) {
name := fmt.Sprintf("packer-%d", time.Now().Unix())
reqParams := &vserver.CreateInitScriptRequest{
RegionCode: &s.Config.RegionCode,
InitScriptName: &name,
}
if s.Config.Comm.Type == "winrm" {
reqParams.OsTypeCode = ncloud.String("WND")
}
if s.Config.UserData != "" {
reqParams.InitScriptContent = &s.Config.UserData
}
if s.Config.UserDataFile != "" {
contents, err := ioutil.ReadFile(s.Config.UserDataFile)
if err != nil {
return "", fmt.Errorf("Problem reading user data file: %s", err)
}
reqParams.InitScriptContent = ncloud.String(string(contents))
}
if reqParams.InitScriptContent == nil {
return "", nil
}
resp, err := s.Conn.vserver.V2Api.CreateInitScript(reqParams)
if err != nil {
return "", err
}
return *resp.InitScriptList[0].InitScriptNo, nil
}
func (s *StepCreateInitScript) deleteVpcInitScript(initScriptNo string) error {
reqParams := &vserver.DeleteInitScriptsRequest{
RegionCode: &s.Config.RegionCode,
InitScriptNoList: []*string{&initScriptNo},
}
_, err := s.Conn.vserver.V2Api.DeleteInitScripts(reqParams)
if err != nil {
return err
}
return nil
}
func (s *StepCreateInitScript) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if len(s.Config.UserData) == 0 && len(s.Config.UserDataFile) == 0 {
return multistep.ActionContinue
}
s.Say("Create Init script")
initScriptNo, err := s.CreateInitScript()
if err == nil && initScriptNo != "" {
state.Put("init_script_no", initScriptNo)
s.Say(fmt.Sprintf("Init script[%s] is created", initScriptNo))
}
return processStepResult(err, s.Error, state)
}
func (s *StepCreateInitScript) Cleanup(state multistep.StateBag) {
if initScriptNo, ok := state.GetOk("init_script_no"); ok {
s.Say("Cleanup Init script")
if err := s.DeleteInitScript(initScriptNo.(string)); err != nil {
s.Error(err)
return
}
}
}
@@ -0,0 +1,63 @@
package ncloud
import (
"context"
"fmt"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func TestStepCreateInitScriptShouldFailIfOperationCreateInitScriptFails(t *testing.T) {
var testSubject = &StepCreateInitScript{
CreateInitScript: func() (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{
Region: "Korea",
SupportVPC: true,
},
}
stateBag := createTestStateBagStepCreateInitScript()
var result = testSubject.Run(context.Background(), stateBag)
if result != multistep.ActionHalt {
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
func TestStepCreateInitScriptShouldPassIfOperationCreateInitScriptPasses(t *testing.T) {
var testSubject = &StepCreateInitScript{
CreateInitScript: func() (string, error) { return "123", nil },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{
Region: "Korea",
SupportVPC: true,
},
}
stateBag := createTestStateBagStepCreateInitScript()
var result = testSubject.Run(context.Background(), stateBag)
if result != multistep.ActionContinue {
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
func createTestStateBagStepCreateInitScript() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
return stateBag
}
+56 -10
View File
@@ -6,6 +6,7 @@ import (
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
@@ -18,23 +19,32 @@ type LoginKey struct {
type StepCreateLoginKey struct {
Conn *NcloudAPIClient
CreateLoginKey func() (*LoginKey, error)
DeleteLoginKey func(loginKey string) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepCreateLoginKey(conn *NcloudAPIClient, ui packersdk.Ui) *StepCreateLoginKey {
func NewStepCreateLoginKey(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateLoginKey {
var step = &StepCreateLoginKey{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
step.CreateLoginKey = step.createLoginKey
if config.SupportVPC {
step.CreateLoginKey = step.createVpcLoginKey
step.DeleteLoginKey = step.deleteVpcLoginKey
} else {
step.CreateLoginKey = step.createClassicLoginKey
step.DeleteLoginKey = step.deleteClassicLoginKey
}
return step
}
func (s *StepCreateLoginKey) createLoginKey() (*LoginKey, error) {
func (s *StepCreateLoginKey) createClassicLoginKey() (*LoginKey, error) {
keyName := fmt.Sprintf("packer-%d", time.Now().Unix())
reqParams := &server.CreateLoginKeyRequest{KeyName: &keyName}
@@ -46,12 +56,46 @@ func (s *StepCreateLoginKey) createLoginKey() (*LoginKey, error) {
return &LoginKey{keyName, *privateKey.PrivateKey}, nil
}
func (s *StepCreateLoginKey) createVpcLoginKey() (*LoginKey, error) {
keyName := fmt.Sprintf("packer-%d", time.Now().Unix())
reqParams := &vserver.CreateLoginKeyRequest{KeyName: &keyName}
privateKey, err := s.Conn.vserver.V2Api.CreateLoginKey(reqParams)
if err != nil {
return nil, err
}
return &LoginKey{keyName, *privateKey.PrivateKey}, nil
}
func (s *StepCreateLoginKey) deleteClassicLoginKey(keyName string) error {
reqParams := &server.DeleteLoginKeyRequest{KeyName: &keyName}
_, err := s.Conn.server.V2Api.DeleteLoginKey(reqParams)
if err != nil {
return err
}
return nil
}
func (s *StepCreateLoginKey) deleteVpcLoginKey(keyName string) error {
reqParams := &vserver.DeleteLoginKeysRequest{KeyNameList: []*string{&keyName}}
_, err := s.Conn.vserver.V2Api.DeleteLoginKeys(reqParams)
if err != nil {
return err
}
return nil
}
func (s *StepCreateLoginKey) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create Login Key")
loginKey, err := s.CreateLoginKey()
if err == nil {
state.Put("LoginKey", loginKey)
state.Put("login_key", loginKey)
s.Say(fmt.Sprintf("Login Key[%s] is created", loginKey.KeyName))
}
@@ -59,9 +103,11 @@ func (s *StepCreateLoginKey) Run(ctx context.Context, state multistep.StateBag)
}
func (s *StepCreateLoginKey) Cleanup(state multistep.StateBag) {
if loginKey, ok := state.GetOk("LoginKey"); ok {
if loginKey, ok := state.GetOk("login_key"); ok {
s.Say("Clean up login key")
reqParams := &server.DeleteLoginKeyRequest{KeyName: &loginKey.(*LoginKey).KeyName}
s.Conn.server.V2Api.DeleteLoginKey(reqParams)
if err := s.DeleteLoginKey(loginKey.(*LoginKey).KeyName); err != nil {
s.Error(err)
return
}
}
}
+2 -2
View File
@@ -23,7 +23,7 @@ func TestStepCreateLoginKeyShouldFailIfOperationCreateLoginKeyFails(t *testing.T
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -43,7 +43,7 @@ func TestStepCreateLoginKeyShouldPassIfOperationCreateLoginKeyPasses(t *testing.
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
+256 -60
View File
@@ -3,6 +3,7 @@ package ncloud
import (
"context"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
@@ -12,32 +13,103 @@ import (
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
type StepCreatePublicIPInstance struct {
const (
PublicIpStatusUsed = "USED"
PublicIpStatusCreated = "CREAT"
PublicIpStatusRunning = "RUN"
)
type StepCreatePublicIP struct {
Conn *NcloudAPIClient
CreatePublicIPInstance func(serverInstanceNo string) (*server.PublicIpInstance, error)
GetPublicIP func(publicIPNo string) (*server.PublicIpInstance, error)
CreatePublicIP func(serverInstanceNo string) (*server.PublicIpInstance, error)
DeletePublicIp func(publicIPNo string) error
WaiterAssociatePublicIPToServerInstance func(serverInstanceNo string, publicIP string) error
DisassociatePublicIpFromServerInstance func(publicIPNo string) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepCreatePublicIPInstance(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreatePublicIPInstance {
var step = &StepCreatePublicIPInstance{
func NewStepCreatePublicIP(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreatePublicIP {
var step = &StepCreatePublicIP{
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
if config.SupportVPC {
step.GetPublicIP = step.getVpcPublicIP
step.CreatePublicIP = step.createVpcPublicIP
step.WaiterAssociatePublicIPToServerInstance = step.waiterAssociateVpcPublicIPToServerInstance
step.DisassociatePublicIpFromServerInstance = step.disassociateVpcPublicIpFromServerInstance
step.DeletePublicIp = step.deleteVpcPublicIp
} else {
step.GetPublicIP = step.getClassicPublicIP
step.CreatePublicIP = step.createClassicPublicIP
step.WaiterAssociatePublicIPToServerInstance = step.waiterAssociateClassicPublicIPToServerInstance
step.DisassociatePublicIpFromServerInstance = step.disassociateClassicPublicIpFromServerInstance
step.DeletePublicIp = step.deleteClassicPublicIp
}
return step
}
func (s *StepCreatePublicIPInstance) waiterAssociatePublicIPToServerInstance(serverInstanceNo string, publicIP string) error {
reqParams := new(server.GetServerInstanceListRequest)
reqParams.ServerInstanceNoList = []*string{&serverInstanceNo}
func (s *StepCreatePublicIP) getClassicPublicIP(publicIPNo string) (*server.PublicIpInstance, error) {
reqParams := &server.GetPublicIpInstanceListRequest{
PublicIpInstanceNoList: []*string{&publicIPNo},
}
resp, err := s.Conn.server.V2Api.GetPublicIpInstanceList(reqParams)
if err != nil {
return nil, err
}
if resp != nil && *resp.TotalRows > 0 {
return resp.PublicIpInstanceList[0], nil
}
return nil, nil
}
func (s *StepCreatePublicIP) getVpcPublicIP(publicIPNo string) (*server.PublicIpInstance, error) {
reqParams := &vserver.GetPublicIpInstanceDetailRequest{
RegionCode: &s.Config.RegionCode,
PublicIpInstanceNo: &publicIPNo,
}
resp, err := s.Conn.vserver.V2Api.GetPublicIpInstanceDetail(reqParams)
if err != nil {
return nil, err
}
if resp != nil && *resp.TotalRows > 0 {
inst := resp.PublicIpInstanceList[0]
return &server.PublicIpInstance{
PublicIpInstanceNo: inst.PublicIpInstanceNo,
PublicIp: inst.PublicIp,
PublicIpInstanceStatus: &server.CommonCode{
Code: inst.PublicIpInstanceStatus.Code,
CodeName: inst.PublicIpInstanceStatus.CodeName,
},
PublicIpInstanceOperation: &server.CommonCode{
Code: inst.PublicIpInstanceOperation.Code,
CodeName: inst.PublicIpInstanceOperation.CodeName,
},
ServerInstanceAssociatedWithPublicIp: &server.ServerInstance{
ServerInstanceNo: inst.ServerInstanceNo,
},
}, nil
}
return nil, nil
}
func (s *StepCreatePublicIP) waiterAssociateClassicPublicIPToServerInstance(serverInstanceNo string, publicIP string) error {
reqParams := &server.GetServerInstanceListRequest{
ServerInstanceNoList: []*string{&serverInstanceNo},
}
c1 := make(chan error, 1)
@@ -68,9 +140,45 @@ func (s *StepCreatePublicIPInstance) waiterAssociatePublicIPToServerInstance(ser
}
}
func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo string) (*server.PublicIpInstance, error) {
reqParams := new(server.CreatePublicIpInstanceRequest)
reqParams.ServerInstanceNo = &serverInstanceNo
func (s *StepCreatePublicIP) waiterAssociateVpcPublicIPToServerInstance(serverInstanceNo string, publicIP string) error {
reqParams := &vserver.GetServerInstanceDetailRequest{
RegionCode: &s.Config.RegionCode,
ServerInstanceNo: &serverInstanceNo,
}
c1 := make(chan error, 1)
go func() {
for {
serverInstanceList, err := s.Conn.vserver.V2Api.GetServerInstanceDetail(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 *StepCreatePublicIP) createClassicPublicIP(serverInstanceNo string) (*server.PublicIpInstance, error) {
reqParams := &server.CreatePublicIpInstanceRequest{
ServerInstanceNo: &serverInstanceNo,
}
publicIPInstanceList, err := s.Conn.server.V2Api.CreatePublicIpInstance(reqParams)
if err != nil {
@@ -81,7 +189,7 @@ func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo str
publicIP := publicIPInstance.PublicIp
s.Say(fmt.Sprintf("Public IP Instance [%s:%s] is created", *publicIPInstance.PublicIpInstanceNo, *publicIP))
err = s.waiterAssociatePublicIPToServerInstance(serverInstanceNo, *publicIP)
err = s.WaiterAssociatePublicIPToServerInstance(serverInstanceNo, *publicIP)
if err != nil {
return nil, err
}
@@ -89,69 +197,49 @@ func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo str
return publicIPInstance, nil
}
func (s *StepCreatePublicIPInstance) Run(ctx 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)
// 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", *publicIPInstance)
func (s *StepCreatePublicIP) createVpcPublicIP(serverInstanceNo string) (*server.PublicIpInstance, error) {
reqParams := &vserver.CreatePublicIpInstanceRequest{
RegionCode: &s.Config.RegionCode,
ServerInstanceNo: &serverInstanceNo,
}
return processStepResult(err, s.Error, state)
publicIPInstanceList, err := s.Conn.vserver.V2Api.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)
if err != nil {
return nil, err
}
return &server.PublicIpInstance{
PublicIpInstanceNo: publicIPInstance.PublicIpInstanceNo,
PublicIp: publicIP,
}, nil
}
func (s *StepCreatePublicIPInstance) Cleanup(state multistep.StateBag) {
publicIPInstance, ok := state.GetOk("PublicIPInstance")
if !ok {
return
}
s.Say("Clean up Public IP Instance")
publicIPInstanceNo := publicIPInstance.(*server.PublicIpInstance).PublicIpInstanceNo
s.waitPublicIPInstanceStatus(publicIPInstanceNo, "USED")
log.Println("Disassociate Public IP Instance ", publicIPInstanceNo)
reqParams := &server.DisassociatePublicIpFromServerInstanceRequest{PublicIpInstanceNo: publicIPInstanceNo}
s.Conn.server.V2Api.DisassociatePublicIpFromServerInstance(reqParams)
s.waitPublicIPInstanceStatus(publicIPInstanceNo, "CREAT")
reqDeleteParams := &server.DeletePublicIpInstancesRequest{
PublicIpInstanceNoList: ncloud.StringList([]string{*publicIPInstanceNo}),
}
log.Println("Delete Public IP Instance ", publicIPInstanceNo)
s.Conn.server.V2Api.DeletePublicIpInstances(reqDeleteParams)
}
func (s *StepCreatePublicIPInstance) waitPublicIPInstanceStatus(publicIPInstanceNo *string, status string) {
func (s *StepCreatePublicIP) waitPublicIPStatus(publicIPInstanceNo string, status string) error {
c1 := make(chan error, 1)
go func() {
reqParams := new(server.GetPublicIpInstanceListRequest)
reqParams.PublicIpInstanceNoList = []*string{publicIPInstanceNo}
for {
resp, err := s.Conn.server.V2Api.GetPublicIpInstanceList(reqParams)
publicIp, err := s.GetPublicIP(publicIPInstanceNo)
if err != nil {
log.Printf(err.Error())
c1 <- err
return
}
if *resp.TotalRows == 0 {
if publicIp == nil {
c1 <- nil
return
}
instance := resp.PublicIpInstanceList[0]
if *instance.PublicIpInstanceStatus.Code == status && *instance.PublicIpInstanceOperation.Code == "NULL" {
if *publicIp.PublicIpInstanceStatus.Code == status && *publicIp.PublicIpInstanceOperation.Code == "NULL" {
c1 <- nil
return
}
@@ -162,8 +250,116 @@ func (s *StepCreatePublicIPInstance) waitPublicIPInstanceStatus(publicIPInstance
select {
case <-c1:
return
return nil
case <-time.After(time.Second * 60):
return fmt.Errorf("TIMEOUT : wait for public ip[%s] to status[%s] Failed", publicIPInstanceNo, status)
}
}
func (s *StepCreatePublicIP) disassociateClassicPublicIpFromServerInstance(publicIPInstanceNo string) error {
reqParams := &server.DisassociatePublicIpFromServerInstanceRequest{
PublicIpInstanceNo: &publicIPInstanceNo,
}
_, err := s.Conn.server.V2Api.DisassociatePublicIpFromServerInstance(reqParams)
return err
}
func (s *StepCreatePublicIP) disassociateVpcPublicIpFromServerInstance(publicIPInstanceNo string) error {
reqParams := &vserver.DisassociatePublicIpFromServerInstanceRequest{
RegionCode: &s.Config.RegionCode,
PublicIpInstanceNo: &publicIPInstanceNo,
}
_, err := s.Conn.vserver.V2Api.DisassociatePublicIpFromServerInstance(reqParams)
return err
}
func (s *StepCreatePublicIP) deleteClassicPublicIp(publicIPInstanceNo string) error {
reqParams := &server.DeletePublicIpInstancesRequest{
PublicIpInstanceNoList: ncloud.StringList([]string{publicIPInstanceNo}),
}
_, err := s.Conn.server.V2Api.DeletePublicIpInstances(reqParams)
return err
}
func (s *StepCreatePublicIP) deleteVpcPublicIp(publicIPInstanceNo string) error {
reqParams := &vserver.DeletePublicIpInstanceRequest{
RegionCode: &s.Config.RegionCode,
PublicIpInstanceNo: &publicIPInstanceNo,
}
_, err := s.Conn.vserver.V2Api.DeletePublicIpInstance(reqParams)
return err
}
func (s *StepCreatePublicIP) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create Public IP Instance")
serverInstanceNo := state.Get("instance_no").(string)
publicIPInstance, err := s.CreatePublicIP(serverInstanceNo)
if err == nil {
state.Put("public_ip", *publicIPInstance.PublicIp)
state.Put("public_ip_instance", publicIPInstance)
}
return processStepResult(err, s.Error, state)
}
func (s *StepCreatePublicIP) Cleanup(state multistep.StateBag) {
publicIPInstance, ok := state.GetOk("public_ip_instance")
if !ok {
return
}
s.Say("Clean up Public IP Instance")
publicIPInstanceNo := publicIPInstance.(*server.PublicIpInstance).PublicIpInstanceNo
publicIp, err := s.GetPublicIP(*publicIPInstanceNo)
if err != nil {
s.Error(err)
}
if publicIp == nil {
return
}
publicIpUsedStatus := PublicIpStatusUsed
publicIpCreatedStatus := PublicIpStatusCreated
if s.Config.SupportVPC {
publicIpUsedStatus = PublicIpStatusRunning
publicIpCreatedStatus = PublicIpStatusRunning
}
if publicIp.ServerInstanceAssociatedWithPublicIp != nil &&
publicIp.ServerInstanceAssociatedWithPublicIp.ServerInstanceNo != nil &&
len(*publicIp.ServerInstanceAssociatedWithPublicIp.ServerInstanceNo) > 0 {
if err := s.waitPublicIPStatus(*publicIPInstanceNo, publicIpUsedStatus); err != nil {
s.Error(err)
}
log.Println("Disassociate Public IP Instance ", publicIPInstanceNo)
if err := s.DisassociatePublicIpFromServerInstance(*publicIPInstanceNo); err != nil {
s.Error(err)
return
}
}
if err := s.waitPublicIPStatus(*publicIPInstanceNo, publicIpCreatedStatus); err != nil {
s.Error(err)
return
}
log.Println("Delete Public IP Instance ", publicIPInstanceNo)
if err := s.DeletePublicIp(*publicIPInstanceNo); err != nil {
s.Error(err)
return
}
}
@@ -12,8 +12,8 @@ import (
)
func TestStepCreatePublicIPInstanceShouldFailIfOperationCreatePublicIPInstanceFails(t *testing.T) {
var testSubject = &StepCreatePublicIPInstance{
CreatePublicIPInstance: func(serverInstanceNo string) (*server.PublicIpInstance, error) {
var testSubject = &StepCreatePublicIP{
CreatePublicIP: func(serverInstanceNo string) (*server.PublicIpInstance, error) {
return nil, fmt.Errorf("!! Unit Test FAIL !!")
},
Say: func(message string) {},
@@ -28,7 +28,7 @@ func TestStepCreatePublicIPInstanceShouldFailIfOperationCreatePublicIPInstanceFa
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -38,8 +38,8 @@ func TestStepCreatePublicIPInstanceShouldPassIfOperationCreatePublicIPInstancePa
c.Comm.Prepare(nil)
c.Comm.Type = "ssh"
var testSubject = &StepCreatePublicIPInstance{
CreatePublicIPInstance: func(serverInstanceNo string) (*server.PublicIpInstance, error) {
var testSubject = &StepCreatePublicIP{
CreatePublicIP: func(serverInstanceNo string) (*server.PublicIpInstance, error) {
return &server.PublicIpInstance{PublicIpInstanceNo: ncloud.String("a"), PublicIp: ncloud.String("b")}, nil
},
Say: func(message string) {},
@@ -55,7 +55,7 @@ func TestStepCreatePublicIPInstanceShouldPassIfOperationCreatePublicIPInstancePa
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -63,7 +63,7 @@ func TestStepCreatePublicIPInstanceShouldPassIfOperationCreatePublicIPInstancePa
func createTestStateBagStepCreatePublicIPInstance() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("InstanceNo", "a")
stateBag.Put("instance_no", "a")
return stateBag
}
+62 -10
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
@@ -11,6 +12,10 @@ import (
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
const (
ServerImageStatusCreated = "CREAT"
)
type StepCreateServerImage struct {
Conn *NcloudAPIClient
CreateServerImage func(serverInstanceNo string) (*server.MemberServerImage, error)
@@ -27,21 +32,26 @@ func NewStepCreateServerImage(conn *NcloudAPIClient, ui packersdk.Ui, config *Co
Config: config,
}
step.CreateServerImage = step.createServerImage
if config.SupportVPC {
step.CreateServerImage = step.createVpcServerImage
} else {
step.CreateServerImage = step.createClassicServerImage
}
return step
}
func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*server.MemberServerImage, error) {
func (s *StepCreateServerImage) createClassicServerImage(serverInstanceNo string) (*server.MemberServerImage, error) {
// Can't create server image when status of server instance is stopping (not stopped)
if err := waiterServerInstanceStatus(s.Conn, serverInstanceNo, "NSTOP", 1*time.Minute); err != nil {
if err := waiterClassicServerInstanceStatus(s.Conn, serverInstanceNo, ServerInstanceStatusStopped, 1*time.Minute); err != nil {
return nil, err
}
reqParams := new(server.CreateMemberServerImageRequest)
reqParams.MemberServerImageName = &s.Config.ServerImageName
reqParams.MemberServerImageDescription = &s.Config.ServerImageDescription
reqParams.ServerInstanceNo = &serverInstanceNo
reqParams := &server.CreateMemberServerImageRequest{
MemberServerImageName: &s.Config.ServerImageName,
MemberServerImageDescription: &s.Config.ServerImageDescription,
ServerInstanceNo: &serverInstanceNo,
}
memberServerImageList, err := s.Conn.server.V2Api.CreateMemberServerImage(reqParams)
if err != nil {
@@ -52,7 +62,7 @@ func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*ser
s.Say(fmt.Sprintf("Server Image[%s:%s] is creating...", *serverImage.MemberServerImageName, *serverImage.MemberServerImageNo))
if err := waiterMemberServerImageStatus(s.Conn, *serverImage.MemberServerImageNo, "CREAT", 6*time.Hour); err != nil {
if err := waiterClassicMemberServerImageStatus(s.Conn, *serverImage.MemberServerImageNo, ServerImageStatusCreated, 6*time.Hour); err != nil {
return nil, errors.New("TIMEOUT : Server Image is not created")
}
@@ -61,14 +71,56 @@ func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*ser
return serverImage, nil
}
func (s *StepCreateServerImage) createVpcServerImage(serverInstanceNo string) (*server.MemberServerImage, error) {
// Can't create server image when status of server instance is stopping (not stopped)
if err := waiterVpcServerInstanceStatus(s.Conn, serverInstanceNo, ServerInstanceStatusStopped, 1*time.Minute); err != nil {
return nil, err
}
reqParams := &vserver.CreateMemberServerImageInstanceRequest{
MemberServerImageName: &s.Config.ServerImageName,
MemberServerImageDescription: &s.Config.ServerImageDescription,
ServerInstanceNo: &serverInstanceNo,
}
memberServerImageList, err := s.Conn.vserver.V2Api.CreateMemberServerImageInstance(reqParams)
if err != nil {
return nil, err
}
serverImage := memberServerImageList.MemberServerImageInstanceList[0]
s.Say(fmt.Sprintf("Server Image[%s:%s] is creating...", *serverImage.MemberServerImageName, *serverImage.MemberServerImageInstanceNo))
if err := waiterVpcMemberServerImageStatus(s.Conn, *serverImage.MemberServerImageInstanceNo, ServerImageStatusCreated, 6*time.Hour); err != nil {
return nil, errors.New("TIMEOUT : Server Image is not created")
}
s.Say(fmt.Sprintf("Server Image[%s:%s] is created", *serverImage.MemberServerImageName, *serverImage.MemberServerImageInstanceNo))
result := &server.MemberServerImage{
MemberServerImageNo: serverImage.MemberServerImageInstanceNo,
MemberServerImageName: serverImage.MemberServerImageName,
}
if serverImage.MemberServerImageInstanceStatus != nil {
result.MemberServerImageStatus = &server.CommonCode{
Code: serverImage.MemberServerImageInstanceStatus.Code,
CodeName: serverImage.MemberServerImageInstanceStatus.CodeName,
}
}
return result, nil
}
func (s *StepCreateServerImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create Server Image")
serverInstanceNo := state.Get("InstanceNo").(string)
serverInstanceNo := state.Get("instance_no").(string)
serverImage, err := s.CreateServerImage(serverInstanceNo)
if err == nil {
state.Put("memberServerImage", serverImage)
state.Put("member_server_image", serverImage)
}
return processStepResult(err, s.Error, state)
@@ -27,7 +27,7 @@ func TestStepCreateServerImageShouldFailIfOperationCreateServerImageFails(t *tes
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -46,7 +46,7 @@ func TestStepCreateServerImageShouldPassIfOperationCreateServerImagePasses(t *te
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -54,7 +54,7 @@ func TestStepCreateServerImageShouldPassIfOperationCreateServerImagePasses(t *te
func createTestStateBagStepCreateServerImage() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("InstanceNo", "a")
stateBag.Put("instance_no", "a")
return stateBag
}
+148 -46
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"io/ioutil"
"log"
"time"
@@ -14,14 +15,21 @@ import (
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
const (
ServerInstanceStatusStopped = "NSTOP"
ServerInstanceStatusTerminated = "TERMT"
ServerInstanceStatusRunning = "RUN"
)
type StepCreateServerInstance struct {
Conn *NcloudAPIClient
CreateServerInstance func(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error)
CheckServerInstanceStatusIsRunning func(serverInstanceNo string) error
Say func(message string)
Error func(e error)
Config *Config
serverInstanceNo string
Conn *NcloudAPIClient
CreateServerInstance func(loginKeyName string, feeSystemTypeCode string, state multistep.StateBag) (string, error)
GetServerInstance func() (string, string, error)
WaiterServerInstanceStatus func(conn *NcloudAPIClient, serverInstanceNo string, status string, timeout time.Duration) error
Say func(message string)
Error func(e error)
Config *Config
serverInstanceNo string
}
func NewStepCreateServerInstance(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateServerInstance {
@@ -32,21 +40,32 @@ func NewStepCreateServerInstance(conn *NcloudAPIClient, ui packersdk.Ui, config
Config: config,
}
step.CreateServerInstance = step.createServerInstance
if config.SupportVPC {
step.CreateServerInstance = step.createVpcServerInstance
step.WaiterServerInstanceStatus = waiterVpcServerInstanceStatus
step.GetServerInstance = step.getVpcServerInstance
} else {
step.CreateServerInstance = step.createClassicServerInstance
step.WaiterServerInstanceStatus = waiterClassicServerInstanceStatus
step.GetServerInstance = step.getClassicServerInstance
}
return step
}
func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) {
reqParams := new(server.CreateServerInstancesRequest)
reqParams.ServerProductCode = &s.Config.ServerProductCode
reqParams.MemberServerImageNo = &s.Config.MemberServerImageNo
func (s *StepCreateServerInstance) createClassicServerInstance(loginKeyName string, feeSystemTypeCode string, state multistep.StateBag) (string, error) {
var zoneNo = state.Get("zone_no").(string)
reqParams := &server.CreateServerInstancesRequest{
ServerProductCode: &s.Config.ServerProductCode,
MemberServerImageNo: &s.Config.MemberServerImageNo,
LoginKeyName: &loginKeyName,
ZoneNo: &zoneNo,
FeeSystemTypeCode: &feeSystemTypeCode,
}
if s.Config.MemberServerImageNo == "" {
reqParams.ServerImageProductCode = &s.Config.ServerImageProductCode
}
reqParams.LoginKeyName = &loginKeyName
reqParams.ZoneNo = &zoneNo
reqParams.FeeSystemTypeCode = &feeSystemTypeCode
if s.Config.UserData != "" {
reqParams.UserData = &s.Config.UserData
@@ -61,8 +80,8 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon
reqParams.UserData = ncloud.String(string(contents))
}
if s.Config.AccessControlGroupConfigurationNo != "" {
reqParams.AccessControlGroupConfigurationNoList = []*string{&s.Config.AccessControlGroupConfigurationNo}
if s.Config.AccessControlGroupNo != "" {
reqParams.AccessControlGroupConfigurationNoList = []*string{&s.Config.AccessControlGroupNo}
}
serverInstanceList, err := s.Conn.server.V2Api.CreateServerInstances(reqParams)
@@ -74,7 +93,7 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon
s.Say(fmt.Sprintf("Server Instance is creating. Server InstanceNo is %s", s.serverInstanceNo))
log.Println("Server Instance information : ", serverInstanceList.ServerInstanceList[0])
if err := waiterServerInstanceStatus(s.Conn, s.serverInstanceNo, "RUN", 30*time.Minute); err != nil {
if err := s.WaiterServerInstanceStatus(s.Conn, s.serverInstanceNo, ServerInstanceStatusRunning, 30*time.Minute); err != nil {
return "", errors.New("TIMEOUT : server instance status is not running")
}
@@ -83,20 +102,104 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon
return s.serverInstanceNo, nil
}
func (s *StepCreateServerInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create Server Instance")
func (s *StepCreateServerInstance) createVpcServerInstance(loginKeyName string, feeSystemTypeCode string, state multistep.StateBag) (string, error) {
var initScriptNo string
var acgNo string
var err error
var loginKey = state.Get("LoginKey").(*LoginKey)
var zoneNo = state.Get("ZoneNo").(string)
feeSystemTypeCode := "MTRAT"
if _, ok := state.GetOk("FeeSystemTypeCode"); ok {
feeSystemTypeCode = state.Get("FeeSystemTypeCode").(string)
if v, ok := state.GetOk("init_script_no"); ok {
initScriptNo = v.(string)
}
serverInstanceNo, err := s.CreateServerInstance(loginKey.KeyName, zoneNo, feeSystemTypeCode)
if s.Config.AccessControlGroupNo != "" {
acgNo = s.Config.AccessControlGroupNo
} else {
acgNo = state.Get("access_control_group_no").(string)
}
reqParams := &vserver.CreateServerInstancesRequest{
RegionCode: &s.Config.RegionCode,
ServerProductCode: &s.Config.ServerProductCode,
MemberServerImageInstanceNo: &s.Config.MemberServerImageNo,
LoginKeyName: &loginKeyName,
FeeSystemTypeCode: &feeSystemTypeCode,
InitScriptNo: &initScriptNo,
VpcNo: &s.Config.VpcNo,
SubnetNo: &s.Config.SubnetNo,
NetworkInterfaceList: []*vserver.NetworkInterfaceParameter{{
NetworkInterfaceOrder: ncloud.Int32(0),
AccessControlGroupNoList: []*string{ncloud.String(acgNo)}},
},
}
if s.Config.MemberServerImageNo == "" {
reqParams.ServerImageProductCode = &s.Config.ServerImageProductCode
}
serverInstanceList, err := s.Conn.vserver.V2Api.CreateServerInstances(reqParams)
if err != nil {
return "", err
}
s.serverInstanceNo = *serverInstanceList.ServerInstanceList[0].ServerInstanceNo
s.Say(fmt.Sprintf("Server Instance is creating. Server InstanceNo is %s", s.serverInstanceNo))
log.Println("Server Instance information : ", serverInstanceList.ServerInstanceList[0])
if err := s.WaiterServerInstanceStatus(s.Conn, s.serverInstanceNo, ServerInstanceStatusRunning, 30*time.Minute); err != nil {
return "", errors.New("TIMEOUT : server instance status is not running")
}
s.Say(fmt.Sprintf("Server Instance is created. Server InstanceNo is %s", s.serverInstanceNo))
return s.serverInstanceNo, nil
}
func (s *StepCreateServerInstance) getClassicServerInstance() (string, string, error) {
reqParams := &server.GetServerInstanceListRequest{
ServerInstanceNoList: []*string{&s.serverInstanceNo},
}
resp, err := s.Conn.server.V2Api.GetServerInstanceList(reqParams)
if err != nil {
return "", "", err
}
if *resp.TotalRows > 0 {
return *resp.ServerInstanceList[0].ServerInstanceNo, *resp.ServerInstanceList[0].ServerInstanceStatus.Code, nil
} else {
return "", "", nil
}
}
func (s *StepCreateServerInstance) getVpcServerInstance() (string, string, error) {
reqParams := &vserver.GetServerInstanceDetailRequest{
ServerInstanceNo: &s.serverInstanceNo,
}
resp, err := s.Conn.vserver.V2Api.GetServerInstanceDetail(reqParams)
if err != nil {
return "", "", err
}
if *resp.TotalRows > 0 {
return *resp.ServerInstanceList[0].ServerInstanceNo, *resp.ServerInstanceList[0].ServerInstanceStatus.Code, nil
} else {
return "", "", nil
}
}
func (s *StepCreateServerInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Create Server Instance")
loginKey := state.Get("login_key").(*LoginKey)
feeSystemTypeCode := "MTRAT"
if _, ok := state.GetOk("fee_system_type_code"); ok {
feeSystemTypeCode = state.Get("fee_system_type_code").(string)
}
serverInstanceNo, err := s.CreateServerInstance(loginKey.KeyName, feeSystemTypeCode, state)
if err == nil {
state.Put("InstanceNo", serverInstanceNo)
state.Put("instance_no", serverInstanceNo)
// 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", serverInstanceNo)
@@ -108,6 +211,7 @@ func (s *StepCreateServerInstance) Run(ctx context.Context, state multistep.Stat
func (s *StepCreateServerInstance) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
ui := state.Get("ui").(packersdk.Ui)
if !cancelled && !halted {
return
@@ -117,33 +221,31 @@ func (s *StepCreateServerInstance) Cleanup(state multistep.StateBag) {
return
}
reqParams := new(server.GetServerInstanceListRequest)
reqParams.ServerInstanceNoList = []*string{&s.serverInstanceNo}
_, status, err := s.GetServerInstance()
serverInstanceList, err := s.Conn.server.V2Api.GetServerInstanceList(reqParams)
if err != nil || *serverInstanceList.TotalRows == 0 {
if err != nil || len(status) == 0 {
return
}
s.Say("Clean up Server Instance")
serverInstance := serverInstanceList.ServerInstanceList[0]
// stop server instance
if *serverInstance.ServerInstanceStatus.Code != "NSTOP" && *serverInstance.ServerInstanceStatus.Code != "TERMT" {
reqParams := new(server.StopServerInstancesRequest)
reqParams.ServerInstanceNoList = []*string{&s.serverInstanceNo}
log.Println("Stop Server Instance")
s.Conn.server.V2Api.StopServerInstances(reqParams)
waiterServerInstanceStatus(s.Conn, s.serverInstanceNo, "NSTOP", time.Minute)
if status != ServerInstanceStatusStopped && status != ServerInstanceStatusTerminated {
stepStopServerInstance := NewStepStopServerInstance(s.Conn, ui, s.Config)
err := stepStopServerInstance.StopServerInstance(s.serverInstanceNo)
if err != nil {
s.Error(err)
return
}
}
// terminate server instance
if *serverInstance.ServerInstanceStatus.Code != "TERMT" {
reqParams := new(server.TerminateServerInstancesRequest)
reqParams.ServerInstanceNoList = []*string{&s.serverInstanceNo}
log.Println("Terminate Server Instance")
s.Conn.server.V2Api.TerminateServerInstances(reqParams)
if status != ServerInstanceStatusTerminated {
stepStopServerInstance := NewStepTerminateServerInstance(s.Conn, ui, s.Config)
err := stepStopServerInstance.TerminateServerInstance(s.serverInstanceNo)
if err != nil {
s.Error(err)
return
}
}
}
@@ -10,7 +10,7 @@ import (
func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T) {
var testSubject = &StepCreateServerInstance{
CreateServerInstance: func(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) {
CreateServerInstance: func(loginKeyName string, feeSystemTypeCode string, state multistep.StateBag) (string, error) {
return "", fmt.Errorf("!! Unit Test FAIL !!")
},
Say: func(message string) {},
@@ -25,16 +25,18 @@ func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T)
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
func TestStepCreateServerInstanceShouldPassIfOperationCreatePasses(t *testing.T) {
var testSubject = &StepCreateServerInstance{
CreateServerInstance: func(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) { return "", nil },
Say: func(message string) {},
Error: func(e error) {},
CreateServerInstance: func(loginKeyName string, feeSystemTypeCode string, state multistep.StateBag) (string, error) {
return "", nil
},
Say: func(message string) {},
Error: func(e error) {},
}
stateBag := createTestStateBagStepCreateServerInstance()
@@ -45,7 +47,7 @@ func TestStepCreateServerInstanceShouldPassIfOperationCreatePasses(t *testing.T)
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -53,8 +55,8 @@ func TestStepCreateServerInstanceShouldPassIfOperationCreatePasses(t *testing.T)
func createTestStateBagStepCreateServerInstance() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("LoginKey", &LoginKey{"a", "b"})
stateBag.Put("ZoneNo", "1")
stateBag.Put("login_key", &LoginKey{"a", "b"})
stateBag.Put("zone_no", "1")
return stateBag
}
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
@@ -12,30 +13,35 @@ import (
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
type StepDeleteBlockStorageInstance struct {
Conn *NcloudAPIClient
DeleteBlockStorageInstance func(blockStorageInstanceNo string) error
Say func(message string)
Error func(e error)
Config *Config
type StepDeleteBlockStorage struct {
Conn *NcloudAPIClient
DeleteBlockStorage func(blockStorageNo string) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepDeleteBlockStorageInstance(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepDeleteBlockStorageInstance {
var step = &StepDeleteBlockStorageInstance{
func NewStepDeleteBlockStorage(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepDeleteBlockStorage {
var step = &StepDeleteBlockStorage{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
step.DeleteBlockStorageInstance = step.deleteBlockStorageInstance
if config.SupportVPC {
step.DeleteBlockStorage = step.deleteVpcBlockStorage
} else {
step.DeleteBlockStorage = step.deleteClassicBlockStorage
}
return step
}
func (s *StepDeleteBlockStorageInstance) getBlockInstanceList(serverInstanceNo string) []*string {
reqParams := new(server.GetBlockStorageInstanceListRequest)
reqParams.ServerInstanceNo = &serverInstanceNo
func (s *StepDeleteBlockStorage) getClassicBlockList(serverInstanceNo string) []*string {
reqParams := &server.GetBlockStorageInstanceListRequest{
ServerInstanceNo: &serverInstanceNo,
}
blockStorageInstanceList, err := s.Conn.server.V2Api.GetBlockStorageInstanceList(reqParams)
if err != nil {
@@ -58,8 +64,34 @@ func (s *StepDeleteBlockStorageInstance) getBlockInstanceList(serverInstanceNo s
return instanceList
}
func (s *StepDeleteBlockStorageInstance) deleteBlockStorageInstance(serverInstanceNo string) error {
blockStorageInstanceList := s.getBlockInstanceList(serverInstanceNo)
func (s *StepDeleteBlockStorage) getVpcBlockList(serverInstanceNo string) []*string {
reqParams := &vserver.GetBlockStorageInstanceListRequest{
ServerInstanceNo: &serverInstanceNo,
}
blockStorageInstanceList, err := s.Conn.vserver.V2Api.GetBlockStorageInstanceList(reqParams)
if err != nil {
return nil
}
if *blockStorageInstanceList.TotalRows == 1 {
return nil
}
var instanceList []*string
for _, blockStorageInstance := range blockStorageInstanceList.BlockStorageInstanceList {
log.Println(blockStorageInstance)
if *blockStorageInstance.BlockStorageType.Code != "BASIC" {
instanceList = append(instanceList, blockStorageInstance.BlockStorageInstanceNo)
}
}
return instanceList
}
func (s *StepDeleteBlockStorage) deleteClassicBlockStorage(serverInstanceNo string) error {
blockStorageInstanceList := s.getClassicBlockList(serverInstanceNo)
if blockStorageInstanceList == nil || len(blockStorageInstanceList) == 0 {
return nil
}
@@ -73,26 +105,48 @@ func (s *StepDeleteBlockStorageInstance) deleteBlockStorageInstance(serverInstan
s.Say(fmt.Sprintf("Block Storage Instance is deleted. Block Storage Instance List is %v", blockStorageInstanceList))
if err := waiterDetachedBlockStorageInstance(s.Conn, serverInstanceNo, time.Minute); err != nil {
if err := waiterClassicDetachedBlockStorage(s.Conn, serverInstanceNo, time.Minute); err != nil {
return errors.New("TIMEOUT : Block Storage instance status is not deattached")
}
return nil
}
func (s *StepDeleteBlockStorageInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepDeleteBlockStorage) deleteVpcBlockStorage(serverInstanceNo string) error {
blockStorageInstanceList := s.getVpcBlockList(serverInstanceNo)
if blockStorageInstanceList == nil || len(blockStorageInstanceList) == 0 {
return nil
}
reqParams := vserver.DeleteBlockStorageInstancesRequest{
BlockStorageInstanceNoList: blockStorageInstanceList,
}
_, err := s.Conn.vserver.V2Api.DeleteBlockStorageInstances(&reqParams)
if err != nil {
return err
}
s.Say(fmt.Sprintf("Block Storage Instance is deleted. Block Storage Instance List is %v", blockStorageInstanceList))
if err := waiterVpcDetachedBlockStorage(s.Conn, serverInstanceNo, time.Minute); err != nil {
return errors.New("TIMEOUT : Block Storage instance status is not deattached")
}
return nil
}
func (s *StepDeleteBlockStorage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if s.Config.BlockStorageSize == 0 {
return processStepResult(nil, s.Error, state)
}
s.Say("Delete Block Storage Instance")
var serverInstanceNo = state.Get("InstanceNo").(string)
var serverInstanceNo = state.Get("instance_no").(string)
err := s.DeleteBlockStorageInstance(serverInstanceNo)
err := s.DeleteBlockStorage(serverInstanceNo)
return processStepResult(err, s.Error, state)
}
func (*StepDeleteBlockStorageInstance) Cleanup(multistep.StateBag) {
func (*StepDeleteBlockStorage) Cleanup(multistep.StateBag) {
}
@@ -9,11 +9,11 @@ import (
)
func TestStepDeleteBlockStorageInstanceShouldFailIfOperationDeleteBlockStorageInstanceFails(t *testing.T) {
var testSubject = &StepDeleteBlockStorageInstance{
DeleteBlockStorageInstance: func(blockStorageInstanceNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{BlockStorageSize: 10},
var testSubject = &StepDeleteBlockStorage{
DeleteBlockStorage: func(blockStorageNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{BlockStorageSize: 10},
}
stateBag := createTestStateBagStepDeleteBlockStorageInstance()
@@ -24,17 +24,17 @@ func TestStepDeleteBlockStorageInstanceShouldFailIfOperationDeleteBlockStorageIn
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
func TestStepDeleteBlockStorageInstanceShouldPassIfOperationDeleteBlockStorageInstancePasses(t *testing.T) {
var testSubject = &StepDeleteBlockStorageInstance{
DeleteBlockStorageInstance: func(blockStorageInstanceNo string) error { return nil },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{BlockStorageSize: 10},
var testSubject = &StepDeleteBlockStorage{
DeleteBlockStorage: func(blockStorageNo string) error { return nil },
Say: func(message string) {},
Error: func(e error) {},
Config: &Config{BlockStorageSize: 10},
}
stateBag := createTestStateBagStepDeleteBlockStorageInstance()
@@ -45,7 +45,7 @@ func TestStepDeleteBlockStorageInstanceShouldPassIfOperationDeleteBlockStorageIn
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -53,7 +53,7 @@ func TestStepDeleteBlockStorageInstanceShouldPassIfOperationDeleteBlockStorageIn
func createTestStateBagStepDeleteBlockStorageInstance() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("InstanceNo", "1")
stateBag.Put("instance_no", "1")
return stateBag
}
+30 -7
View File
@@ -3,6 +3,7 @@ package ncloud
import (
"context"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
"github.com/hashicorp/packer-plugin-sdk/multistep"
@@ -25,15 +26,20 @@ func NewStepGetRootPassword(conn *NcloudAPIClient, ui packersdk.Ui, config *Conf
Config: config,
}
step.GetRootPassword = step.getRootPassword
if config.SupportVPC {
step.GetRootPassword = step.getVpcRootPassword
} else {
step.GetRootPassword = step.getClassicRootPassword
}
return step
}
func (s *StepGetRootPassword) getRootPassword(serverInstanceNo string, privateKey string) (string, error) {
reqParams := new(server.GetRootPasswordRequest)
reqParams.ServerInstanceNo = &serverInstanceNo
reqParams.PrivateKey = &privateKey
func (s *StepGetRootPassword) getClassicRootPassword(serverInstanceNo string, privateKey string) (string, error) {
reqParams := &server.GetRootPasswordRequest{
ServerInstanceNo: &serverInstanceNo,
PrivateKey: &privateKey,
}
rootPassword, err := s.Conn.server.V2Api.GetRootPassword(reqParams)
if err != nil {
@@ -45,11 +51,28 @@ func (s *StepGetRootPassword) getRootPassword(serverInstanceNo string, privateKe
return *rootPassword.RootPassword, nil
}
func (s *StepGetRootPassword) getVpcRootPassword(serverInstanceNo string, privateKey string) (string, error) {
reqParams := &vserver.GetRootPasswordRequest{
RegionCode: &s.Config.RegionCode,
ServerInstanceNo: &serverInstanceNo,
PrivateKey: &privateKey,
}
rootPassword, err := s.Conn.vserver.V2Api.GetRootPassword(reqParams)
if err != nil {
return "", err
}
s.Say(fmt.Sprintf("Root password is %s", *rootPassword.RootPassword))
return *rootPassword.RootPassword, nil
}
func (s *StepGetRootPassword) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Get Root Password")
serverInstanceNo := state.Get("InstanceNo").(string)
loginKey := state.Get("LoginKey").(*LoginKey)
serverInstanceNo := state.Get("instance_no").(string)
loginKey := state.Get("login_key").(*LoginKey)
rootPassword, err := s.GetRootPassword(serverInstanceNo, loginKey.PrivateKey)
+4 -4
View File
@@ -24,7 +24,7 @@ func TestStepGetRootPasswordShouldFailIfOperationGetRootPasswordFails(t *testing
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -45,7 +45,7 @@ func TestStepGetRootPasswordShouldPassIfOperationGetRootPasswordPasses(t *testin
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -53,8 +53,8 @@ func TestStepGetRootPasswordShouldPassIfOperationGetRootPasswordPasses(t *testin
func DeleteTestStateBagStepGetRootPassword() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("LoginKey", &LoginKey{"a", "b"})
stateBag.Put("InstanceNo", "a")
stateBag.Put("login_key", &LoginKey{"a", "b"})
stateBag.Put("instance_no", "a")
return stateBag
}
+47 -16
View File
@@ -3,7 +3,7 @@ package ncloud
import (
"context"
"fmt"
"log"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
@@ -12,27 +12,37 @@ import (
)
type StepStopServerInstance struct {
Conn *NcloudAPIClient
StopServerInstance func(serverInstanceNo string) error
Say func(message string)
Error func(e error)
Conn *NcloudAPIClient
StopServerInstance func(serverInstanceNo string) error
WaiterServerInstanceStatus func(conn *NcloudAPIClient, serverInstanceNo string, status string, timeout time.Duration) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepStopServerInstance(conn *NcloudAPIClient, ui packersdk.Ui) *StepStopServerInstance {
func NewStepStopServerInstance(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepStopServerInstance {
var step = &StepStopServerInstance{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
step.StopServerInstance = step.stopServerInstance
if config.SupportVPC {
step.StopServerInstance = step.stopVpcServerInstance
step.WaiterServerInstanceStatus = waiterVpcServerInstanceStatus
} else {
step.StopServerInstance = step.stopClassicServerInstance
step.WaiterServerInstanceStatus = waiterClassicServerInstanceStatus
}
return step
}
func (s *StepStopServerInstance) stopServerInstance(serverInstanceNo string) error {
reqParams := new(server.StopServerInstancesRequest)
reqParams.ServerInstanceNoList = []*string{&serverInstanceNo}
func (s *StepStopServerInstance) stopClassicServerInstance(serverInstanceNo string) error {
reqParams := &server.StopServerInstancesRequest{
ServerInstanceNoList: []*string{&serverInstanceNo},
}
serverInstanceList, err := s.Conn.server.V2Api.StopServerInstances(reqParams)
if err != nil {
@@ -40,9 +50,30 @@ func (s *StepStopServerInstance) stopServerInstance(serverInstanceNo string) err
}
s.Say(fmt.Sprintf("Server Instance is stopping. Server InstanceNo is %s", *serverInstanceList.ServerInstanceList[0].ServerInstanceNo))
log.Println("Server Instance information : ", serverInstanceList.ServerInstanceList[0])
if err := waiterServerInstanceStatus(s.Conn, serverInstanceNo, "NSTOP", 5*time.Minute); err != nil {
if err := s.WaiterServerInstanceStatus(s.Conn, serverInstanceNo, ServerInstanceStatusStopped, 5*time.Minute); err != nil {
return err
}
s.Say(fmt.Sprintf("Server Instance stopped. Server InstanceNo is %s", *serverInstanceList.ServerInstanceList[0].ServerInstanceNo))
return nil
}
func (s *StepStopServerInstance) stopVpcServerInstance(serverInstanceNo string) error {
reqParams := &vserver.StopServerInstancesRequest{
RegionCode: &s.Config.RegionCode,
ServerInstanceNoList: []*string{&serverInstanceNo},
}
serverInstanceList, err := s.Conn.vserver.V2Api.StopServerInstances(reqParams)
if err != nil {
return err
}
s.Say(fmt.Sprintf("Server Instance is stopping. Server InstanceNo is %s", *serverInstanceList.ServerInstanceList[0].ServerInstanceNo))
if err := s.WaiterServerInstanceStatus(s.Conn, serverInstanceNo, ServerInstanceStatusStopped, 5*time.Minute); err != nil {
return err
}
@@ -54,7 +85,7 @@ func (s *StepStopServerInstance) stopServerInstance(serverInstanceNo string) err
func (s *StepStopServerInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Stop Server Instance")
var serverInstanceNo = state.Get("InstanceNo").(string)
var serverInstanceNo = state.Get("instance_no").(string)
err := s.StopServerInstance(serverInstanceNo)
@@ -23,7 +23,7 @@ func TestStepStopServerInstanceShouldFailIfOperationStopFails(t *testing.T) {
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -43,7 +43,7 @@ func TestStepStopServerInstanceShouldPassIfOperationStopPasses(t *testing.T) {
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -51,6 +51,6 @@ func TestStepStopServerInstanceShouldPassIfOperationStopPasses(t *testing.T) {
func createTestStateBagStepStopServerInstance() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("InstanceNo", "a")
stateBag.Put("instance_no", "a")
return stateBag
}
@@ -3,6 +3,9 @@ package ncloud
import (
"context"
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
@@ -15,37 +18,45 @@ type StepTerminateServerInstance struct {
TerminateServerInstance func(serverInstanceNo string) error
Say func(message string)
Error func(e error)
Config *Config
}
func NewStepTerminateServerInstance(conn *NcloudAPIClient, ui packersdk.Ui) *StepTerminateServerInstance {
func NewStepTerminateServerInstance(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepTerminateServerInstance {
var step = &StepTerminateServerInstance{
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Conn: conn,
Say: func(message string) { ui.Say(message) },
Error: func(e error) { ui.Error(e.Error()) },
Config: config,
}
step.TerminateServerInstance = step.terminateServerInstance
if config.SupportVPC {
step.TerminateServerInstance = step.terminateVpcServerInstance
} else {
step.TerminateServerInstance = step.terminateClassicServerInstance
}
return step
}
func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo string) error {
reqParams := new(server.TerminateServerInstancesRequest)
reqParams.ServerInstanceNoList = []*string{&serverInstanceNo}
func (s *StepTerminateServerInstance) terminateClassicServerInstance(serverInstanceNo string) error {
reqParams := &server.TerminateServerInstancesRequest{
ServerInstanceNoList: []*string{&serverInstanceNo},
}
_, err := s.Conn.server.V2Api.TerminateServerInstances(reqParams)
if err != nil {
return err
}
s.Say(fmt.Sprintf("Server Instance is terminating. Server InstanceNo is %s", serverInstanceNo))
c1 := make(chan error, 1)
go func() {
reqParams := new(server.GetServerInstanceListRequest)
reqParams.ServerInstanceNoList = []*string{&serverInstanceNo}
reqParams := &server.GetServerInstanceListRequest{
ServerInstanceNoList: []*string{&serverInstanceNo},
}
for {
serverInstanceList, err := s.Conn.server.V2Api.GetServerInstanceList(reqParams)
if err != nil {
c1 <- err
@@ -55,22 +66,67 @@ func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo s
return
}
log.Printf("Wating for terminating server instance [%s] is %s\n", serverInstanceNo, *serverInstanceList.ServerInstanceList[0].ServerInstanceStatus.Code)
time.Sleep(time.Second * 3)
}
}()
select {
case res := <-c1:
s.Say(fmt.Sprintf("Server Instance terminated. Server InstanceNo is %s", serverInstanceNo))
return res
case <-time.After(time.Second * 60):
return errors.New("TIMEOUT : Can't terminate server instance")
}
}
func (s *StepTerminateServerInstance) terminateVpcServerInstance(serverInstanceNo string) error {
reqParams := &vserver.TerminateServerInstancesRequest{
ServerInstanceNoList: []*string{&serverInstanceNo},
}
_, err := s.Conn.vserver.V2Api.TerminateServerInstances(reqParams)
if err != nil {
return err
}
s.Say(fmt.Sprintf("Server Instance is terminating. Server InstanceNo is %s", serverInstanceNo))
c1 := make(chan error, 1)
go func() {
reqParams := &vserver.GetServerInstanceListRequest{
RegionCode: &s.Config.RegionCode,
ServerInstanceNoList: []*string{&serverInstanceNo},
}
for {
serverInstanceList, err := s.Conn.vserver.V2Api.GetServerInstanceList(reqParams)
if err != nil {
c1 <- err
return
} else if *serverInstanceList.TotalRows == 0 {
c1 <- nil
return
}
log.Printf("Wating for terminating server instance [%s] is %s\n", serverInstanceNo, *serverInstanceList.ServerInstanceList[0].ServerInstanceStatus.Code)
time.Sleep(time.Second * 3)
}
}()
select {
case res := <-c1:
s.Say(fmt.Sprintf("Server Instance terminated. Server InstanceNo is %s", serverInstanceNo))
return res
case <-time.After(time.Second * 120):
return errors.New("TIMEOUT : Can't terminate server instance")
}
}
func (s *StepTerminateServerInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
s.Say("Terminate Server Instance")
var serverInstanceNo = state.Get("InstanceNo").(string)
var serverInstanceNo = state.Get("instance_no").(string)
err := s.TerminateServerInstance(serverInstanceNo)
@@ -23,7 +23,7 @@ func TestStepTerminateServerInstanceShouldFailIfOperationTerminationFails(t *tes
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -43,7 +43,7 @@ func TestStepTerminateServerInstanceShouldPassIfOperationTerminationPasses(t *te
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -51,6 +51,6 @@ func TestStepTerminateServerInstanceShouldPassIfOperationTerminationPasses(t *te
func createTestStateBagStepTerminateServerInstance() multistep.StateBag {
stateBag := new(multistep.BasicStateBag)
stateBag.Put("InstanceNo", "a")
stateBag.Put("instance_no", "a")
return stateBag
}
+264 -61
View File
@@ -5,6 +5,8 @@ import (
"context"
"errors"
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vpc"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"strings"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
@@ -16,14 +18,20 @@ import (
//StepValidateTemplate : struct for Validation a template
type StepValidateTemplate struct {
Conn *NcloudAPIClient
Validate func() error
Say func(message string)
Error func(e error)
Config *Config
zoneNo string
regionNo string
FeeSystemTypeCode string
Conn *NcloudAPIClient
Validate func() error
getZone func() error
getMemberServerImageList func() ([]*server.MemberServerImage, error)
getServerImageProductList func() ([]*server.Product, error)
getServerProductList func(serverImageProductCode string) ([]*server.Product, error)
Say func(message string)
Error func(e error)
Config *Config
zoneNo string
zoneCode string
regionNo string
regionCode string
FeeSystemTypeCode string
}
// NewStepValidateTemplate : function for Validation a template
@@ -35,6 +43,18 @@ func NewStepValidateTemplate(conn *NcloudAPIClient, ui packersdk.Ui, config *Con
Config: config,
}
if config.SupportVPC {
step.getZone = step.getZoneCode
step.getMemberServerImageList = step.getVpcMemberServerImageList
step.getServerImageProductList = step.getVpcServerImageProductList
step.getServerProductList = step.getVpcServerProductList
} else {
step.getZone = step.getZoneNo
step.getMemberServerImageList = step.getClassicMemberServerImageList
step.getServerImageProductList = step.getClassicServerImageProductList
step.getServerProductList = step.getClassicServerProductList
}
step.Validate = step.validateTemplate
return step
@@ -51,21 +71,19 @@ func (s *StepValidateTemplate) getZoneNo() error {
return err
}
var regionNo string
for _, region := range regionList.RegionList {
if strings.EqualFold(*region.RegionName, s.Config.Region) {
regionNo = *region.RegionNo
s.regionNo = *region.RegionNo
s.regionCode = *region.RegionCode
}
}
if regionNo == "" {
if s.regionNo == "" {
return fmt.Errorf("region %s is invalid", s.Config.Region)
}
s.regionNo = regionNo
// Get ZoneNo
resp, err := s.Conn.server.V2Api.GetZoneList(&server.GetZoneListRequest{RegionNo: &regionNo})
resp, err := s.Conn.server.V2Api.GetZoneList(&server.GetZoneListRequest{RegionNo: &s.regionNo})
if err != nil {
return err
}
@@ -77,19 +95,51 @@ func (s *StepValidateTemplate) getZoneNo() error {
return nil
}
func (s *StepValidateTemplate) validateMemberServerImage() error {
// getZoneCode : get zoneCode
func (s *StepValidateTemplate) getZoneCode() error {
if s.Config.Region == "" {
return nil
}
regionList, err := s.Conn.vserver.V2Api.GetRegionList(&vserver.GetRegionListRequest{})
if err != nil {
return err
}
for _, region := range regionList.RegionList {
if strings.EqualFold(*region.RegionName, s.Config.Region) {
s.regionCode = *region.RegionCode
s.Config.RegionCode = *region.RegionCode
}
}
if s.regionCode == "" {
return fmt.Errorf("region %s is invalid", s.Config.Region)
}
// Get ZoneNo
resp, err := s.Conn.vserver.V2Api.GetZoneList(&vserver.GetZoneListRequest{RegionCode: &s.regionCode})
if err != nil {
return err
}
if len(resp.ZoneList) > 0 {
s.zoneCode = *resp.ZoneList[0].ZoneCode
}
return nil
}
func (s *StepValidateTemplate) validateMemberServerImage(fnGetServerImageList func() ([]*server.MemberServerImage, error)) error {
var serverImageName = s.Config.ServerImageName
reqParams := new(server.GetMemberServerImageListRequest)
reqParams.RegionNo = &s.regionNo
memberServerImageList, err := s.Conn.server.V2Api.GetMemberServerImageList(reqParams)
memberServerImageList, err := fnGetServerImageList()
if err != nil {
return err
}
var isExistMemberServerImageNo = false
for _, image := range memberServerImageList.MemberServerImageList {
for _, image := range memberServerImageList {
// Check duplicate server_image_name
if *image.MemberServerImageName == serverImageName {
return fmt.Errorf("server_image_name %s is exists", serverImageName)
@@ -112,16 +162,84 @@ func (s *StepValidateTemplate) validateMemberServerImage() error {
return nil
}
func (s *StepValidateTemplate) getClassicMemberServerImageList() ([]*server.MemberServerImage, error) {
reqParams := &server.GetMemberServerImageListRequest{
RegionNo: &s.regionNo,
}
resp, err := s.Conn.server.V2Api.GetMemberServerImageList(reqParams)
if err != nil {
return nil, err
}
return resp.MemberServerImageList, nil
}
func (s *StepValidateTemplate) getVpcMemberServerImageList() ([]*server.MemberServerImage, error) {
reqParams := &vserver.GetMemberServerImageInstanceListRequest{
RegionCode: &s.regionCode,
}
memberServerImageList, err := s.Conn.vserver.V2Api.GetMemberServerImageInstanceList(reqParams)
if err != nil {
return nil, err
}
var results []*server.MemberServerImage
for _, r := range memberServerImageList.MemberServerImageInstanceList {
results = append(results, &server.MemberServerImage{
MemberServerImageNo: r.MemberServerImageInstanceNo,
MemberServerImageName: r.MemberServerImageName,
MemberServerImageDescription: r.MemberServerImageDescription,
OriginalServerInstanceNo: r.OriginalServerInstanceNo,
OriginalServerProductCode: r.OriginalServerImageProductCode,
})
}
return results, nil
}
func (s *StepValidateTemplate) getClassicServerImageProductList() ([]*server.Product, error) {
reqParams := &server.GetServerImageProductListRequest{
RegionNo: &s.regionNo,
}
resp, err := s.Conn.server.V2Api.GetServerImageProductList(reqParams)
if err != nil {
return nil, err
}
return resp.ProductList, nil
}
func (s *StepValidateTemplate) getVpcServerImageProductList() ([]*server.Product, error) {
reqParams := &vserver.GetServerImageProductListRequest{
RegionCode: &s.regionCode,
}
resp, err := s.Conn.vserver.V2Api.GetServerImageProductList(reqParams)
if err != nil {
return nil, err
}
var results []*server.Product
for _, r := range resp.ProductList {
results = append(results, &server.Product{
ProductCode: r.ProductCode,
ProductName: r.ProductName,
})
}
return results, nil
}
func (s *StepValidateTemplate) validateServerImageProduct() error {
var serverImageProductCode = s.Config.ServerImageProductCode
if serverImageProductCode == "" {
return nil
}
reqParams := new(server.GetServerImageProductListRequest)
reqParams.RegionNo = &s.regionNo
serverImageProductList, err := s.Conn.server.V2Api.GetServerImageProductList(reqParams)
serverImageProductList, err := s.getServerImageProductList()
if err != nil {
return err
}
@@ -132,7 +250,7 @@ func (s *StepValidateTemplate) validateServerImageProduct() error {
table := tablewriter.NewWriter(&buf)
table.SetHeader([]string{"Name", "Code"})
for _, product := range serverImageProductList.ProductList {
for _, product := range serverImageProductList {
// Check exist server image product code
if *product.ProductCode == serverImageProductCode {
isExistServerImage = true
@@ -143,26 +261,6 @@ func (s *StepValidateTemplate) validateServerImageProduct() error {
table.Append([]string{*product.ProductName, *product.ProductCode})
}
if !isExistServerImage {
reqParams.BlockStorageSize = ncloud.Int32(100)
serverImageProductList, err := s.Conn.server.V2Api.GetServerImageProductList(reqParams)
if err != nil {
return err
}
for _, product := range serverImageProductList.ProductList {
// Check exist server image product code
if *product.ProductCode == serverImageProductCode {
isExistServerImage = true
productName = *product.ProductName
break
}
table.Append([]string{*product.ProductName, *product.ProductCode})
}
}
if !isExistServerImage {
table.Render()
s.Say(buf.String())
@@ -177,21 +275,63 @@ func (s *StepValidateTemplate) validateServerImageProduct() error {
return nil
}
func (s *StepValidateTemplate) getClassicServerProductList(serverImageProductCode string) ([]*server.Product, error) {
reqParams := &server.GetServerProductListRequest{
ServerImageProductCode: &serverImageProductCode,
RegionNo: &s.regionNo,
}
resp, err := s.Conn.server.V2Api.GetServerProductList(reqParams)
if err != nil {
return nil, err
}
return resp.ProductList, nil
}
func (s *StepValidateTemplate) getVpcServerProductList(serverImageProductCode string) ([]*server.Product, error) {
reqParams := &vserver.GetServerProductListRequest{
ServerImageProductCode: &serverImageProductCode,
RegionCode: &s.regionCode,
}
resp, err := s.Conn.vserver.V2Api.GetServerProductList(reqParams)
if err != nil {
return nil, err
}
var results []*server.Product
for _, r := range resp.ProductList {
results = append(results, &server.Product{
ProductCode: r.ProductCode,
ProductName: r.ProductName,
ProductType: &server.CommonCode{
Code: r.ProductType.Code,
CodeName: r.ProductType.CodeName,
},
})
}
return results, nil
}
func (s *StepValidateTemplate) validateServerProductCode() error {
var serverImageProductCode = s.Config.ServerImageProductCode
var productCode = s.Config.ServerProductCode
reqParams := new(server.GetServerProductListRequest)
reqParams.ServerImageProductCode = &serverImageProductCode
reqParams.RegionNo = &s.regionNo
resp, err := s.Conn.server.V2Api.GetServerProductList(reqParams)
productList, err := s.getServerProductList(serverImageProductCode)
if err != nil {
return err
}
if productCode == "" {
return nil
}
var isExistProductCode = false
for _, product := range resp.ProductList {
for _, product := range productList {
// Check exist server image product code
if *product.ProductCode == productCode {
isExistProductCode = true
@@ -203,11 +343,6 @@ func (s *StepValidateTemplate) validateServerProductCode() error {
return errors.New("You cannot create my server image for VDS servers")
}
break
} else if productCode == "" && *product.ProductType.Code == "STAND" {
isExistProductCode = true
s.Config.ServerProductCode = *product.ProductCode
s.Say("server_product_code '" + *product.ProductCode + "' is configured automatically")
break
}
}
@@ -216,7 +351,7 @@ func (s *StepValidateTemplate) validateServerProductCode() error {
var buf bytes.Buffer
table := tablewriter.NewWriter(&buf)
table.SetHeader([]string{"Name", "Code"})
for _, product := range resp.ProductList {
for _, product := range productList {
table.Append([]string{*product.ProductName, *product.ProductCode})
}
table.Render()
@@ -229,15 +364,78 @@ func (s *StepValidateTemplate) validateServerProductCode() error {
return nil
}
func (s *StepValidateTemplate) validateVpc() error {
if !s.Config.SupportVPC {
return nil
}
if s.Config.VpcNo != "" {
reqParam := &vpc.GetVpcDetailRequest{
RegionCode: &s.Config.RegionCode,
VpcNo: &s.Config.VpcNo,
}
resp, err := s.Conn.vpc.V2Api.GetVpcDetail(reqParam)
if err != nil {
return err
}
if resp == nil || *resp.TotalRows == 0 {
return fmt.Errorf("cloud not found VPC `vpc_no` [%s]", s.Config.VpcNo)
}
}
if s.Config.SubnetNo != "" {
reqParam := &vpc.GetSubnetDetailRequest{
RegionCode: &s.Config.RegionCode,
SubnetNo: &s.Config.SubnetNo,
}
resp, err := s.Conn.vpc.V2Api.GetSubnetDetail(reqParam)
if err != nil {
return err
}
if resp != nil && *resp.TotalRows > 0 && *resp.SubnetList[0].SubnetType.Code == "PUBLIC" {
s.Config.VpcNo = *resp.SubnetList[0].VpcNo
s.Say("Set `vpc_no` is " + s.Config.VpcNo)
} else {
return fmt.Errorf("cloud not found public subnet in `subnet_no` [%s]", s.Config.SubnetNo)
}
}
if s.Config.VpcNo != "" && s.Config.SubnetNo == "" {
reqParam := &vpc.GetSubnetListRequest{
RegionCode: &s.Config.RegionCode,
VpcNo: &s.Config.VpcNo,
SubnetTypeCode: ncloud.String("PUBLIC"),
}
resp, err := s.Conn.vpc.V2Api.GetSubnetList(reqParam)
if err != nil {
return err
}
if resp != nil && *resp.TotalRows > 0 {
s.Config.SubnetNo = *resp.SubnetList[0].SubnetNo
s.Say("Set `subnet_no` is " + s.Config.SubnetNo)
} else {
return fmt.Errorf("cloud not found public subnet in `vpc_no` [%s]", s.Config.VpcNo)
}
}
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 {
if err := s.getZone(); err != nil {
return err
}
// Validate member_server_image_no and member_server_image_no
if err := s.validateMemberServerImage(); err != nil {
if err := s.validateMemberServerImage(s.getMemberServerImageList); err != nil {
return err
}
@@ -246,6 +444,11 @@ func (s *StepValidateTemplate) validateTemplate() error {
return err
}
// Validate VPC
if err := s.validateVpc(); err != nil {
return err
}
// Validate server_product_code
return s.validateServerProductCode()
}
@@ -256,10 +459,10 @@ func (s *StepValidateTemplate) Run(ctx context.Context, state multistep.StateBag
err := s.Validate()
state.Put("ZoneNo", s.zoneNo)
state.Put("zone_no", s.zoneNo)
if s.FeeSystemTypeCode != "" {
state.Put("FeeSystemTypeCode", s.FeeSystemTypeCode)
state.Put("fee_system_type_code", s.FeeSystemTypeCode)
}
return processStepResult(err, s.Error, state)
@@ -23,7 +23,7 @@ func TestStepValidateTemplateShouldFailIfValidateFails(t *testing.T) {
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == false {
if _, ok := stateBag.GetOk("error"); ok == false {
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
}
}
@@ -43,7 +43,7 @@ func TestStepValidateTemplateShouldPassIfValidatePasses(t *testing.T) {
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
}
if _, ok := stateBag.GetOk("Error"); ok == true {
if _, ok := stateBag.GetOk("error"); ok == true {
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
}
}
@@ -2,15 +2,17 @@ package ncloud
import (
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
)
func waiterBlockStorageInstanceStatus(conn *NcloudAPIClient, blockStorageInstanceNo *string, status string, timeout time.Duration) error {
reqParams := new(server.GetBlockStorageInstanceListRequest)
reqParams.BlockStorageInstanceNoList = []*string{blockStorageInstanceNo}
func waiterClassicBlockStorageStatus(conn *NcloudAPIClient, blockStorageInstanceNo *string, status string, timeout time.Duration) error {
reqParams := &server.GetBlockStorageInstanceListRequest{
BlockStorageInstanceNoList: []*string{blockStorageInstanceNo},
}
c1 := make(chan error, 1)
@@ -49,12 +51,54 @@ func waiterBlockStorageInstanceStatus(conn *NcloudAPIClient, blockStorageInstanc
}
}
func waiterDetachedBlockStorageInstance(conn *NcloudAPIClient, serverInstanceNo string, timeout time.Duration) error {
reqParams := new(server.GetBlockStorageInstanceListRequest)
reqParams.ServerInstanceNo = &serverInstanceNo
func waiterVpcBlockStorageStatus(conn *NcloudAPIClient, blockStorageInstanceNo *string, status string, timeout time.Duration) error {
reqParams := &vserver.GetBlockStorageInstanceListRequest{
BlockStorageInstanceNoList: []*string{blockStorageInstanceNo},
}
c1 := make(chan error, 1)
go func() {
for {
blockStorageInstanceList, err := conn.vserver.V2Api.GetBlockStorageInstanceList(reqParams)
if err != nil {
c1 <- err
return
}
if status == "DETAC" && len(blockStorageInstanceList.BlockStorageInstanceList) == 0 {
c1 <- nil
return
}
blockStorageInstance := blockStorageInstanceList.BlockStorageInstanceList[0]
code := blockStorageInstance.BlockStorageInstanceStatus.Code
operationCode := blockStorageInstance.BlockStorageInstanceOperation.Code
if *code == status && *operationCode == "NULL" {
c1 <- nil
return
}
log.Println(blockStorageInstance)
time.Sleep(time.Second * 5)
}
}()
select {
case res := <-c1:
return res
case <-time.After(timeout):
return fmt.Errorf("TIMEOUT : block storage instance status is not changed into status %s", status)
}
}
func waiterClassicDetachedBlockStorage(conn *NcloudAPIClient, serverInstanceNo string, timeout time.Duration) error {
reqParams := &server.GetBlockStorageInstanceListRequest{
ServerInstanceNo: &serverInstanceNo,
}
c1 := make(chan error, 1)
go func() {
for {
blockStorageInstanceList, err := conn.server.V2Api.GetBlockStorageInstanceList(reqParams)
@@ -79,3 +123,34 @@ func waiterDetachedBlockStorageInstance(conn *NcloudAPIClient, serverInstanceNo
return fmt.Errorf("TIMEOUT : attached block storage instance is not detached")
}
}
func waiterVpcDetachedBlockStorage(conn *NcloudAPIClient, serverInstanceNo string, timeout time.Duration) error {
reqParams := &vserver.GetBlockStorageInstanceListRequest{
ServerInstanceNo: &serverInstanceNo,
}
c1 := make(chan error, 1)
go func() {
for {
blockStorageInstanceList, err := conn.vserver.V2Api.GetBlockStorageInstanceList(reqParams)
if err != nil {
c1 <- err
return
}
if *blockStorageInstanceList.TotalRows == 1 {
c1 <- nil
return
}
time.Sleep(time.Second * 5)
}
}()
select {
case res := <-c1:
return res
case <-time.After(timeout):
return fmt.Errorf("TIMEOUT : attached block storage instance is not detached")
}
}
+39 -4
View File
@@ -2,15 +2,17 @@ package ncloud
import (
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
)
func waiterMemberServerImageStatus(conn *NcloudAPIClient, memberServerImageNo string, status string, timeout time.Duration) error {
reqParams := new(server.GetMemberServerImageListRequest)
reqParams.MemberServerImageNoList = []*string{&memberServerImageNo}
func waiterClassicMemberServerImageStatus(conn *NcloudAPIClient, memberServerImageNo string, status string, timeout time.Duration) error {
reqParams := &server.GetMemberServerImageListRequest{
MemberServerImageNoList: []*string{&memberServerImageNo},
}
c1 := make(chan error, 1)
@@ -29,7 +31,40 @@ func waiterMemberServerImageStatus(conn *NcloudAPIClient, memberServerImageNo st
}
log.Printf("Status of member server image [%s] is %s\n", memberServerImageNo, *code)
log.Println(memberServerImageList.MemberServerImageList[0])
time.Sleep(time.Second * 5)
}
}()
select {
case res := <-c1:
return res
case <-time.After(timeout):
return fmt.Errorf("TIMEOUT : member server image status is not changed into status %s", status)
}
}
func waiterVpcMemberServerImageStatus(conn *NcloudAPIClient, memberServerImageNo string, status string, timeout time.Duration) error {
reqParams := &vserver.GetMemberServerImageInstanceDetailRequest{
MemberServerImageInstanceNo: &memberServerImageNo,
}
c1 := make(chan error, 1)
go func() {
for {
memberServerImageList, err := conn.vserver.V2Api.GetMemberServerImageInstanceDetail(reqParams)
if err != nil {
c1 <- err
return
}
code := memberServerImageList.MemberServerImageInstanceList[0].MemberServerImageInstanceStatus.Code
if *code == status {
c1 <- nil
return
}
log.Printf("Status of member server image [%s] is %s\n", memberServerImageNo, *code)
time.Sleep(time.Second * 5)
}
}()
@@ -2,13 +2,14 @@ package ncloud
import (
"fmt"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
"log"
"time"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
)
func waiterServerInstanceStatus(conn *NcloudAPIClient, serverInstanceNo string, status string, timeout time.Duration) error {
func waiterClassicServerInstanceStatus(conn *NcloudAPIClient, serverInstanceNo string, status string, timeout time.Duration) error {
reqParams := new(server.GetServerInstanceListRequest)
reqParams.ServerInstanceNoList = []*string{&serverInstanceNo}
@@ -29,7 +30,40 @@ func waiterServerInstanceStatus(conn *NcloudAPIClient, serverInstanceNo string,
}
log.Printf("Status of serverInstanceNo [%s] is %s\n", serverInstanceNo, *code)
log.Println(serverInstanceList.ServerInstanceList[0])
time.Sleep(time.Second * 5)
}
}()
select {
case res := <-c1:
return res
case <-time.After(timeout):
return fmt.Errorf("TIMEOUT : server instance status is not changed into status %s", status)
}
}
func waiterVpcServerInstanceStatus(conn *NcloudAPIClient, serverInstanceNo string, status string, timeout time.Duration) error {
reqParams := &vserver.GetServerInstanceDetailRequest{
ServerInstanceNo: &serverInstanceNo,
}
c1 := make(chan error, 1)
go func() {
for {
serverInstanceList, err := conn.vserver.V2Api.GetServerInstanceDetail(reqParams)
if err != nil {
c1 <- err
return
}
code := serverInstanceList.ServerInstanceList[0].ServerInstanceStatus.Code
if *code == status {
c1 <- nil
return
}
log.Printf("Status of serverInstanceNo [%s] is %s\n", serverInstanceNo, *code)
time.Sleep(time.Second * 5)
}
}()
+1 -1
View File
@@ -11,7 +11,7 @@ require (
github.com/Azure/go-autorest/autorest/date v0.2.0
github.com/Azure/go-autorest/autorest/to v0.3.0
github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.0
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.7
github.com/Telmate/proxmox-api-go v0.0.0-20200715182505-ec97c70ba887
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20170113022742-e6dbea820a9f
+2
View File
@@ -81,6 +81,8 @@ github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022/go.mod h1:nu
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.0 h1:0nxjOH7NurPGUWNG5BCrASWjB0uuhGbgJAKLqj2ZDTo=
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.0/go.mod h1:P+3VS0ETiQPyWOx3vB/oeC8J3qd7jnVZLYAFwWgGRt8=
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.7 h1:Kpnbe19WkzVPpLLdAus4LkpNJ+pzLpfAViOUuvPcCqA=
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.7/go.mod h1:P+3VS0ETiQPyWOx3vB/oeC8J3qd7jnVZLYAFwWgGRt8=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/Telmate/proxmox-api-go v0.0.0-20200715182505-ec97c70ba887 h1:Q65o4V0g/KR1sSUZIMf4m1rShb7f1tVHuEt30hfnh2A=
@@ -0,0 +1,18 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type ChangeBlockStorageVolumeSizeRequest struct {
// 블록스토리지인스턴스번호
BlockStorageInstanceNo *string `json:"blockStorageInstanceNo"`
// 블록스토리지사이즈
BlockStorageSize *int64 `json:"blockStorageSize"`
}
@@ -0,0 +1,22 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type ChangeBlockStorageVolumeSizeResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
BlockStorageInstanceList []*BlockStorageInstance `json:"blockStorageInstanceList,omitempty"`
}
@@ -0,0 +1,12 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type GetInitScriptListRequest struct {
}
@@ -0,0 +1,22 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type GetInitScriptListResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
InitScriptList []*InitScript `json:"initScriptList,omitempty"`
}
@@ -0,0 +1,15 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type GetRootPasswordServerInstanceListRequest struct {
// 인스턴스태그리스트
RootPasswordServerInstanceList []*RootPasswordServerInstanceParameter `json:"rootPasswordServerInstanceList"`
}
@@ -0,0 +1,22 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type GetRootPasswordServerInstanceListResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
RootPasswordServerInstanceList []*RootPasswordServerInstance `json:"rootPasswordServerInstanceList,omitempty"`
}
@@ -0,0 +1,30 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type InitScript struct {
// 초기화스크립트번호
InitScriptNo *string `json:"initScriptNo,omitempty"`
// 초기화스크립트명
InitScriptName *string `json:"initScriptName,omitempty"`
// 생성일자
CreateDate *string `json:"createDate,omitempty"`
// 초기화스크립트설명
InitScriptDescription *string `json:"initScriptDescription,omitempty"`
// 초기화스크립트내용
InitScriptContent *string `json:"initScriptContent,omitempty"`
// OS구분
OsType *CommonCode `json:"osType,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type ReplaceServerInstanceAssociatedWithPublicIpRequest struct {
// 공인IP인스턴스번호
PublicIpInstanceNo *string `json:"publicIpInstanceNo"`
// 서버인스턴스번호
ServerInstanceNo *string `json:"serverInstanceNo"`
}
@@ -0,0 +1,22 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type ReplaceServerInstanceAssociatedWithPublicIpResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
PublicIpInstanceList []*PublicIpInstance `json:"publicIpInstanceList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type RootPasswordServerInstance struct {
// 서버인스턴스번호
ServerInstanceNo *string `json:"serverInstanceNo,omitempty"`
// 루트패스워드
RootPassword *string `json:"rootPassword,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* server
*
* <br/>https://ncloud.apigw.ntruss.com/server/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package server
type RootPasswordServerInstanceParameter struct {
// 서버인스턴스번호
ServerInstanceNo *string `json:"serverInstanceNo,omitempty"`
// 사설키
PrivateKey *string `json:"privateKey,omitempty"`
}
@@ -0,0 +1,8 @@
language: go
install:
- go get -d -v .
script:
- go build -v ./
@@ -0,0 +1,7 @@
Copyright 2018 NAVER BUSINESS PLATFORM Corp.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,163 @@
# Go API client for vpc
VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
## Overview
This API client was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the [swagger-spec](https://github.com/swagger-api/swagger-spec) from a remote server, you can easily generate an API client.
- API version: 2020-09-17T10:29:55Z
- Package version: 1.0.0
- Build package: io.swagger.codegen.languages.NcpGoForNcloudClientCodegen
## Installation
Put the package under your project folder and add the following in import:
```
"./vpc"
```
## Documentation for API Endpoints
All URIs are relative to *https://ncloud.apigw.ntruss.com/vpc/v2*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*V2Api* | [**AcceptOrRejectVpcPeering**](docs/V2Api.md#acceptorrejectvpcpeering) | **Post** /acceptOrRejectVpcPeering |
*V2Api* | [**AddNetworkAclInboundRule**](docs/V2Api.md#addnetworkaclinboundrule) | **Post** /addNetworkAclInboundRule |
*V2Api* | [**AddNetworkAclOutboundRule**](docs/V2Api.md#addnetworkacloutboundrule) | **Post** /addNetworkAclOutboundRule |
*V2Api* | [**AddRoute**](docs/V2Api.md#addroute) | **Post** /addRoute |
*V2Api* | [**AddRouteTableSubnet**](docs/V2Api.md#addroutetablesubnet) | **Post** /addRouteTableSubnet |
*V2Api* | [**CreateNatGatewayInstance**](docs/V2Api.md#createnatgatewayinstance) | **Post** /createNatGatewayInstance |
*V2Api* | [**CreateNetworkAcl**](docs/V2Api.md#createnetworkacl) | **Post** /createNetworkAcl |
*V2Api* | [**CreateRouteTable**](docs/V2Api.md#createroutetable) | **Post** /createRouteTable |
*V2Api* | [**CreateSubnet**](docs/V2Api.md#createsubnet) | **Post** /createSubnet |
*V2Api* | [**CreateVpc**](docs/V2Api.md#createvpc) | **Post** /createVpc |
*V2Api* | [**CreateVpcPeeringInstance**](docs/V2Api.md#createvpcpeeringinstance) | **Post** /createVpcPeeringInstance |
*V2Api* | [**DeleteNatGatewayInstance**](docs/V2Api.md#deletenatgatewayinstance) | **Post** /deleteNatGatewayInstance |
*V2Api* | [**DeleteNetworkAcl**](docs/V2Api.md#deletenetworkacl) | **Post** /deleteNetworkAcl |
*V2Api* | [**DeleteRouteTable**](docs/V2Api.md#deleteroutetable) | **Post** /deleteRouteTable |
*V2Api* | [**DeleteSubnet**](docs/V2Api.md#deletesubnet) | **Post** /deleteSubnet |
*V2Api* | [**DeleteVpc**](docs/V2Api.md#deletevpc) | **Post** /deleteVpc |
*V2Api* | [**DeleteVpcPeeringInstance**](docs/V2Api.md#deletevpcpeeringinstance) | **Post** /deleteVpcPeeringInstance |
*V2Api* | [**GetNatGatewayInstanceDetail**](docs/V2Api.md#getnatgatewayinstancedetail) | **Post** /getNatGatewayInstanceDetail |
*V2Api* | [**GetNatGatewayInstanceList**](docs/V2Api.md#getnatgatewayinstancelist) | **Post** /getNatGatewayInstanceList |
*V2Api* | [**GetNetworkAclDetail**](docs/V2Api.md#getnetworkacldetail) | **Post** /getNetworkAclDetail |
*V2Api* | [**GetNetworkAclList**](docs/V2Api.md#getnetworkacllist) | **Post** /getNetworkAclList |
*V2Api* | [**GetNetworkAclRuleList**](docs/V2Api.md#getnetworkaclrulelist) | **Post** /getNetworkAclRuleList |
*V2Api* | [**GetRouteList**](docs/V2Api.md#getroutelist) | **Post** /getRouteList |
*V2Api* | [**GetRouteTableDetail**](docs/V2Api.md#getroutetabledetail) | **Post** /getRouteTableDetail |
*V2Api* | [**GetRouteTableList**](docs/V2Api.md#getroutetablelist) | **Post** /getRouteTableList |
*V2Api* | [**GetRouteTableSubnetList**](docs/V2Api.md#getroutetablesubnetlist) | **Post** /getRouteTableSubnetList |
*V2Api* | [**GetSubnetDetail**](docs/V2Api.md#getsubnetdetail) | **Post** /getSubnetDetail |
*V2Api* | [**GetSubnetList**](docs/V2Api.md#getsubnetlist) | **Post** /getSubnetList |
*V2Api* | [**GetVpcDetail**](docs/V2Api.md#getvpcdetail) | **Post** /getVpcDetail |
*V2Api* | [**GetVpcList**](docs/V2Api.md#getvpclist) | **Post** /getVpcList |
*V2Api* | [**GetVpcPeeringInstanceDetail**](docs/V2Api.md#getvpcpeeringinstancedetail) | **Post** /getVpcPeeringInstanceDetail |
*V2Api* | [**GetVpcPeeringInstanceList**](docs/V2Api.md#getvpcpeeringinstancelist) | **Post** /getVpcPeeringInstanceList |
*V2Api* | [**RemoveNetworkAclInboundRule**](docs/V2Api.md#removenetworkaclinboundrule) | **Post** /removeNetworkAclInboundRule |
*V2Api* | [**RemoveNetworkAclOutboundRule**](docs/V2Api.md#removenetworkacloutboundrule) | **Post** /removeNetworkAclOutboundRule |
*V2Api* | [**RemoveRoute**](docs/V2Api.md#removeroute) | **Post** /removeRoute |
*V2Api* | [**RemoveRouteTableSubnet**](docs/V2Api.md#removeroutetablesubnet) | **Post** /removeRouteTableSubnet |
*V2Api* | [**SetNatGatewayDescription**](docs/V2Api.md#setnatgatewaydescription) | **Post** /setNatGatewayDescription |
*V2Api* | [**SetNetworkAclDescription**](docs/V2Api.md#setnetworkacldescription) | **Post** /setNetworkAclDescription |
*V2Api* | [**SetRouteTableDescription**](docs/V2Api.md#setroutetabledescription) | **Post** /setRouteTableDescription |
*V2Api* | [**SetSubnetNetworkAcl**](docs/V2Api.md#setsubnetnetworkacl) | **Post** /setSubnetNetworkAcl |
*V2Api* | [**SetVpcPeeringDescription**](docs/V2Api.md#setvpcpeeringdescription) | **Post** /setVpcPeeringDescription |
## Documentation For Models
- [AcceptOrRejectVpcPeeringRequest](docs/AcceptOrRejectVpcPeeringRequest.md)
- [AcceptOrRejectVpcPeeringResponse](docs/AcceptOrRejectVpcPeeringResponse.md)
- [AddNetworkAclInboundRuleRequest](docs/AddNetworkAclInboundRuleRequest.md)
- [AddNetworkAclInboundRuleResponse](docs/AddNetworkAclInboundRuleResponse.md)
- [AddNetworkAclOutboundRuleRequest](docs/AddNetworkAclOutboundRuleRequest.md)
- [AddNetworkAclOutboundRuleResponse](docs/AddNetworkAclOutboundRuleResponse.md)
- [AddNetworkAclRuleParameter](docs/AddNetworkAclRuleParameter.md)
- [AddRouteRequest](docs/AddRouteRequest.md)
- [AddRouteResponse](docs/AddRouteResponse.md)
- [AddRouteTableSubnetRequest](docs/AddRouteTableSubnetRequest.md)
- [AddRouteTableSubnetResponse](docs/AddRouteTableSubnetResponse.md)
- [CommonCode](docs/CommonCode.md)
- [CreateNatGatewayInstanceRequest](docs/CreateNatGatewayInstanceRequest.md)
- [CreateNatGatewayInstanceResponse](docs/CreateNatGatewayInstanceResponse.md)
- [CreateNetworkAclRequest](docs/CreateNetworkAclRequest.md)
- [CreateNetworkAclResponse](docs/CreateNetworkAclResponse.md)
- [CreateRouteTableRequest](docs/CreateRouteTableRequest.md)
- [CreateRouteTableResponse](docs/CreateRouteTableResponse.md)
- [CreateSubnetRequest](docs/CreateSubnetRequest.md)
- [CreateSubnetResponse](docs/CreateSubnetResponse.md)
- [CreateVpcPeeringInstanceRequest](docs/CreateVpcPeeringInstanceRequest.md)
- [CreateVpcPeeringInstanceResponse](docs/CreateVpcPeeringInstanceResponse.md)
- [CreateVpcRequest](docs/CreateVpcRequest.md)
- [CreateVpcResponse](docs/CreateVpcResponse.md)
- [DeleteNatGatewayInstanceRequest](docs/DeleteNatGatewayInstanceRequest.md)
- [DeleteNatGatewayInstanceResponse](docs/DeleteNatGatewayInstanceResponse.md)
- [DeleteNetworkAclRequest](docs/DeleteNetworkAclRequest.md)
- [DeleteNetworkAclResponse](docs/DeleteNetworkAclResponse.md)
- [DeleteRouteTableRequest](docs/DeleteRouteTableRequest.md)
- [DeleteRouteTableResponse](docs/DeleteRouteTableResponse.md)
- [DeleteSubnetRequest](docs/DeleteSubnetRequest.md)
- [DeleteSubnetResponse](docs/DeleteSubnetResponse.md)
- [DeleteVpcPeeringInstanceRequest](docs/DeleteVpcPeeringInstanceRequest.md)
- [DeleteVpcPeeringInstanceResponse](docs/DeleteVpcPeeringInstanceResponse.md)
- [DeleteVpcRequest](docs/DeleteVpcRequest.md)
- [DeleteVpcResponse](docs/DeleteVpcResponse.md)
- [GetNatGatewayInstanceDetailRequest](docs/GetNatGatewayInstanceDetailRequest.md)
- [GetNatGatewayInstanceDetailResponse](docs/GetNatGatewayInstanceDetailResponse.md)
- [GetNatGatewayInstanceListRequest](docs/GetNatGatewayInstanceListRequest.md)
- [GetNatGatewayInstanceListResponse](docs/GetNatGatewayInstanceListResponse.md)
- [GetNetworkAclDetailRequest](docs/GetNetworkAclDetailRequest.md)
- [GetNetworkAclDetailResponse](docs/GetNetworkAclDetailResponse.md)
- [GetNetworkAclListRequest](docs/GetNetworkAclListRequest.md)
- [GetNetworkAclListResponse](docs/GetNetworkAclListResponse.md)
- [GetNetworkAclRuleListRequest](docs/GetNetworkAclRuleListRequest.md)
- [GetNetworkAclRuleListResponse](docs/GetNetworkAclRuleListResponse.md)
- [GetRouteListRequest](docs/GetRouteListRequest.md)
- [GetRouteListResponse](docs/GetRouteListResponse.md)
- [GetRouteTableDetailRequest](docs/GetRouteTableDetailRequest.md)
- [GetRouteTableDetailResponse](docs/GetRouteTableDetailResponse.md)
- [GetRouteTableListRequest](docs/GetRouteTableListRequest.md)
- [GetRouteTableListResponse](docs/GetRouteTableListResponse.md)
- [GetRouteTableSubnetListRequest](docs/GetRouteTableSubnetListRequest.md)
- [GetRouteTableSubnetListResponse](docs/GetRouteTableSubnetListResponse.md)
- [GetSubnetDetailRequest](docs/GetSubnetDetailRequest.md)
- [GetSubnetDetailResponse](docs/GetSubnetDetailResponse.md)
- [GetSubnetListRequest](docs/GetSubnetListRequest.md)
- [GetSubnetListResponse](docs/GetSubnetListResponse.md)
- [GetVpcDetailRequest](docs/GetVpcDetailRequest.md)
- [GetVpcDetailResponse](docs/GetVpcDetailResponse.md)
- [GetVpcListRequest](docs/GetVpcListRequest.md)
- [GetVpcListResponse](docs/GetVpcListResponse.md)
- [GetVpcPeeringInstanceDetailRequest](docs/GetVpcPeeringInstanceDetailRequest.md)
- [GetVpcPeeringInstanceDetailResponse](docs/GetVpcPeeringInstanceDetailResponse.md)
- [GetVpcPeeringInstanceListRequest](docs/GetVpcPeeringInstanceListRequest.md)
- [GetVpcPeeringInstanceListResponse](docs/GetVpcPeeringInstanceListResponse.md)
- [NatGatewayInstance](docs/NatGatewayInstance.md)
- [NetworkAcl](docs/NetworkAcl.md)
- [NetworkAclRule](docs/NetworkAclRule.md)
- [RemoveNetworkAclInboundRuleRequest](docs/RemoveNetworkAclInboundRuleRequest.md)
- [RemoveNetworkAclInboundRuleResponse](docs/RemoveNetworkAclInboundRuleResponse.md)
- [RemoveNetworkAclOutboundRuleRequest](docs/RemoveNetworkAclOutboundRuleRequest.md)
- [RemoveNetworkAclOutboundRuleResponse](docs/RemoveNetworkAclOutboundRuleResponse.md)
- [RemoveNetworkAclRuleParameter](docs/RemoveNetworkAclRuleParameter.md)
- [RemoveRouteRequest](docs/RemoveRouteRequest.md)
- [RemoveRouteResponse](docs/RemoveRouteResponse.md)
- [RemoveRouteTableSubnetRequest](docs/RemoveRouteTableSubnetRequest.md)
- [RemoveRouteTableSubnetResponse](docs/RemoveRouteTableSubnetResponse.md)
- [Route](docs/Route.md)
- [RouteParameter](docs/RouteParameter.md)
- [RouteTable](docs/RouteTable.md)
- [SetNatGatewayDescriptionRequest](docs/SetNatGatewayDescriptionRequest.md)
- [SetNatGatewayDescriptionResponse](docs/SetNatGatewayDescriptionResponse.md)
- [SetNetworkAclDescriptionRequest](docs/SetNetworkAclDescriptionRequest.md)
- [SetNetworkAclDescriptionResponse](docs/SetNetworkAclDescriptionResponse.md)
- [SetRouteTableDescriptionRequest](docs/SetRouteTableDescriptionRequest.md)
- [SetRouteTableDescriptionResponse](docs/SetRouteTableDescriptionResponse.md)
- [SetSubnetNetworkAclRequest](docs/SetSubnetNetworkAclRequest.md)
- [SetSubnetNetworkAclResponse](docs/SetSubnetNetworkAclResponse.md)
- [SetVpcPeeringDescriptionRequest](docs/SetVpcPeeringDescriptionRequest.md)
- [SetVpcPeeringDescriptionResponse](docs/SetVpcPeeringDescriptionResponse.md)
- [Subnet](docs/Subnet.md)
- [Vpc](docs/Vpc.md)
- [VpcPeeringInstance](docs/VpcPeeringInstance.md)
@@ -0,0 +1,21 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AcceptOrRejectVpcPeeringRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// VPCPeering인스턴스번호
VpcPeeringInstanceNo *string `json:"vpcPeeringInstanceNo"`
// 수락여부
IsAccept *bool `json:"isAccept"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AcceptOrRejectVpcPeeringResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
VpcPeeringInstanceList []*VpcPeeringInstance `json:"vpcPeeringInstanceList,omitempty"`
}
@@ -0,0 +1,21 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddNetworkAclInboundRuleRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL번호
NetworkAclNo *string `json:"networkAclNo"`
// 네트워크ACLRule리스트
NetworkAclRuleList []*AddNetworkAclRuleParameter `json:"networkAclRuleList"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddNetworkAclInboundRuleResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclRuleList []*NetworkAclRule `json:"networkAclRuleList,omitempty"`
}
@@ -0,0 +1,21 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddNetworkAclOutboundRuleRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL번호
NetworkAclNo *string `json:"networkAclNo"`
// 네트워크ACLRule리스트
NetworkAclRuleList []*AddNetworkAclRuleParameter `json:"networkAclRuleList"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddNetworkAclOutboundRuleResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclRuleList []*NetworkAclRule `json:"networkAclRuleList,omitempty"`
}
@@ -0,0 +1,30 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddNetworkAclRuleParameter struct {
// 네트워크ACLRule설명
NetworkAclRuleDescription *string `json:"networkAclRuleDescription,omitempty"`
// IP블록
IpBlock *string `json:"ipBlock"`
// Rule액션코드
RuleActionCode *string `json:"ruleActionCode"`
// 포트범위
PortRange *string `json:"portRange,omitempty"`
// 우선순위
Priority *int32 `json:"priority"`
// 프로토콜유형코드
ProtocolTypeCode *string `json:"protocolTypeCode"`
}
@@ -0,0 +1,24 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddRouteRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 라우트리스트
RouteList []*RouteParameter `json:"routeList"`
// 라우트테이블번호
RouteTableNo *string `json:"routeTableNo"`
// VPC번호
VpcNo *string `json:"vpcNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddRouteResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
RouteList []*Route `json:"routeList,omitempty"`
}
@@ -0,0 +1,24 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddRouteTableSubnetRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 라우트테이블번호
RouteTableNo *string `json:"routeTableNo"`
// 서브넷번호리스트
SubnetNoList []*string `json:"subnetNoList"`
// VPC번호
VpcNo *string `json:"vpcNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type AddRouteTableSubnetResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
SubnetList []*Subnet `json:"subnetList,omitempty"`
}
@@ -0,0 +1,450 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
import (
"bytes"
"crypto"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"unicode"
"unicode/utf8"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/hmac"
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
)
var (
jsonCheck = regexp.MustCompile("(?i:[application|text]/json)")
xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)")
)
// APIClient manages communication with the vpc API v2020-09-17T10:29:55Z
// In most cases there should be only one, shared, APIClient.
type APIClient struct {
cfg *ncloud.Configuration
common service // Reuse a single struct instead of allocating one for each service on the heap.
// API Services
V2Api *V2ApiService
}
type service struct {
client *APIClient
}
// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
// optionally a custom http.Client to allow for advanced features such as caching.
func NewAPIClient(cfg *ncloud.Configuration) *APIClient {
if cfg.HTTPClient == nil {
cfg.HTTPClient = http.DefaultClient
}
c := &APIClient{}
c.cfg = cfg
c.common.client = c
// API Services
c.V2Api = (*V2ApiService)(&c.common)
return c
}
func atoi(in string) (int, error) {
return strconv.Atoi(in)
}
// selectHeaderContentType select a content type from the available list.
func selectHeaderContentType(contentTypes []string) string {
if len(contentTypes) == 0 {
return ""
}
if contains(contentTypes, "application/json") {
return "application/json"
}
return contentTypes[0] // use the first content type specified in 'consumes'
}
// selectHeaderAccept join all accept types and return
func selectHeaderAccept(accepts []string) string {
if len(accepts) == 0 {
return ""
}
if contains(accepts, "application/json") {
return "application/json"
}
return strings.Join(accepts, ",")
}
// contains is a case insenstive match, finding needle in a haystack
func contains(haystack []string, needle string) bool {
for _, a := range haystack {
if strings.ToLower(a) == strings.ToLower(needle) {
return true
}
}
return false
}
// Verify optional parameters are of the correct type.
func typeCheckParameter(obj interface{}, expected string, name string) error {
// Make sure there is an object.
if obj == nil {
return nil
}
// Check the type is as expected.
if reflect.TypeOf(obj).String() != expected {
return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String())
}
return nil
}
// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
func parameterToString(obj interface{}, collectionFormat string) string {
var delimiter string
switch collectionFormat {
case "pipes":
delimiter = "|"
case "ssv":
delimiter = " "
case "tsv":
delimiter = "\t"
case "csv":
delimiter = ","
}
if reflect.TypeOf(obj).Kind() == reflect.Slice {
return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
}
return fmt.Sprintf("%v", obj)
}
// callAPI do the request.
func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
return c.cfg.HTTPClient.Do(request)
}
// Change base path to allow switching to mocks
func (c *APIClient) ChangeBasePath(path string) {
c.cfg.BasePath = path
}
// prepareRequest build the request
func (c *APIClient) prepareRequest(
path string,
method string,
postBody interface{},
headerParams map[string]string,
queryParams url.Values,
formParams url.Values,
fileName string,
fileBytes []byte) (localVarRequest *http.Request, err error) {
var body *bytes.Buffer
// Detect postBody type and post.
if postBody != nil {
contentType := headerParams["Content-Type"]
if contentType == "" {
contentType = detectContentType(postBody)
headerParams["Content-Type"] = contentType
}
body, err = setBody(postBody, contentType)
if err != nil {
return nil, err
}
}
// add form parameters and file if available.
if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") {
if body != nil {
return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
}
body = &bytes.Buffer{}
w := multipart.NewWriter(body)
for k, v := range formParams {
for _, iv := range v {
if strings.HasPrefix(k, "@") { // file
err = addFile(w, k[1:], iv)
if err != nil {
return nil, err
}
} else { // form value
w.WriteField(k, iv)
}
}
}
if len(fileBytes) > 0 && fileName != "" {
w.Boundary()
//_, fileNm := filepath.Split(fileName)
part, err := w.CreateFormFile("file", filepath.Base(fileName))
if err != nil {
return nil, err
}
_, err = part.Write(fileBytes)
if err != nil {
return nil, err
}
// Set the Boundary in the Content-Type
headerParams["Content-Type"] = w.FormDataContentType()
}
// Set Content-Length
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
w.Close()
}
// Setup path and query parameters
url, err := url.Parse(path)
if err != nil {
return nil, err
}
// Adding Query Param
query := url.Query()
for k, v := range queryParams {
for _, iv := range v {
query.Add(k, iv)
}
}
// Encode the parameters.
url.RawQuery = query.Encode()
// Generate a new request
if body != nil {
localVarRequest, err = http.NewRequest(method, url.String(), body)
} else {
localVarRequest, err = http.NewRequest(method, url.String(), nil)
}
if err != nil {
return nil, err
}
// add header parameters, if any
if len(headerParams) > 0 {
headers := http.Header{}
for h, v := range headerParams {
headers.Set(h, v)
}
localVarRequest.Header = headers
}
// Override request host, if applicable
if c.cfg.Host != "" {
localVarRequest.Host = c.cfg.Host
}
// Add the user agent to the request.
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
// APIKey Authentication
if auth := c.cfg.APIKey; auth != nil {
timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10)
signer := hmac.NewSigner(auth.SecretKey, crypto.SHA256)
signature, _ := signer.Sign(method, path, auth.AccessKey, timestamp)
localVarRequest.Header.Add("x-ncp-apigw-timestamp", timestamp)
localVarRequest.Header.Add("x-ncp-iam-access-key", auth.AccessKey)
localVarRequest.Header.Add("x-ncp-apigw-signature-v1", signature)
}
for header, value := range c.cfg.DefaultHeader {
localVarRequest.Header.Add(header, value)
}
return localVarRequest, nil
}
// Add a file to the multipart request
func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {
return err
}
_, err = io.Copy(part, file)
return err
}
// Prevent trying to import "fmt"
func reportError(format string, a ...interface{}) error {
return fmt.Errorf(format, a...)
}
func toLowerFirstChar(s string) string {
a := []rune(s)
a[0] = unicode.ToLower(a[0])
return string(a)
}
// Set request body from an interface{}
func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
if bodyBuf == nil {
bodyBuf = &bytes.Buffer{}
}
bodyBuf.WriteString("responseFormatType=json")
s := reflect.ValueOf(body).Elem()
bodyBuf.WriteString(buildQueryString(s, ""))
if err != nil {
return nil, err
}
if bodyBuf.Len() == 0 {
err = fmt.Errorf("invalid body type %s", contentType)
return nil, err
}
return bodyBuf, nil
}
func buildQueryString(s reflect.Value, prefix string) string {
bodyBuf := &bytes.Buffer{}
if s.Kind() == reflect.Struct {
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
if !f.IsNil() {
name := toLowerFirstChar(s.Type().Field(i).Name)
if len(prefix) > 0 {
bodyBuf.WriteString(buildQueryString(f, fmt.Sprintf("%s.%s", prefix, name)))
} else {
bodyBuf.WriteString(buildQueryString(f, name))
}
}
}
} else if s.Kind() == reflect.Slice {
for i := 0; i < s.Len(); i++ {
item := s.Index(i)
bodyBuf.WriteString(buildQueryString(item.Elem(), fmt.Sprintf("%s.%d", prefix, i+1)))
}
} else if s.Kind() == reflect.Ptr {
bodyBuf.WriteString(fmt.Sprintf("&%s=%s", prefix, convertToString(s)))
} else if s.Kind() == reflect.String {
bodyBuf.WriteString(fmt.Sprintf("&%s=%s", prefix, s.Interface()))
}
return bodyBuf.String()
}
func convertToString(f reflect.Value) string {
switch f.Type().String() {
case "*string":
return url.QueryEscape(ncloud.StringValue(f.Interface().(*string)))
case "*bool":
return fmt.Sprintf("%t", *f.Interface().(*bool))
case "*int":
return fmt.Sprintf("%d", *f.Interface().(*int))
case "*int32":
return fmt.Sprintf("%d", *f.Interface().(*int32))
case "*int64":
return fmt.Sprintf("%d", *f.Interface().(*int64))
case "*float32":
return fmt.Sprintf("%f", *f.Interface().(*float32))
}
return ""
}
// detectContentType method is used to figure out `Request.Body` content type for request header
func detectContentType(body interface{}) string {
contentType := "text/plain; charset=utf-8"
kind := reflect.TypeOf(body).Kind()
switch kind {
case reflect.Struct, reflect.Map, reflect.Ptr:
contentType = "application/json; charset=utf-8"
case reflect.String:
contentType = "text/plain; charset=utf-8"
default:
if b, ok := body.([]byte); ok {
contentType = http.DetectContentType(b)
} else if kind == reflect.Slice {
contentType = "application/json; charset=utf-8"
}
}
return contentType
}
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
type cacheControl map[string]string
func parseCacheControl(headers http.Header) cacheControl {
cc := cacheControl{}
ccHeader := headers.Get("Cache-Control")
for _, part := range strings.Split(ccHeader, ",") {
part = strings.Trim(part, " ")
if part == "" {
continue
}
if strings.ContainsRune(part, '=') {
keyval := strings.Split(part, "=")
cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
} else {
cc[part] = ""
}
}
return cc
}
// CacheExpires helper function to determine remaining time before repeating a request.
func CacheExpires(r *http.Response) time.Time {
// Figure out when the cache expires.
var expires time.Time
now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
if err != nil {
return time.Now()
}
respCacheControl := parseCacheControl(r.Header)
if maxAge, ok := respCacheControl["max-age"]; ok {
lifetime, err := time.ParseDuration(maxAge + "s")
if err != nil {
expires = now
}
expires = now.Add(lifetime)
} else {
expiresHeader := r.Header.Get("Expires")
if expiresHeader != "" {
expires, err = time.Parse(time.RFC1123, expiresHeader)
if err != nil {
expires = now
}
}
}
return expires
}
func strlen(s string) int {
return utf8.RuneCountInString(s)
}
@@ -0,0 +1,42 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
import (
"net/http"
)
type APIResponse struct {
*http.Response `json:"-"`
Message string `json:"message,omitempty"`
// Operation is the name of the swagger operation.
Operation string `json:"operation,omitempty"`
// RequestURL is the request URL. This value is always available, even if the
// embedded *http.Response is nil.
RequestURL string `json:"url,omitempty"`
// Method is the HTTP method used for the request. This value is always
// available, even if the embedded *http.Response is nil.
Method string `json:"method,omitempty"`
// Payload holds the contents of the response body (which may be nil or empty).
// This is provided here as the raw response.Body() reader will have already
// been drained.
Payload []byte `json:"-"`
}
func NewAPIResponse(r *http.Response) *APIResponse {
response := &APIResponse{Response: r}
return response
}
func NewAPIResponseWithError(errorMessage string) *APIResponse {
response := &APIResponse{Message: errorMessage}
return response
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CommonCode struct {
// 코드
Code *string `json:"code,omitempty"`
// 코드명
CodeName *string `json:"codeName,omitempty"`
}
@@ -0,0 +1,37 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
import (
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
"os"
)
// contextKeys are used to identify the type of value in the context.
// Since these are string, it is possible to get a short description of the
// context key for logging and debugging using key.String().
type contextKey string
func (c contextKey) String() string {
return "auth " + string(c)
}
func NewConfiguration(apiKey *ncloud.APIKey) *ncloud.Configuration {
cfg := &ncloud.Configuration{
BasePath: "https://ncloud.apigw.ntruss.com/vpc/v2",
DefaultHeader: make(map[string]string),
UserAgent: "vpc/1.0.0/go",
APIKey: apiKey,
}
if os.Getenv("NCLOUD_API_GW") != "" {
cfg.BasePath = os.Getenv("NCLOUD_API_GW") + "/vpc/v2"
}
return cfg
}
@@ -0,0 +1,27 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateNatGatewayInstanceRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// NATGateway설명
NatGatewayDescription *string `json:"natGatewayDescription,omitempty"`
// NATGateway이름
NatGatewayName *string `json:"natGatewayName,omitempty"`
// VPC번호
VpcNo *string `json:"vpcNo"`
// ZONE코드
ZoneCode *string `json:"zoneCode"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateNatGatewayInstanceResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NatGatewayInstanceList []*NatGatewayInstance `json:"natGatewayInstanceList,omitempty"`
}
@@ -0,0 +1,24 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateNetworkAclRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL설명
NetworkAclDescription *string `json:"networkAclDescription,omitempty"`
// 네트워크ACL이름
NetworkAclName *string `json:"networkAclName,omitempty"`
// VPC번호
VpcNo *string `json:"vpcNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateNetworkAclResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclList []*NetworkAcl `json:"networkAclList,omitempty"`
}
@@ -0,0 +1,27 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateRouteTableRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 라우트테이블설명
RouteTableDescription *string `json:"routeTableDescription,omitempty"`
// 지원하는서브넷유형코드
SupportedSubnetTypeCode *string `json:"supportedSubnetTypeCode"`
// 라우트테이블이름
RouteTableName *string `json:"routeTableName,omitempty"`
// VPC번호
VpcNo *string `json:"vpcNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateRouteTableResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
RouteTableList []*RouteTable `json:"routeTableList,omitempty"`
}
@@ -0,0 +1,36 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateSubnetRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 서브넷유형코드
SubnetTypeCode *string `json:"subnetTypeCode"`
// 용도유형코드
UsageTypeCode *string `json:"usageTypeCode,omitempty"`
// 네트워크ACL번호
NetworkAclNo *string `json:"networkAclNo"`
// 서브넷
Subnet *string `json:"subnet"`
// 서브넷이름
SubnetName *string `json:"subnetName,omitempty"`
// VPC번호
VpcNo *string `json:"vpcNo"`
// ZONE코드
ZoneCode *string `json:"zoneCode"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateSubnetResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
SubnetList []*Subnet `json:"subnetList,omitempty"`
}
@@ -0,0 +1,33 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateVpcPeeringInstanceRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// VPCPeering설명
VpcPeeringDescription *string `json:"vpcPeeringDescription,omitempty"`
// 요청VPC번호
SourceVpcNo *string `json:"sourceVpcNo"`
// 수락VPC소유자ID
TargetVpcLoginId *string `json:"targetVpcLoginId,omitempty"`
// 수락VPC이름
TargetVpcName *string `json:"targetVpcName,omitempty"`
// 수락VPC번호
TargetVpcNo *string `json:"targetVpcNo"`
// VPCPeering이름
VpcPeeringName *string `json:"vpcPeeringName,omitempty"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateVpcPeeringInstanceResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
VpcPeeringInstanceList []*VpcPeeringInstance `json:"vpcPeeringInstanceList,omitempty"`
}
@@ -0,0 +1,21 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateVpcRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// IPv4 CIDR블록
Ipv4CidrBlock *string `json:"ipv4CidrBlock"`
// VPC이름
VpcName *string `json:"vpcName,omitempty"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type CreateVpcResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
VpcList []*Vpc `json:"vpcList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteNatGatewayInstanceRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// NATGateway인스턴스번호
NatGatewayInstanceNo *string `json:"natGatewayInstanceNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteNatGatewayInstanceResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NatGatewayInstanceList []*NatGatewayInstance `json:"natGatewayInstanceList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteNetworkAclRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL번호
NetworkAclNo *string `json:"networkAclNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteNetworkAclResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclList []*NetworkAcl `json:"networkAclList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteRouteTableRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 라우트테이블번호
RouteTableNo *string `json:"routeTableNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteRouteTableResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
RouteTableList []*RouteTable `json:"routeTableList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteSubnetRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 서브넷번호
SubnetNo *string `json:"subnetNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteSubnetResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
SubnetList []*Subnet `json:"subnetList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteVpcPeeringInstanceRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// VPCPeering인스턴스번호
VpcPeeringInstanceNo *string `json:"vpcPeeringInstanceNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteVpcPeeringInstanceResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
VpcPeeringInstanceList []*VpcPeeringInstance `json:"vpcPeeringInstanceList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteVpcRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// VPC번호
VpcNo *string `json:"vpcNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type DeleteVpcResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
VpcList []*Vpc `json:"VpcList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNatGatewayInstanceDetailRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// NATGatway인스턴스번호
NatGatewayInstanceNo *string `json:"natGatewayInstanceNo,omitempty"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNatGatewayInstanceDetailResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NatGatewayInstanceList []*NatGatewayInstance `json:"natGatewayInstanceList,omitempty"`
}
@@ -0,0 +1,39 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNatGatewayInstanceListRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// ZONE코드
ZoneCode *string `json:"zoneCode,omitempty"`
// NATGateway인스턴스번호리스트
NatGatewayInstanceNoList []*string `json:"natGatewayInstanceNoList,omitempty"`
// 공인IP주소
PublicIp *string `json:"publicIp,omitempty"`
// VPC이름
VpcName *string `json:"vpcName,omitempty"`
// natGatewayName
NatGatewayName *string `json:"natGatewayName,omitempty"`
// NATGateway인스턴스상태코드
NatGatewayInstanceStatusCode *string `json:"natGatewayInstanceStatusCode,omitempty"`
// 페이지번호
PageNo *int32 `json:"pageNo,omitempty"`
// 페이지사이즈
PageSize *int32 `json:"pageSize,omitempty"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNatGatewayInstanceListResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NatGatewayInstanceList []*NatGatewayInstance `json:"natGatewayInstanceList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNetworkAclDetailRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL번호
NetworkAclNo *string `json:"networkAclNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNetworkAclDetailResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclList []*NetworkAcl `json:"networkAclList,omitempty"`
}
@@ -0,0 +1,33 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNetworkAclListRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL이름
NetworkAclName *string `json:"networkAclName,omitempty"`
// 네트워크ACL상태코드
NetworkAclStatusCode *string `json:"networkAclStatusCode,omitempty"`
// 네트워크ACL번호리스트
NetworkAclNoList []*string `json:"networkAclNoList,omitempty"`
// 페이지번호
PageNo *int32 `json:"pageNo,omitempty"`
// 페이지사이즈
PageSize *int32 `json:"pageSize,omitempty"`
// VPC번호
VpcNo *string `json:"vpcNo,omitempty"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNetworkAclListResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclList []*NetworkAcl `json:"networkAclList,omitempty"`
}
@@ -0,0 +1,21 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNetworkAclRuleListRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 네트워크ACL번호
NetworkAclNo *string `json:"networkAclNo"`
// 네트워크ACLRule유형코드
NetworkAclRuleTypeCode *string `json:"networkAclRuleTypeCode,omitempty"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetNetworkAclRuleListResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
NetworkAclRuleList []*NetworkAclRule `json:"networkAclRuleList,omitempty"`
}
@@ -0,0 +1,21 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetRouteListRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 라우트테이블번호
RouteTableNo *string `json:"routeTableNo"`
// VPC번호
VpcNo *string `json:"vpcNo"`
}
@@ -0,0 +1,22 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetRouteListResponse struct {
RequestId *string `json:"requestId,omitempty"`
ReturnCode *string `json:"returnCode,omitempty"`
ReturnMessage *string `json:"returnMessage,omitempty"`
TotalRows *int32 `json:"totalRows,omitempty"`
RouteList []*Route `json:"routeList,omitempty"`
}
@@ -0,0 +1,18 @@
/*
* vpc
*
* VPC Network 관련 API<br/>https://ncloud.apigw.ntruss.com/vpc/v2
*
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package vpc
type GetRouteTableDetailRequest struct {
// REGION코드
RegionCode *string `json:"regionCode,omitempty"`
// 라우트테이블번호
RouteTableNo *string `json:"routeTableNo"`
}

Some files were not shown because too many files have changed in this diff Show More