Merge pull request #8250 from tencentyun/master
tencentcloud-cvm builder: we added retry on remote api call to improve the user experience
This commit is contained in:
commit
0c2fba089d
|
@ -3,6 +3,7 @@
|
|||
package cvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
@ -71,49 +72,67 @@ func (cf *TencentCloudAccessConfig) Client() (*cvm.Client, *vpc.Client, error) {
|
|||
vpc_client *vpc.Client
|
||||
resp *cvm.DescribeZonesResponse
|
||||
)
|
||||
|
||||
if err = cf.validateRegion(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
credential := common.NewCredential(
|
||||
cf.SecretId, cf.SecretKey)
|
||||
|
||||
if cf.Zone == "" {
|
||||
return nil, nil, fmt.Errorf("parameter zone must be set")
|
||||
}
|
||||
|
||||
credential := common.NewCredential(cf.SecretId, cf.SecretKey)
|
||||
cpf := profile.NewClientProfile()
|
||||
cpf.HttpProfile.ReqMethod = "POST"
|
||||
cpf.HttpProfile.ReqTimeout = 300
|
||||
cpf.Language = "en-US"
|
||||
|
||||
if cvm_client, err = cvm.NewClient(credential, cf.Region, cpf); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if vpc_client, err = vpc.NewClient(credential, cf.Region, cpf); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if resp, err = cvm_client.DescribeZones(nil); err != nil {
|
||||
|
||||
ctx := context.TODO()
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = cvm_client.DescribeZones(nil)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if cf.Zone != "" {
|
||||
for _, zone := range resp.Response.ZoneSet {
|
||||
if cf.Zone == *zone.Zone {
|
||||
return cvm_client, vpc_client, nil
|
||||
}
|
||||
|
||||
for _, zone := range resp.Response.ZoneSet {
|
||||
if cf.Zone == *zone.Zone {
|
||||
return cvm_client, vpc_client, nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("unknown zone: %s", cf.Zone)
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("zone must be set")
|
||||
}
|
||||
|
||||
return nil, nil, fmt.Errorf("unknown zone: %s", cf.Zone)
|
||||
}
|
||||
|
||||
func (cf *TencentCloudAccessConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
var errs []error
|
||||
|
||||
if err := cf.Config(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if cf.Region == "" {
|
||||
errs = append(errs, fmt.Errorf("region must be set"))
|
||||
errs = append(errs, fmt.Errorf("parameter region must be set"))
|
||||
} else if !cf.SkipValidation {
|
||||
if err := cf.validateRegion(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -121,20 +140,28 @@ func (cf *TencentCloudAccessConfig) Config() error {
|
|||
if cf.SecretId == "" {
|
||||
cf.SecretId = os.Getenv("TENCENTCLOUD_SECRET_ID")
|
||||
}
|
||||
|
||||
if cf.SecretKey == "" {
|
||||
cf.SecretKey = os.Getenv("TENCENTCLOUD_SECRET_KEY")
|
||||
}
|
||||
|
||||
if cf.SecretId == "" || cf.SecretKey == "" {
|
||||
return fmt.Errorf("TENCENTCLOUD_SECRET_ID and TENCENTCLOUD_SECRET_KEY must be set")
|
||||
return fmt.Errorf("parameter secret_id and secret_key must be set")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cf *TencentCloudAccessConfig) validateRegion() error {
|
||||
return validRegion(cf.Region)
|
||||
}
|
||||
|
||||
func validRegion(region string) error {
|
||||
for _, valid := range ValidRegions {
|
||||
if valid == Region(cf.Region) {
|
||||
if Region(region) == valid {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("unknown region: %s", cf.Region)
|
||||
|
||||
return fmt.Errorf("unknown region: %s", region)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
|
@ -29,8 +30,8 @@ func (a *Artifact) Id() string {
|
|||
for region, imageId := range a.TencentCloudImages {
|
||||
parts = append(parts, fmt.Sprintf("%s:%s", region, imageId))
|
||||
}
|
||||
|
||||
sort.Strings(parts)
|
||||
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,8 @@ func (a *Artifact) String() string {
|
|||
parts = append(parts, fmt.Sprintf("%s: %s", region, imageId))
|
||||
}
|
||||
sort.Strings(parts)
|
||||
return fmt.Sprintf("Tencentcloud images(%s) were created:\n\n", strings.Join(parts, "\n"))
|
||||
|
||||
return fmt.Sprintf("Tencentcloud images(%s) were created.\n\n", strings.Join(parts, "\n"))
|
||||
}
|
||||
|
||||
func (a *Artifact) State(name string) interface{} {
|
||||
|
@ -53,6 +55,7 @@ func (a *Artifact) State(name string) interface{} {
|
|||
}
|
||||
|
||||
func (a *Artifact) Destroy() error {
|
||||
ctx := context.TODO()
|
||||
errors := make([]error, 0)
|
||||
|
||||
for region, imageId := range a.TencentCloudImages {
|
||||
|
@ -60,22 +63,31 @@ func (a *Artifact) Destroy() error {
|
|||
|
||||
describeReq := cvm.NewDescribeImagesRequest()
|
||||
describeReq.ImageIds = []*string{&imageId}
|
||||
|
||||
describeResp, err := a.Client.DescribeImages(describeReq)
|
||||
var describeResp *cvm.DescribeImagesResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
describeResp, e = a.Client.DescribeImages(describeReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if *describeResp.Response.TotalCount == 0 {
|
||||
errors = append(errors, fmt.Errorf(
|
||||
"describe images failed, region(%s) ImageId(%s)", region, imageId))
|
||||
}
|
||||
|
||||
var shareAccountIds []*string = nil
|
||||
describeShareReq := cvm.NewDescribeImageSharePermissionRequest()
|
||||
describeShareReq.ImageId = &imageId
|
||||
|
||||
describeShareResp, err := a.Client.DescribeImageSharePermission(describeShareReq)
|
||||
var shareAccountIds []*string = nil
|
||||
var describeShareResp *cvm.DescribeImageSharePermissionResponse
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
describeShareResp, e = a.Client.DescribeImageSharePermission(describeShareReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
} else {
|
||||
|
@ -90,7 +102,10 @@ func (a *Artifact) Destroy() error {
|
|||
cancelShareReq.AccountIds = shareAccountIds
|
||||
CANCEL := "CANCEL"
|
||||
cancelShareReq.Permission = &CANCEL
|
||||
_, err := a.Client.ModifyImageSharePermission(cancelShareReq)
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := a.Client.ModifyImageSharePermission(cancelShareReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
@ -98,8 +113,10 @@ func (a *Artifact) Destroy() error {
|
|||
|
||||
deleteReq := cvm.NewDeleteImagesRequest()
|
||||
deleteReq.ImageIds = []*string{&imageId}
|
||||
|
||||
_, err = a.Client.DeleteImages(deleteReq)
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := a.Client.DeleteImages(deleteReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
@ -120,5 +137,6 @@ func (a *Artifact) stateAtlasMetadata() interface{} {
|
|||
k := fmt.Sprintf("region.%s", region)
|
||||
metadata[k] = imageId
|
||||
}
|
||||
|
||||
return metadata
|
||||
}
|
||||
|
|
|
@ -49,13 +49,13 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
errs = packer.MultiErrorAppend(errs, b.config.TencentCloudAccessConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.TencentCloudImageConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.TencentCloudRunConfig.Prepare(&b.config.ctx)...)
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.SecretId, b.config.SecretKey)
|
||||
log.Println(b.config)
|
||||
log.Printf("[DEBUG]packer config: %v", b.config)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -64,17 +64,21 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("cvm_client", cvmClient)
|
||||
state.Put("vpc_client", vpcClient)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
var steps []multistep.Step
|
||||
|
||||
// Build the steps
|
||||
var steps []multistep.Step
|
||||
steps = []multistep.Step{
|
||||
&stepCheckSourceImage{b.config.SourceImageId},
|
||||
&stepPreValidate{},
|
||||
&stepCheckSourceImage{
|
||||
b.config.SourceImageId,
|
||||
},
|
||||
&stepConfigKeyPair{
|
||||
Debug: b.config.PackerDebug,
|
||||
Comm: &b.config.Comm,
|
||||
|
@ -94,7 +98,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
&stepConfigSecurityGroup{
|
||||
SecurityGroupId: b.config.SecurityGroupId,
|
||||
SecurityGroupName: b.config.SecurityGroupName,
|
||||
Description: "a simple security group",
|
||||
Description: "securitygroup for packer",
|
||||
},
|
||||
&stepRunInstance{
|
||||
InstanceType: b.config.InstanceType,
|
||||
|
@ -119,7 +123,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
&common.StepCleanupTempKeys{
|
||||
Comm: &b.config.TencentCloudRunConfig.Comm,
|
||||
},
|
||||
// We need this step to detach temporary key from instance, otherwise
|
||||
// We need this step to detach keypair from instance, otherwise
|
||||
// it always fails to delete the key.
|
||||
&stepDetachTempKeyPair{},
|
||||
&stepCreateImage{},
|
||||
|
@ -148,5 +152,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
BuilderIdValue: BuilderId,
|
||||
Client: cvmClient,
|
||||
}
|
||||
|
||||
return artifact, nil
|
||||
}
|
||||
|
|
|
@ -1,44 +1,35 @@
|
|||
package cvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
func CheckResourceIdFormat(resource string, id string) bool {
|
||||
regex := regexp.MustCompile(fmt.Sprintf("%s-[0-9a-z]{8}$", resource))
|
||||
if !regex.MatchString(id) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func MessageClean(state multistep.StateBag, module string) {
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
if cancelled || halted {
|
||||
ui.Say(fmt.Sprintf("Deleting %s because of cancellation or error...", module))
|
||||
} else {
|
||||
ui.Say(fmt.Sprintf("Cleaning up '%s'", module))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// DefaultWaitForInterval is sleep interval when wait statue
|
||||
const DefaultWaitForInterval = 5
|
||||
|
||||
// WaitForInstance wait for instance reaches statue
|
||||
func WaitForInstance(client *cvm.Client, instanceId string, status string, timeout int) error {
|
||||
ctx := context.TODO()
|
||||
req := cvm.NewDescribeInstancesRequest()
|
||||
req.InstanceIds = []*string{&instanceId}
|
||||
|
||||
for {
|
||||
resp, err := client.DescribeInstances(req)
|
||||
var resp *cvm.DescribeInstancesResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = client.DescribeInstances(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -54,10 +45,13 @@ func WaitForInstance(client *cvm.Client, instanceId string, status string, timeo
|
|||
return fmt.Errorf("wait instance(%s) status(%s) timeout", instanceId, status)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForImageReady wait for image reaches statue
|
||||
func WaitForImageReady(client *cvm.Client, imageName string, status string, timeout int) error {
|
||||
ctx := context.TODO()
|
||||
req := cvm.NewDescribeImagesRequest()
|
||||
FILTER_IMAGE_NAME := "image-name"
|
||||
req.Filters = []*cvm.Filter{
|
||||
|
@ -66,8 +60,14 @@ func WaitForImageReady(client *cvm.Client, imageName string, status string, time
|
|||
Values: []*string{&imageName},
|
||||
},
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := client.DescribeImages(req)
|
||||
var resp *cvm.DescribeImagesResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = client.DescribeImages(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -84,12 +84,22 @@ func WaitForImageReady(client *cvm.Client, imageName string, status string, time
|
|||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return fmt.Errorf("wait image(%s) ready timeout", imageName)
|
||||
return fmt.Errorf("wait image(%s) status(%s) timeout", imageName, status)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckResourceIdFormat check resource id format
|
||||
func CheckResourceIdFormat(resource string, id string) bool {
|
||||
regex := regexp.MustCompile(fmt.Sprintf("%s-[0-9a-z]{8}$", resource))
|
||||
if !regex.MatchString(id) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// SSHHost returns a function that can be given to the SSH communicator
|
||||
func SSHHost(pubilcIp bool) func(multistep.StateBag) (string, error) {
|
||||
return func(state multistep.StateBag) (string, error) {
|
||||
|
@ -101,3 +111,83 @@ func SSHHost(pubilcIp bool) func(multistep.StateBag) (string, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retry do retry on api request
|
||||
func Retry(ctx context.Context, fn func(context.Context) error) error {
|
||||
return retry.Config{
|
||||
Tries: 30,
|
||||
ShouldRetry: func(err error) bool {
|
||||
e, ok := err.(*errors.TencentCloudSDKError)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if e.Code == "ClientError.NetworkError" || e.Code == "ClientError.HttpStatusCodeError" ||
|
||||
e.Code == "InvalidKeyPair.NotSupported" || e.Code == "InvalidInstance.NotSupported" ||
|
||||
strings.Contains(e.Code, "RequestLimitExceeded") || strings.Contains(e.Code, "InternalError") ||
|
||||
strings.Contains(e.Code, "ResourceInUse") || strings.Contains(e.Code, "ResourceBusy") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
RetryDelay: (&retry.Backoff{
|
||||
InitialBackoff: 1 * time.Second,
|
||||
MaxBackoff: 5 * time.Second,
|
||||
Multiplier: 2,
|
||||
}).Linear,
|
||||
}.Run(ctx, fn)
|
||||
}
|
||||
|
||||
// SayClean tell you clean module message
|
||||
func SayClean(state multistep.StateBag, module string) {
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
if halted {
|
||||
Say(state, fmt.Sprintf("Deleting %s because of error...", module), "")
|
||||
} else if cancelled {
|
||||
Say(state, fmt.Sprintf("Deleting %s because of cancellation...", module), "")
|
||||
} else {
|
||||
Say(state, fmt.Sprintf("Cleaning up %s...", module), "")
|
||||
}
|
||||
}
|
||||
|
||||
// Say tell you a message
|
||||
func Say(state multistep.StateBag, message, prefix string) {
|
||||
if prefix != "" {
|
||||
message = fmt.Sprintf("%s: %s", prefix, message)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(message, "Trying to") {
|
||||
message += "..."
|
||||
}
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
ui.Say(message)
|
||||
}
|
||||
|
||||
// Message print a message
|
||||
func Message(state multistep.StateBag, message, prefix string) {
|
||||
if prefix != "" {
|
||||
message = fmt.Sprintf("%s: %s", prefix, message)
|
||||
}
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
ui.Message(message)
|
||||
}
|
||||
|
||||
// Error print error message
|
||||
func Error(state multistep.StateBag, err error, prefix string) {
|
||||
if prefix != "" {
|
||||
err = fmt.Errorf("%s: %s", prefix, err)
|
||||
}
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
ui.Error(err.Error())
|
||||
}
|
||||
|
||||
// Halt print error message and exit
|
||||
func Halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
|
||||
Error(state, err, prefix)
|
||||
state.Put("error", err)
|
||||
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ type TencentCloudImageConfig struct {
|
|||
|
||||
func (cf *TencentCloudImageConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
var errs []error
|
||||
|
||||
cf.ForcePoweroff = true
|
||||
if cf.ImageName == "" {
|
||||
errs = append(errs, fmt.Errorf("image_name must be specified"))
|
||||
|
@ -68,17 +69,10 @@ func (cf *TencentCloudImageConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
}
|
||||
cf.ImageCopyRegions = regions
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validRegion(region string) error {
|
||||
for _, valid := range ValidRegions {
|
||||
if Region(region) == valid {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("unknown region: %s", region)
|
||||
}
|
||||
|
|
|
@ -31,5 +31,4 @@ func TestTencentCloudImageConfig_Prepare(t *testing.T) {
|
|||
if err := cf.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err:%v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ package cvm
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer/common/uuid"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
|
@ -68,7 +69,7 @@ type TencentCloudRunConfig struct {
|
|||
// Max bandwidth out your cvm will be launched by(in MB).
|
||||
// values can be set between 1 ~ 100.
|
||||
InternetMaxBandwidthOut int64 `mapstructure:"internet_max_bandwidth_out" required:"false"`
|
||||
// Specify security group your cvm will be launched by.
|
||||
// Specify securitygroup your cvm will be launched by.
|
||||
SecurityGroupId string `mapstructure:"security_group_id" required:"false"`
|
||||
// Specify security name you will create if security_group_id not set.
|
||||
SecurityGroupName string `mapstructure:"security_group_name" required:"false"`
|
||||
|
@ -92,10 +93,11 @@ var ValidCBSType = []string{
|
|||
}
|
||||
|
||||
func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
packerId := fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()[:8])
|
||||
if cf.Comm.SSHKeyPairName == "" && cf.Comm.SSHTemporaryKeyPairName == "" &&
|
||||
cf.Comm.SSHPrivateKeyFile == "" && cf.Comm.SSHPassword == "" && cf.Comm.WinRMPassword == "" {
|
||||
//tencentcloud support key pair name length max to 25
|
||||
cf.Comm.SSHTemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()[:8])
|
||||
cf.Comm.SSHTemporaryKeyPairName = packerId
|
||||
}
|
||||
|
||||
errs := cf.Comm.Prepare(ctx)
|
||||
|
@ -126,7 +128,7 @@ func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
|
||||
if cf.VpcId == "" {
|
||||
if cf.VpcName == "" {
|
||||
cf.VpcName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
|
||||
cf.VpcName = packerId
|
||||
}
|
||||
if cf.CidrBlock == "" {
|
||||
cf.CidrBlock = "10.0.0.0/16"
|
||||
|
@ -135,9 +137,10 @@ func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
errs = append(errs, errors.New("can't set subnet_id without set vpc_id"))
|
||||
}
|
||||
}
|
||||
|
||||
if cf.SubnetId == "" {
|
||||
if cf.SubnetName == "" {
|
||||
cf.SubnetName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
|
||||
cf.SubnetName = packerId
|
||||
}
|
||||
if cf.SubnectCidrBlock == "" {
|
||||
cf.SubnectCidrBlock = "10.0.8.0/24"
|
||||
|
@ -145,7 +148,7 @@ func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
}
|
||||
|
||||
if cf.SecurityGroupId == "" && cf.SecurityGroupName == "" {
|
||||
cf.SecurityGroupName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
|
||||
cf.SecurityGroupName = packerId
|
||||
}
|
||||
|
||||
if cf.DiskType != "" && !checkDiskType(cf.DiskType) {
|
||||
|
@ -163,13 +166,18 @@ func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
}
|
||||
|
||||
if cf.InstanceName == "" {
|
||||
cf.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
|
||||
cf.InstanceName = packerId
|
||||
}
|
||||
|
||||
if cf.HostName == "" {
|
||||
cf.HostName = cf.InstanceName[:15]
|
||||
cf.HostName = cf.InstanceName
|
||||
}
|
||||
|
||||
if len(cf.HostName) > 15 {
|
||||
cf.HostName = cf.HostName[:15]
|
||||
}
|
||||
cf.HostName = strings.Replace(cf.HostName, "_", "-", -1)
|
||||
|
||||
if cf.RunTags == nil {
|
||||
cf.RunTags = make(map[string]string)
|
||||
}
|
||||
|
@ -183,5 +191,6 @@ func checkDiskType(diskType string) bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ func TestTencentCloudRunConfig_Prepare(t *testing.T) {
|
|||
|
||||
func TestTencentCloudRunConfigPrepare_UserData(t *testing.T) {
|
||||
cf := testConfig()
|
||||
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("new temp file failed: %v", err)
|
||||
|
@ -76,6 +77,7 @@ func TestTencentCloudRunConfigPrepare_UserData(t *testing.T) {
|
|||
|
||||
func TestTencentCloudRunConfigPrepare_UserDataFile(t *testing.T) {
|
||||
cf := testConfig()
|
||||
|
||||
cf.UserDataFile = "not-exist-file"
|
||||
if err := cf.Prepare(nil); err == nil {
|
||||
t.Fatal("should have error")
|
||||
|
@ -117,13 +119,16 @@ func TestTencentCloudRunConfigPrepare_TemporaryKeyPairName(t *testing.T) {
|
|||
|
||||
func TestTencentCloudRunConfigPrepare_SSHPrivateIp(t *testing.T) {
|
||||
cf := testConfig()
|
||||
|
||||
if cf.SSHPrivateIp != false {
|
||||
t.Fatalf("invalid ssh_private_ip value: %v", cf.SSHPrivateIp)
|
||||
}
|
||||
|
||||
cf.SSHPrivateIp = true
|
||||
if err := cf.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have error: %v", err)
|
||||
}
|
||||
|
||||
if cf.SSHPrivateIp != true {
|
||||
t.Fatalf("invalud ssh_private_ip value: %v", cf.SSHPrivateIp)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
|
@ -14,32 +13,31 @@ type stepCheckSourceImage struct {
|
|||
}
|
||||
|
||||
func (s *stepCheckSourceImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
config := state.Get("config").(*Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
|
||||
Say(state, config.SourceImageId, "Trying to check source image")
|
||||
|
||||
req := cvm.NewDescribeImagesRequest()
|
||||
req.ImageIds = []*string{&config.SourceImageId}
|
||||
req.InstanceType = &config.InstanceType
|
||||
|
||||
resp, err := client.DescribeImages(req)
|
||||
var resp *cvm.DescribeImagesResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var err error
|
||||
resp, err = client.DescribeImages(req)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
err := fmt.Errorf("querying image info failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to get source image info")
|
||||
}
|
||||
|
||||
if *resp.Response.TotalCount > 0 { // public image or private image.
|
||||
if *resp.Response.TotalCount > 0 {
|
||||
state.Put("source_image", resp.Response.ImageSet[0])
|
||||
ui.Message(fmt.Sprintf("Image found: %s", *resp.Response.ImageSet[0].ImageId))
|
||||
Message(state, *resp.Response.ImageSet[0].ImageName, "Image found")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
// later market image will be included.
|
||||
err = fmt.Errorf("no image founded under current instance_type(%s) restriction", config.InstanceType)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
|
||||
return Halt(state, fmt.Errorf("No image found under current instance_type(%s) restriction", config.InstanceType), "")
|
||||
}
|
||||
|
||||
func (s *stepCheckSourceImage) Cleanup(bag multistep.StateBag) {}
|
||||
|
|
|
@ -6,12 +6,9 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
|
@ -19,83 +16,79 @@ type stepConfigKeyPair struct {
|
|||
Debug bool
|
||||
Comm *communicator.Config
|
||||
DebugKeyPath string
|
||||
|
||||
keyID string
|
||||
keyID string
|
||||
}
|
||||
|
||||
func (s *stepConfigKeyPair) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
|
||||
if s.Comm.SSHPrivateKeyFile != "" {
|
||||
ui.Say("Using existing SSH private key")
|
||||
Say(state, "Using existing SSH private key", "")
|
||||
privateKeyBytes, err := ioutil.ReadFile(s.Comm.SSHPrivateKeyFile)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf(
|
||||
"loading configured private key file failed: %s", err))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, fmt.Sprintf("Failed to load configured private key(%s)", s.Comm.SSHPrivateKeyFile))
|
||||
}
|
||||
|
||||
s.Comm.SSHPrivateKey = privateKeyBytes
|
||||
|
||||
Message(state, fmt.Sprintf("Loaded %d bytes private key data", len(s.Comm.SSHPrivateKey)), "")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName == "" {
|
||||
ui.Say("Using SSH Agent with key pair in source image")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName != "" {
|
||||
ui.Say(fmt.Sprintf("Using SSH Agent for existing key pair %s", s.Comm.SSHKeyPairName))
|
||||
if s.Comm.SSHAgentAuth {
|
||||
if s.Comm.SSHKeyPairName == "" {
|
||||
Say(state, "Using SSH agent with key pair in source image", "")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
Say(state, fmt.Sprintf("Using SSH agent with exists key pair(%s)", s.Comm.SSHKeyPairName), "")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
if s.Comm.SSHTemporaryKeyPairName == "" {
|
||||
ui.Say("Not using temporary keypair")
|
||||
Say(state, "Not to use temporary keypair", "")
|
||||
s.Comm.SSHKeyPairName = ""
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui.Say(fmt.Sprintf("Creating temporary keypair: %s", s.Comm.SSHTemporaryKeyPairName))
|
||||
Say(state, s.Comm.SSHTemporaryKeyPairName, "Trying to create a new keypair")
|
||||
|
||||
req := cvm.NewCreateKeyPairRequest()
|
||||
req.KeyName = &s.Comm.SSHTemporaryKeyPairName
|
||||
defaultProjectId := int64(0)
|
||||
req.ProjectId = &defaultProjectId
|
||||
resp, err := client.CreateKeyPair(req)
|
||||
var resp *cvm.CreateKeyPairResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = client.CreateKeyPair(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("creating temporary keypair failed: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to create keypair")
|
||||
}
|
||||
|
||||
// set keyId to delete when Cleanup
|
||||
s.keyID = *resp.Response.KeyPair.KeyId
|
||||
state.Put("temporary_key_pair_id", resp.Response.KeyPair.KeyId)
|
||||
state.Put("temporary_key_pair_id", s.keyID)
|
||||
Message(state, s.keyID, "Keypair created")
|
||||
|
||||
s.Comm.SSHKeyPairName = *resp.Response.KeyPair.KeyId
|
||||
s.Comm.SSHPrivateKey = []byte(*resp.Response.KeyPair.PrivateKey)
|
||||
|
||||
if s.Debug {
|
||||
ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath))
|
||||
Message(state, fmt.Sprintf("Saving temporary key to %s for debug purposes", s.DebugKeyPath), "")
|
||||
f, err := os.Create(s.DebugKeyPath)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("creating debug key file failed:%s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to saving debug key file")
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err := f.Write([]byte(*resp.Response.KeyPair.PrivateKey)); err != nil {
|
||||
state.Put("error", fmt.Errorf("writing debug key file failed:%s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to writing debug key file")
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
if err := f.Chmod(0600); err != nil {
|
||||
state.Put("error", fmt.Errorf("setting debug key file's permission failed:%s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to chmod debug key file")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -103,28 +96,25 @@ func (s *stepConfigKeyPair) Cleanup(state multistep.StateBag) {
|
|||
if s.Comm.SSHPrivateKeyFile != "" || (s.Comm.SSHKeyPairName == "" && s.keyID == "") {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Deleting temporary keypair...")
|
||||
SayClean(state, "keypair")
|
||||
|
||||
req := cvm.NewDeleteKeyPairsRequest()
|
||||
req.KeyIds = []*string{&s.keyID}
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 5 * time.Second, MaxBackoff: 5 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := client.DeleteKeyPairs(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.DeleteKeyPairs(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf(
|
||||
"delete keypair failed, please delete it manually, keyId: %s, err: %s", s.keyID, err.Error()))
|
||||
Error(state, err, fmt.Sprintf("Failed to delete keypair(%s), please delete it manually", s.keyID))
|
||||
}
|
||||
|
||||
if s.Debug {
|
||||
if err := os.Remove(s.DebugKeyPath); err != nil {
|
||||
ui.Error(fmt.Sprintf("delete debug key file %s failed: %s", s.DebugKeyPath, err.Error()))
|
||||
Error(state, err, fmt.Sprintf("Failed to delete debug key file(%s), please delete it manually", s.DebugKeyPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,9 @@ package cvm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/pkg/errors"
|
||||
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
|
||||
)
|
||||
|
||||
|
@ -22,42 +17,51 @@ type stepConfigSecurityGroup struct {
|
|||
|
||||
func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
vpcClient := state.Get("vpc_client").(*vpc.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
if len(s.SecurityGroupId) != 0 { // use existing security group
|
||||
if len(s.SecurityGroupId) != 0 {
|
||||
Say(state, s.SecurityGroupId, "Trying to use existing securitygroup")
|
||||
req := vpc.NewDescribeSecurityGroupsRequest()
|
||||
req.SecurityGroupIds = []*string{&s.SecurityGroupId}
|
||||
resp, err := vpcClient.DescribeSecurityGroups(req)
|
||||
var resp *vpc.DescribeSecurityGroupsResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = vpcClient.DescribeSecurityGroups(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("query security group failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to get securitygroup info")
|
||||
}
|
||||
if *resp.Response.TotalCount > 0 {
|
||||
state.Put("security_group_id", s.SecurityGroupId)
|
||||
s.isCreate = false
|
||||
state.Put("security_group_id", s.SecurityGroupId)
|
||||
Message(state, *resp.Response.SecurityGroupSet[0].SecurityGroupName, "Securitygroup found")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
message := fmt.Sprintf("the specified security group(%s) does not exist", s.SecurityGroupId)
|
||||
ui.Error(message)
|
||||
state.Put("error", errors.New(message))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, fmt.Errorf("The specified securitygroup(%s) does not exists", s.SecurityGroupId), "")
|
||||
}
|
||||
// create a new security group
|
||||
|
||||
Say(state, "Trying to create a new securitygroup", "")
|
||||
|
||||
req := vpc.NewCreateSecurityGroupRequest()
|
||||
req.GroupName = &s.SecurityGroupName
|
||||
req.GroupDescription = &s.Description
|
||||
resp, err := vpcClient.CreateSecurityGroup(req)
|
||||
var resp *vpc.CreateSecurityGroupResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = vpcClient.CreateSecurityGroup(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("create security group failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to create securitygroup")
|
||||
}
|
||||
|
||||
s.isCreate = true
|
||||
s.SecurityGroupId = *resp.Response.SecurityGroup.SecurityGroupId
|
||||
state.Put("security_group_id", s.SecurityGroupId)
|
||||
s.isCreate = true
|
||||
Message(state, s.SecurityGroupId, "Securitygroup created")
|
||||
|
||||
// bind security group ingress police
|
||||
// bind securitygroup ingress police
|
||||
Say(state, "Trying to create securitygroup polices", "")
|
||||
pReq := vpc.NewCreateSecurityGroupPoliciesRequest()
|
||||
ACCEPT := "ACCEPT"
|
||||
DEFAULT_CIDR := "0.0.0.0/0"
|
||||
|
@ -70,14 +74,15 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
|
|||
},
|
||||
},
|
||||
}
|
||||
_, err = vpcClient.CreateSecurityGroupPolicies(pReq)
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := vpcClient.CreateSecurityGroupPolicies(pReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("bind security group police failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to create securitygroup polices")
|
||||
}
|
||||
|
||||
// bind security group engress police
|
||||
// bind securitygroup engress police
|
||||
pReq = vpc.NewCreateSecurityGroupPoliciesRequest()
|
||||
pReq.SecurityGroupId = &s.SecurityGroupId
|
||||
pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{
|
||||
|
@ -88,13 +93,16 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
|
|||
},
|
||||
},
|
||||
}
|
||||
_, err = vpcClient.CreateSecurityGroupPolicies(pReq)
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := vpcClient.CreateSecurityGroupPolicies(pReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("bind security group police failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to create securitygroup polices")
|
||||
}
|
||||
|
||||
Message(state, "Securitygroup polices created", "")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -102,23 +110,19 @@ func (s *stepConfigSecurityGroup) Cleanup(state multistep.StateBag) {
|
|||
if !s.isCreate {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
vpcClient := state.Get("vpc_client").(*vpc.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
MessageClean(state, "Security Group")
|
||||
SayClean(state, "securitygroup")
|
||||
|
||||
req := vpc.NewDeleteSecurityGroupRequest()
|
||||
req.SecurityGroupId = &s.SecurityGroupId
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 5 * time.Second, MaxBackoff: 5 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := vpcClient.DeleteSecurityGroup(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := vpcClient.DeleteSecurityGroup(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("delete security group(%s) failed: %s, you need to delete it by hand",
|
||||
s.SecurityGroupId, err.Error()))
|
||||
return
|
||||
Error(state, err, fmt.Sprintf("Failed to delete securitygroup(%s), please delete it manually", s.SecurityGroupId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,8 @@ package cvm
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/pkg/errors"
|
||||
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
|
||||
)
|
||||
|
||||
|
@ -22,79 +18,76 @@ type stepConfigSubnet struct {
|
|||
|
||||
func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
vpcClient := state.Get("vpc_client").(*vpc.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
vpcId := state.Get("vpc_id").(string)
|
||||
|
||||
if len(s.SubnetId) != 0 { // exist subnet
|
||||
ui.Say(fmt.Sprintf("Trying to use existing subnet(%s)", s.SubnetId))
|
||||
if len(s.SubnetId) != 0 {
|
||||
Say(state, s.SubnetId, "Trying to use existing subnet")
|
||||
req := vpc.NewDescribeSubnetsRequest()
|
||||
req.SubnetIds = []*string{&s.SubnetId}
|
||||
resp, err := vpcClient.DescribeSubnets(req)
|
||||
var resp *vpc.DescribeSubnetsResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = vpcClient.DescribeSubnets(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("query subnet failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to get subnet info")
|
||||
}
|
||||
if *resp.Response.TotalCount > 0 {
|
||||
subnet0 := *resp.Response.SubnetSet[0]
|
||||
if *subnet0.VpcId != vpcId {
|
||||
message := fmt.Sprintf("the specified subnet(%s) does not belong to "+
|
||||
"the specified vpc(%s)", s.SubnetId, vpcId)
|
||||
ui.Error(message)
|
||||
state.Put("error", errors.New(message))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
state.Put("subnet_id", *subnet0.SubnetId)
|
||||
s.isCreate = false
|
||||
if *resp.Response.SubnetSet[0].VpcId != vpcId {
|
||||
return Halt(state, fmt.Errorf("The specified subnet(%s) does not belong to the specified vpc(%s)", s.SubnetId, vpcId), "")
|
||||
}
|
||||
state.Put("subnet_id", *resp.Response.SubnetSet[0].SubnetId)
|
||||
Message(state, *resp.Response.SubnetSet[0].SubnetName, "Subnet found")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
message := fmt.Sprintf("the specified subnet(%s) does not exist", s.SubnetId)
|
||||
state.Put("error", errors.New(message))
|
||||
ui.Error(message)
|
||||
return multistep.ActionHalt
|
||||
} else { // create a new subnet, tencentcloud create subnet api is synchronous, no need to wait for create.
|
||||
ui.Say(fmt.Sprintf("Trying to create a new subnet"))
|
||||
req := vpc.NewCreateSubnetRequest()
|
||||
req.VpcId = &vpcId
|
||||
req.SubnetName = &s.SubnetName
|
||||
req.CidrBlock = &s.SubnetCidrBlock
|
||||
req.Zone = &s.Zone
|
||||
resp, err := vpcClient.CreateSubnet(req)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("create subnet failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
subnet0 := *resp.Response.Subnet
|
||||
state.Put("subnet_id", *subnet0.SubnetId)
|
||||
s.SubnetId = *subnet0.SubnetId
|
||||
s.isCreate = true
|
||||
return multistep.ActionContinue
|
||||
return Halt(state, fmt.Errorf("The specified subnet(%s) does not exist", s.SubnetId), "")
|
||||
}
|
||||
|
||||
Say(state, "Trying to create a new subnet", "")
|
||||
|
||||
req := vpc.NewCreateSubnetRequest()
|
||||
req.VpcId = &vpcId
|
||||
req.SubnetName = &s.SubnetName
|
||||
req.CidrBlock = &s.SubnetCidrBlock
|
||||
req.Zone = &s.Zone
|
||||
var resp *vpc.CreateSubnetResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = vpcClient.CreateSubnet(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
return Halt(state, err, "Failed to create subnet")
|
||||
}
|
||||
|
||||
s.isCreate = true
|
||||
s.SubnetId = *resp.Response.Subnet.SubnetId
|
||||
state.Put("subnet_id", s.SubnetId)
|
||||
Message(state, s.SubnetId, "Subnet created")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepConfigSubnet) Cleanup(state multistep.StateBag) {
|
||||
if !s.isCreate {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
vpcClient := state.Get("vpc_client").(*vpc.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
MessageClean(state, "SUBNET")
|
||||
SayClean(state, "subnet")
|
||||
|
||||
req := vpc.NewDeleteSubnetRequest()
|
||||
req.SubnetId = &s.SubnetId
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 5 * time.Second, MaxBackoff: 5 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := vpcClient.DeleteSubnet(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := vpcClient.DeleteSubnet(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("delete subnet(%s) failed: %s, you need to delete it by hand",
|
||||
s.SubnetId, err.Error()))
|
||||
return
|
||||
Error(state, err, fmt.Sprintf("Failed to delete subnet(%s), please delete it manually", s.SubnetId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,8 @@ package cvm
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/pkg/errors"
|
||||
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
|
||||
)
|
||||
|
||||
|
@ -21,69 +17,69 @@ type stepConfigVPC struct {
|
|||
|
||||
func (s *stepConfigVPC) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
vpcClient := state.Get("vpc_client").(*vpc.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
if len(s.VpcId) != 0 { // exist vpc
|
||||
ui.Say(fmt.Sprintf("Trying to use existing vpc(%s)", s.VpcId))
|
||||
if len(s.VpcId) != 0 {
|
||||
Say(state, s.VpcId, "Trying to use existing vpc")
|
||||
req := vpc.NewDescribeVpcsRequest()
|
||||
req.VpcIds = []*string{&s.VpcId}
|
||||
resp, err := vpcClient.DescribeVpcs(req)
|
||||
var resp *vpc.DescribeVpcsResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = vpcClient.DescribeVpcs(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("query vpc failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to get vpc info")
|
||||
}
|
||||
if *resp.Response.TotalCount > 0 {
|
||||
vpc0 := *resp.Response.VpcSet[0]
|
||||
state.Put("vpc_id", *vpc0.VpcId)
|
||||
s.isCreate = false
|
||||
state.Put("vpc_id", *resp.Response.VpcSet[0].VpcId)
|
||||
Message(state, *resp.Response.VpcSet[0].VpcName, "Vpc found")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
message := fmt.Sprintf("the specified vpc(%s) does not exist", s.VpcId)
|
||||
state.Put("error", errors.New(message))
|
||||
ui.Error(message)
|
||||
return multistep.ActionHalt
|
||||
} else { // create a new vpc, tencentcloud create vpc api is synchronous, no need to wait for create.
|
||||
ui.Say(fmt.Sprintf("Trying to create a new vpc"))
|
||||
req := vpc.NewCreateVpcRequest()
|
||||
req.VpcName = &s.VpcName
|
||||
req.CidrBlock = &s.CidrBlock
|
||||
resp, err := vpcClient.CreateVpc(req)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("create vpc failed: %s", err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
vpc0 := *resp.Response.Vpc
|
||||
state.Put("vpc_id", *vpc0.VpcId)
|
||||
s.VpcId = *vpc0.VpcId
|
||||
s.isCreate = true
|
||||
return multistep.ActionContinue
|
||||
return Halt(state, fmt.Errorf("The specified vpc(%s) does not exist", s.VpcId), "")
|
||||
}
|
||||
|
||||
Say(state, "Trying to create a new vpc", "")
|
||||
|
||||
req := vpc.NewCreateVpcRequest()
|
||||
req.VpcName = &s.VpcName
|
||||
req.CidrBlock = &s.CidrBlock
|
||||
var resp *vpc.CreateVpcResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = vpcClient.CreateVpc(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
return Halt(state, err, "Failed to create vpc")
|
||||
}
|
||||
|
||||
s.isCreate = true
|
||||
s.VpcId = *resp.Response.Vpc.VpcId
|
||||
state.Put("vpc_id", s.VpcId)
|
||||
Message(state, s.VpcId, "Vpc created")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepConfigVPC) Cleanup(state multistep.StateBag) {
|
||||
if !s.isCreate {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
vpcClient := state.Get("vpc_client").(*vpc.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
MessageClean(state, "VPC")
|
||||
SayClean(state, "vpc")
|
||||
|
||||
req := vpc.NewDeleteVpcRequest()
|
||||
req.VpcId = &s.VpcId
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 5 * time.Second, MaxBackoff: 5 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := vpcClient.DeleteVpc(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := vpcClient.DeleteVpc(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("delete vpc(%s) failed: %s, you need to delete it by hand",
|
||||
s.VpcId, err.Error()))
|
||||
return
|
||||
Error(state, err, fmt.Sprintf("Failed to delete vpc(%s), please delete it manually", s.VpcId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,9 @@ package cvm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
|
@ -20,9 +19,11 @@ func (s *stepCopyImage) Run(ctx context.Context, state multistep.StateBag) multi
|
|||
}
|
||||
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
imageId := state.Get("image").(*cvm.Image).ImageId
|
||||
|
||||
Say(state, strings.Join(s.DesinationRegions, ","), "Trying to copy image to")
|
||||
|
||||
req := cvm.NewSyncImagesRequest()
|
||||
req.ImageIds = []*string{imageId}
|
||||
copyRegions := make([]*string, 0, len(s.DesinationRegions))
|
||||
|
@ -33,15 +34,17 @@ func (s *stepCopyImage) Run(ctx context.Context, state multistep.StateBag) multi
|
|||
}
|
||||
req.DestinationRegions = copyRegions
|
||||
|
||||
_, err := client.SyncImages(req)
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.SyncImages(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
ui.Error(fmt.Sprintf("copy image failed: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to copy image")
|
||||
}
|
||||
|
||||
Message(state, "Image copied", "")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepCopyImage) Cleanup(state multistep.StateBag) {
|
||||
// just do nothing
|
||||
}
|
||||
func (s *stepCopyImage) Cleanup(state multistep.StateBag) {}
|
||||
|
|
|
@ -3,12 +3,8 @@ package cvm
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
|
@ -17,17 +13,18 @@ type stepCreateImage struct {
|
|||
}
|
||||
|
||||
func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
config := state.Get("config").(*Config)
|
||||
instance := state.Get("instance").(*cvm.Instance)
|
||||
|
||||
ui.Say(fmt.Sprintf("Creating image %s", config.ImageName))
|
||||
Say(state, config.ImageName, "Trying to create a new image")
|
||||
|
||||
req := cvm.NewCreateImageRequest()
|
||||
req.ImageName = &config.ImageName
|
||||
req.ImageDescription = &config.ImageDescription
|
||||
req.InstanceId = instance.InstanceId
|
||||
|
||||
// TODO: We should allow user to specify which data disk should be
|
||||
// included into created image.
|
||||
var dataDiskIds []*string
|
||||
|
@ -46,51 +43,24 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
req.ForcePoweroff = &False
|
||||
}
|
||||
|
||||
if config.Reboot {
|
||||
req.Reboot = &True
|
||||
} else {
|
||||
req.Reboot = &False
|
||||
}
|
||||
|
||||
if config.Sysprep {
|
||||
req.Sysprep = &True
|
||||
} else {
|
||||
req.Sysprep = &False
|
||||
}
|
||||
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{
|
||||
InitialBackoff: 5 * time.Second,
|
||||
MaxBackoff: 5 * time.Second,
|
||||
Multiplier: 2,
|
||||
}).Linear,
|
||||
ShouldRetry: func(err error) bool {
|
||||
if e, ok := err.(*errors.TencentCloudSDKError); ok {
|
||||
if e.Code == "InvalidImageName.Duplicate" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := client.CreateImage(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.CreateImage(req)
|
||||
return e
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
err := fmt.Errorf("create image failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to create image")
|
||||
}
|
||||
|
||||
Message(state, "Waiting for image ready", "")
|
||||
err = WaitForImageReady(client, config.ImageName, "NORMAL", 3600)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("create image failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to wait for image ready")
|
||||
}
|
||||
|
||||
describeReq := cvm.NewDescribeImagesRequest()
|
||||
|
@ -101,21 +71,24 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
Values: []*string{&config.ImageName},
|
||||
},
|
||||
}
|
||||
describeResp, err := client.DescribeImages(describeReq)
|
||||
|
||||
var describeResp *cvm.DescribeImagesResponse
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
describeResp, e = client.DescribeImages(describeReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
err := fmt.Errorf("wait image ready failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to wait for image ready")
|
||||
}
|
||||
|
||||
if *describeResp.Response.TotalCount == 0 {
|
||||
err := fmt.Errorf("create image(%s) failed", config.ImageName)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, fmt.Errorf("No image return"), "Failed to crate image")
|
||||
}
|
||||
|
||||
s.imageId = *describeResp.Response.ImageSet[0].ImageId
|
||||
state.Put("image", describeResp.Response.ImageSet[0])
|
||||
Message(state, s.imageId, "Image created")
|
||||
|
||||
tencentCloudImages := make(map[string]string)
|
||||
tencentCloudImages[config.Region] = s.imageId
|
||||
|
@ -128,20 +101,25 @@ func (s *stepCreateImage) Cleanup(state multistep.StateBag) {
|
|||
if s.imageId == "" {
|
||||
return
|
||||
}
|
||||
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
if !cancelled && !halted {
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Delete image because of cancellation or error...")
|
||||
SayClean(state, "image")
|
||||
|
||||
req := cvm.NewDeleteImagesRequest()
|
||||
req.ImageIds = []*string{&s.imageId}
|
||||
_, err := client.DeleteImages(req)
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.DeleteImages(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("delete image(%s) failed", s.imageId))
|
||||
Error(state, err, fmt.Sprintf("Failed to delete image(%s), please delete it manually", s.imageId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,8 @@ package cvm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
@ -17,35 +13,31 @@ type stepDetachTempKeyPair struct {
|
|||
|
||||
func (s *stepDetachTempKeyPair) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
instance := state.Get("instance").(*cvm.Instance)
|
||||
|
||||
if _, ok := state.GetOk("temporary_key_pair_id"); !ok {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
keyId := state.Get("temporary_key_pair_id").(*string)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
ui.Say(fmt.Sprintf("Detaching temporary key pair %s...", *keyId))
|
||||
|
||||
keyId := state.Get("temporary_key_pair_id").(string)
|
||||
instance := state.Get("instance").(*cvm.Instance)
|
||||
|
||||
Say(state, keyId, "Trying to detach keypair")
|
||||
|
||||
req := cvm.NewDisassociateInstancesKeyPairsRequest()
|
||||
req.KeyIds = []*string{keyId}
|
||||
req.KeyIds = []*string{&keyId}
|
||||
req.InstanceIds = []*string{instance.InstanceId}
|
||||
req.ForceStop = common.BoolPtr(true)
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{
|
||||
InitialBackoff: 5 * time.Second,
|
||||
MaxBackoff: 5 * time.Second,
|
||||
Multiplier: 2,
|
||||
}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := client.DisassociateInstancesKeyPairs(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.DisassociateInstancesKeyPairs(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Fail to detach temporary key pair from instance! Error: %s", err))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Fail to detach keypair from instance")
|
||||
}
|
||||
|
||||
Message(state, "Keypair detached", "")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepDetachTempKeyPair) Cleanup(state multistep.StateBag) {
|
||||
}
|
||||
func (s *stepDetachTempKeyPair) Cleanup(state multistep.StateBag) {}
|
||||
|
|
|
@ -2,19 +2,45 @@ package cvm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
type stepPreValidate struct {
|
||||
DestImageName string
|
||||
ForceDelete bool
|
||||
}
|
||||
|
||||
func (s *stepPreValidate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
ui.Say("TencentCloud support images with same name, image_name check is not required.")
|
||||
config := state.Get("config").(*Config)
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
|
||||
Say(state, config.ImageName, "Trying to check image name")
|
||||
|
||||
req := cvm.NewDescribeImagesRequest()
|
||||
req.Filters = []*cvm.Filter{
|
||||
{
|
||||
Name: common.StringPtr("image-name"),
|
||||
Values: []*string{&config.ImageName},
|
||||
},
|
||||
}
|
||||
var resp *cvm.DescribeImagesResponse
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
var err error
|
||||
resp, err = client.DescribeImages(req)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return Halt(state, err, "Failed to get images info")
|
||||
}
|
||||
|
||||
if *resp.Response.TotalCount > 0 {
|
||||
return Halt(state, fmt.Errorf("Image name %s has exists", config.ImageName), "")
|
||||
}
|
||||
|
||||
Message(state, "useable", "Image name")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,8 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
|
@ -32,8 +29,8 @@ type stepRunInstance struct {
|
|||
|
||||
func (s *stepRunInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
|
||||
config := state.Get("config").(*Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
source_image := state.Get("source_image").(*cvm.Image)
|
||||
vpc_id := state.Get("vpc_id").(string)
|
||||
subnet_id := state.Get("subnet_id").(string)
|
||||
|
@ -43,15 +40,14 @@ func (s *stepRunInstance) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
if password == "" && config.Comm.WinRMPassword != "" {
|
||||
password = config.Comm.WinRMPassword
|
||||
}
|
||||
|
||||
userData, err := s.getUserData(state)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("get user_data failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to get user_data")
|
||||
}
|
||||
|
||||
ui.Say("Creating Instance.")
|
||||
Say(state, "Trying to create a new instance", "")
|
||||
|
||||
// config RunInstances parameters
|
||||
POSTPAID_BY_HOUR := "POSTPAID_BY_HOUR"
|
||||
req := cvm.NewRunInstancesRequest()
|
||||
|
@ -71,7 +67,7 @@ func (s *stepRunInstance) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
// System disk snapshot is mandatory, so if there are additional data disks,
|
||||
// length will be larger than 1.
|
||||
if source_image.SnapshotSet != nil && len(source_image.SnapshotSet) > 1 {
|
||||
ui.Say("Use source image snapshot data disks, ignore user data disk settings.")
|
||||
Message(state, "Use source image snapshot data disks, ignore user data disk settings", "")
|
||||
var dataDisks []*cvm.DataDisk
|
||||
for _, snapshot := range source_image.SnapshotSet {
|
||||
if *snapshot.DiskUsage == "DATA_DISK" {
|
||||
|
@ -144,44 +140,49 @@ func (s *stepRunInstance) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
}
|
||||
}
|
||||
|
||||
resp, err := client.RunInstances(req)
|
||||
var resp *cvm.RunInstancesResponse
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
resp, e = client.RunInstances(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
err := fmt.Errorf("create instance failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to run instance")
|
||||
}
|
||||
|
||||
if len(resp.Response.InstanceIdSet) != 1 {
|
||||
err := fmt.Errorf("create instance failed: %d instance(s) created", len(resp.Response.InstanceIdSet))
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, fmt.Errorf("No instance return"), "Failed to run instance")
|
||||
}
|
||||
|
||||
s.instanceId = *resp.Response.InstanceIdSet[0]
|
||||
Message(state, "Waiting for instance ready", "")
|
||||
|
||||
err = WaitForInstance(client, s.instanceId, "RUNNING", 1800)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("wait instance launch failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to wait for instance ready")
|
||||
}
|
||||
|
||||
describeReq := cvm.NewDescribeInstancesRequest()
|
||||
describeReq.InstanceIds = []*string{&s.instanceId}
|
||||
describeResp, err := client.DescribeInstances(describeReq)
|
||||
var describeResp *cvm.DescribeInstancesResponse
|
||||
err = Retry(ctx, func(ctx context.Context) error {
|
||||
var e error
|
||||
describeResp, e = client.DescribeInstances(describeReq)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
err := fmt.Errorf("wait instance launch failed: %s", err.Error())
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to wait for instance ready")
|
||||
}
|
||||
|
||||
state.Put("instance", describeResp.Response.InstanceSet[0])
|
||||
Message(state, s.instanceId, "Instance created")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepRunInstance) getUserData(state multistep.StateBag) (string, error) {
|
||||
userData := s.UserData
|
||||
|
||||
if userData == "" && s.UserDataFile != "" {
|
||||
data, err := ioutil.ReadFile(s.UserDataFile)
|
||||
if err != nil {
|
||||
|
@ -189,8 +190,10 @@ func (s *stepRunInstance) getUserData(state multistep.StateBag) (string, error)
|
|||
}
|
||||
userData = string(data)
|
||||
}
|
||||
|
||||
userData = base64.StdEncoding.EncodeToString([]byte(userData))
|
||||
log.Printf(fmt.Sprintf("user_data: %s", userData))
|
||||
log.Printf(fmt.Sprintf("[DEBUG]getUserData: user_data: %s", userData))
|
||||
|
||||
return userData, nil
|
||||
}
|
||||
|
||||
|
@ -198,24 +201,19 @@ func (s *stepRunInstance) Cleanup(state multistep.StateBag) {
|
|||
if s.instanceId == "" {
|
||||
return
|
||||
}
|
||||
MessageClean(state, "Instance")
|
||||
|
||||
ctx := context.TODO()
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
SayClean(state, "instance")
|
||||
|
||||
req := cvm.NewTerminateInstancesRequest()
|
||||
req.InstanceIds = []*string{&s.instanceId}
|
||||
ctx := context.TODO()
|
||||
err := retry.Config{
|
||||
Tries: 60,
|
||||
RetryDelay: (&retry.Backoff{
|
||||
InitialBackoff: 5 * time.Second,
|
||||
MaxBackoff: 5 * time.Second,
|
||||
Multiplier: 2,
|
||||
}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
_, err := client.TerminateInstances(req)
|
||||
return err
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.TerminateInstances(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("terminate instance(%s) failed: %s", s.instanceId, err.Error()))
|
||||
Error(state, err, fmt.Sprintf("Failed to terminate instance(%s), please delete it manually", s.instanceId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ package cvm
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
|
||||
)
|
||||
|
||||
|
@ -19,50 +20,57 @@ func (s *stepShareImage) Run(ctx context.Context, state multistep.StateBag) mult
|
|||
}
|
||||
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
imageId := state.Get("image").(*cvm.Image).ImageId
|
||||
Say(state, strings.Join(s.ShareAccounts, ","), "Trying to share image to")
|
||||
|
||||
req := cvm.NewModifyImageSharePermissionRequest()
|
||||
req.ImageId = imageId
|
||||
SHARE := "SHARE"
|
||||
req.Permission = &SHARE
|
||||
req.Permission = common.StringPtr("SHARE")
|
||||
accounts := make([]*string, 0, len(s.ShareAccounts))
|
||||
for _, account := range s.ShareAccounts {
|
||||
accounts = append(accounts, &account)
|
||||
}
|
||||
req.AccountIds = accounts
|
||||
|
||||
_, err := client.ModifyImageSharePermission(req)
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.ModifyImageSharePermission(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
ui.Error(fmt.Sprintf("share image failed: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
return Halt(state, err, "Failed to share image")
|
||||
}
|
||||
|
||||
Message(state, "Image shared", "")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepShareImage) Cleanup(state multistep.StateBag) {
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
if cancelled || halted {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
imageId := state.Get("image").(*cvm.Image).ImageId
|
||||
ui.Say("Cancel share image due to action cancelled or halted.")
|
||||
if !cancelled && !halted {
|
||||
return
|
||||
}
|
||||
|
||||
req := cvm.NewModifyImageSharePermissionRequest()
|
||||
req.ImageId = imageId
|
||||
CANCEL := "CANCEL"
|
||||
req.Permission = &CANCEL
|
||||
accounts := make([]*string, 0, len(s.ShareAccounts))
|
||||
for _, account := range s.ShareAccounts {
|
||||
accounts = append(accounts, &account)
|
||||
}
|
||||
req.AccountIds = accounts
|
||||
ctx := context.TODO()
|
||||
client := state.Get("cvm_client").(*cvm.Client)
|
||||
|
||||
_, err := client.ModifyImageSharePermission(req)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Cancel share image failed: %s", err.Error()))
|
||||
}
|
||||
imageId := state.Get("image").(*cvm.Image).ImageId
|
||||
SayClean(state, "image share")
|
||||
|
||||
req := cvm.NewModifyImageSharePermissionRequest()
|
||||
req.ImageId = imageId
|
||||
req.Permission = common.StringPtr("CANCEL")
|
||||
accounts := make([]*string, 0, len(s.ShareAccounts))
|
||||
for _, account := range s.ShareAccounts {
|
||||
accounts = append(accounts, &account)
|
||||
}
|
||||
req.AccountIds = accounts
|
||||
err := Retry(ctx, func(ctx context.Context) error {
|
||||
_, e := client.ModifyImageSharePermission(req)
|
||||
return e
|
||||
})
|
||||
if err != nil {
|
||||
Error(state, err, fmt.Sprintf("Failed to cancel share image(%s), please delete it manually", *imageId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,32 +3,38 @@
|
|||
"secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}",
|
||||
"secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}"
|
||||
},
|
||||
"builders": [{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-4",
|
||||
"instance_type": "S4.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"ssh_username" : "root",
|
||||
"image_name": "PackerTest",
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"packer_debug": true,
|
||||
"associate_public_ip_address": true,
|
||||
"run_tags": {
|
||||
"good": "luck"
|
||||
},
|
||||
"data_disks": [{
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"disk_size": 50
|
||||
}]
|
||||
}],
|
||||
"provisioners": [{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sleep 30",
|
||||
"yum install redis.x86_64 -y"
|
||||
]
|
||||
}]
|
||||
}
|
||||
"builders": [
|
||||
{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-4",
|
||||
"instance_type": "S4.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"ssh_username": "root",
|
||||
"image_name": "PackerTest",
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"packer_debug": true,
|
||||
"associate_public_ip_address": true,
|
||||
"data_disks": [
|
||||
{
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"disk_size": 50
|
||||
}
|
||||
],
|
||||
"run_tags": {
|
||||
"good": "luck"
|
||||
}
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sleep 30",
|
||||
"yum install redis.x86_64 -y"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,28 +3,32 @@
|
|||
"secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}",
|
||||
"secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}"
|
||||
},
|
||||
"builders": [{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-4",
|
||||
"instance_type": "S4.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"ssh_username" : "root",
|
||||
"image_name": "PackerTest",
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"packer_debug": true,
|
||||
"associate_public_ip_address": true,
|
||||
"run_tags": {
|
||||
"good": "luck"
|
||||
"builders": [
|
||||
{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-4",
|
||||
"instance_type": "S4.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"ssh_username": "root",
|
||||
"image_name": "PackerTest",
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"packer_debug": true,
|
||||
"associate_public_ip_address": true,
|
||||
"run_tags": {
|
||||
"good": "luck"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"provisioners": [{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sleep 30",
|
||||
"yum install redis.x86_64 -y"
|
||||
]
|
||||
}]
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sleep 30",
|
||||
"yum install redis.x86_64 -y"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,33 +3,40 @@
|
|||
"secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}",
|
||||
"secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}"
|
||||
},
|
||||
"builders": [{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-3",
|
||||
"instance_type": "S3.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"vpc_id": "vpc-gjusx3kd",
|
||||
"subnet_id": "subnet-pfditepm",
|
||||
"internet_max_bandwidth_out": 2,
|
||||
"security_group_id": "sg-rypoiksl",
|
||||
"ssh_username" : "root",
|
||||
"image_name": "packerTest",
|
||||
"host_name": "packerTest",
|
||||
"associate_public_ip_address": true,
|
||||
"image_description": "centosPacker",
|
||||
"image_copy_regions": ["ap-beijing"]
|
||||
}],
|
||||
"provisioners": [{
|
||||
"execute_command": "echo '{{user `ssh_pass`}}' | {{ .Vars }} sudo -S -E sh '{{ .Path }}'",
|
||||
"inline": [
|
||||
"yum update -y",
|
||||
"/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
|
||||
],
|
||||
"inline_shebang": "/bin/sh -x",
|
||||
"type": "shell",
|
||||
"skip_clean": true
|
||||
}]
|
||||
"builders": [
|
||||
{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-3",
|
||||
"instance_type": "S3.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"vpc_id": "vpc-h70b6b49",
|
||||
"subnet_id": "subnet-1uwh63so",
|
||||
"internet_max_bandwidth_out": 2,
|
||||
"security_group_id": "sg-nltpbqg1",
|
||||
"ssh_username": "root",
|
||||
"image_name": "packerTest",
|
||||
"host_name": "packerTest",
|
||||
"associate_public_ip_address": true,
|
||||
"image_description": "centosPacker",
|
||||
"image_copy_regions": [
|
||||
"ap-beijing"
|
||||
]
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"execute_command": "echo '{{user `ssh_pass`}}' | {{ .Vars }} sudo -S -E sh '{{ .Path }}'",
|
||||
"inline": [
|
||||
"yum update -y",
|
||||
"/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
|
||||
],
|
||||
"inline_shebang": "/bin/sh -x",
|
||||
"type": "shell",
|
||||
"skip_clean": true
|
||||
}
|
||||
]
|
||||
}
|
2
go.mod
2
go.mod
|
@ -132,7 +132,7 @@ require (
|
|||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/temoto/robotstxt v1.1.1 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.71+incompatible
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.94+incompatible
|
||||
github.com/ucloud/ucloud-sdk-go v0.8.7
|
||||
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1
|
||||
github.com/ulikunitz/xz v0.5.5
|
||||
|
|
4
go.sum
4
go.sum
|
@ -395,8 +395,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=
|
||||
github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.71+incompatible h1:9sIWfe6ZC7xoSlshYWNGicPqomK7N+CsHMa1YFWBCWU=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.71+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.94+incompatible h1:G8i7dPMK1RCpbQz+VpfFp679vmVna38NI8tz5xsybXI=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.94+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/ucloud/ucloud-sdk-go v0.8.7 h1:BmXOb5RivI0Uu4oZRpjI6SQ9/y7n/H9wxTGR1txIE8o=
|
||||
github.com/ucloud/ucloud-sdk-go v0.8.7/go.mod h1:lM6fpI8y6iwACtlbHUav823/uKPdXsNBlnBpRF2fj3c=
|
||||
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1 h1:U6ufy3mLDgg9RYupntOvAF7xCmNNquyKaYaaVHo1Nnk=
|
||||
|
|
35
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/client.go
generated
vendored
35
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/client.go
generated
vendored
|
@ -6,10 +6,12 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
|
||||
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||
)
|
||||
|
@ -18,6 +20,7 @@ type Client struct {
|
|||
region string
|
||||
httpClient *http.Client
|
||||
httpProfile *profile.HttpProfile
|
||||
profile *profile.ClientProfile
|
||||
credential *Credential
|
||||
signMethod string
|
||||
unsignedPayload bool
|
||||
|
@ -47,6 +50,8 @@ func (c *Client) Send(request tchttp.Request, response tchttp.Response) (err err
|
|||
}
|
||||
|
||||
func (c *Client) sendWithSignatureV1(request tchttp.Request, response tchttp.Response) (err error) {
|
||||
// TODO: not an elegant way, it should be done in common params, but finally it need to refactor
|
||||
request.GetParams()["Language"] = c.profile.Language
|
||||
err = tchttp.ConstructParams(request)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -62,10 +67,18 @@ func (c *Client) sendWithSignatureV1(request tchttp.Request, response tchttp.Res
|
|||
if request.GetHttpMethod() == "POST" {
|
||||
httpRequest.Header["Content-Type"] = []string{"application/x-www-form-urlencoded"}
|
||||
}
|
||||
//log.Printf("[DEBUG] http request=%v", httpRequest)
|
||||
if c.debug {
|
||||
outbytes, err := httputil.DumpRequest(httpRequest, true)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] dump request failed because %s", err)
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] http request = %s", outbytes)
|
||||
}
|
||||
httpResponse, err := c.httpClient.Do(httpRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
msg := fmt.Sprintf("Fail to get response because %s", err)
|
||||
return errors.NewTencentCloudSDKError("ClientError.NetworkError", msg, "")
|
||||
}
|
||||
err = tchttp.ParseFromHttpResponse(httpResponse, response)
|
||||
return err
|
||||
|
@ -78,6 +91,7 @@ func (c *Client) sendWithSignatureV3(request tchttp.Request, response tchttp.Res
|
|||
"X-TC-Version": request.GetVersion(),
|
||||
"X-TC-Timestamp": request.GetParams()["Timestamp"],
|
||||
"X-TC-RequestClient": request.GetParams()["RequestClient"],
|
||||
"X-TC-Language": c.profile.Language,
|
||||
}
|
||||
if c.region != "" {
|
||||
headers["X-TC-Region"] = c.region
|
||||
|
@ -184,10 +198,18 @@ func (c *Client) sendWithSignatureV3(request tchttp.Request, response tchttp.Res
|
|||
for k, v := range headers {
|
||||
httpRequest.Header[k] = []string{v}
|
||||
}
|
||||
//log.Printf("[DEBUG] http request=%v, body=%v", httpRequest, requestPayload)
|
||||
if c.debug {
|
||||
outbytes, err := httputil.DumpRequest(httpRequest, true)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] dump request failed because %s", err)
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] http request = %s", outbytes)
|
||||
}
|
||||
httpResponse, err := c.httpClient.Do(httpRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
msg := fmt.Sprintf("Fail to get response because %s", err)
|
||||
return errors.NewTencentCloudSDKError("ClientError.NetworkError", msg, "")
|
||||
}
|
||||
err = tchttp.ParseFromHttpResponse(httpResponse, response)
|
||||
return err
|
||||
|
@ -200,7 +222,7 @@ func (c *Client) GetRegion() string {
|
|||
func (c *Client) Init(region string) *Client {
|
||||
c.httpClient = &http.Client{}
|
||||
c.region = region
|
||||
c.signMethod = "HmacSHA256"
|
||||
c.signMethod = "TC3-HMAC-SHA256"
|
||||
c.debug = false
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
return c
|
||||
|
@ -217,6 +239,7 @@ func (c *Client) WithCredential(cred *Credential) *Client {
|
|||
}
|
||||
|
||||
func (c *Client) WithProfile(clientProfile *profile.ClientProfile) *Client {
|
||||
c.profile = clientProfile
|
||||
c.signMethod = clientProfile.SignMethod
|
||||
c.unsignedPayload = clientProfile.UnsignedPayload
|
||||
c.httpProfile = clientProfile.HttpProfile
|
||||
|
@ -229,7 +252,7 @@ func (c *Client) WithSignatureMethod(method string) *Client {
|
|||
return c
|
||||
}
|
||||
|
||||
func (c *Client) WithHttpTransport (transport http.RoundTripper) *Client {
|
||||
func (c *Client) WithHttpTransport(transport http.RoundTripper) *Client {
|
||||
c.httpClient.Transport = transport
|
||||
return c
|
||||
}
|
||||
|
|
15
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go
generated
vendored
15
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go
generated
vendored
|
@ -152,7 +152,7 @@ func CompleteCommonParams(request Request, region string) {
|
|||
params["Action"] = request.GetAction()
|
||||
params["Timestamp"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
params["Nonce"] = strconv.Itoa(rand.Int())
|
||||
params["RequestClient"] = "SDK_GO_3.0.71"
|
||||
params["RequestClient"] = "SDK_GO_3.0.94"
|
||||
}
|
||||
|
||||
func ConstructParams(req Request) (err error) {
|
||||
|
@ -195,8 +195,9 @@ func flatStructure(value reflect.Value, request Request, prefix string) (err err
|
|||
} else if kind == reflect.Float64 {
|
||||
request.GetParams()[key] = strconv.FormatFloat(field.Float(), 'f', -1, 64)
|
||||
} else if kind == reflect.Slice {
|
||||
for j := 0; j < field.Len(); j++ {
|
||||
vj := field.Index(j)
|
||||
list := value.Field(i)
|
||||
for j := 0; j < list.Len(); j++ {
|
||||
vj := list.Index(j)
|
||||
key := prefix + nameTag + "." + strconv.Itoa(j)
|
||||
kind = vj.Kind()
|
||||
if kind == reflect.Ptr && vj.IsNil() {
|
||||
|
@ -217,11 +218,15 @@ func flatStructure(value reflect.Value, request Request, prefix string) (err err
|
|||
} else if kind == reflect.Float64 {
|
||||
request.GetParams()[key] = strconv.FormatFloat(vj.Float(), 'f', -1, 64)
|
||||
} else {
|
||||
return flatStructure(vj, request, key+".")
|
||||
if err = flatStructure(vj, request, key+"."); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return flatStructure(reflect.ValueOf(field.Interface()), request, prefix+nameTag+".")
|
||||
if err = flatStructure(reflect.ValueOf(field.Interface()), request, prefix+nameTag+"."); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
17
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/response.go
generated
vendored
17
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/response.go
generated
vendored
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
//"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
|
||||
|
@ -37,7 +37,8 @@ func (r *BaseResponse) ParseErrorFromHTTPResponse(body []byte) (err error) {
|
|||
resp := &ErrorResponse{}
|
||||
err = json.Unmarshal(body, resp)
|
||||
if err != nil {
|
||||
return
|
||||
msg := fmt.Sprintf("Fail to parse json content: %s, because: %s", body, err)
|
||||
return errors.NewTencentCloudSDKError("ClientError.ParseJsonError", msg, "")
|
||||
}
|
||||
if resp.Response.Error.Code != "" {
|
||||
return errors.NewTencentCloudSDKError(resp.Response.Error.Code, resp.Response.Error.Message, resp.Response.RequestId)
|
||||
|
@ -46,7 +47,8 @@ func (r *BaseResponse) ParseErrorFromHTTPResponse(body []byte) (err error) {
|
|||
deprecated := &DeprecatedAPIErrorResponse{}
|
||||
err = json.Unmarshal(body, deprecated)
|
||||
if err != nil {
|
||||
return
|
||||
msg := fmt.Sprintf("Fail to parse json content: %s, because: %s", body, err)
|
||||
return errors.NewTencentCloudSDKError("ClientError.ParseJsonError", msg, "")
|
||||
}
|
||||
if deprecated.Code != 0 {
|
||||
return errors.NewTencentCloudSDKError(deprecated.CodeDesc, deprecated.Message, "")
|
||||
|
@ -58,10 +60,12 @@ func ParseFromHttpResponse(hr *http.Response, response Response) (err error) {
|
|||
defer hr.Body.Close()
|
||||
body, err := ioutil.ReadAll(hr.Body)
|
||||
if err != nil {
|
||||
return
|
||||
msg := fmt.Sprintf("Fail to read response body because %s", err)
|
||||
return errors.NewTencentCloudSDKError("ClientError.IOError", msg, "")
|
||||
}
|
||||
if hr.StatusCode != 200 {
|
||||
return fmt.Errorf("Request fail with status: %s, with body: %s", hr.Status, body)
|
||||
msg := fmt.Sprintf("Request fail with http status code: %s, with body: %s", hr.Status, body)
|
||||
return errors.NewTencentCloudSDKError("ClientError.HttpStatusCodeError", msg, "")
|
||||
}
|
||||
//log.Printf("[DEBUG] Response Body=%s", body)
|
||||
err = response.ParseErrorFromHTTPResponse(body)
|
||||
|
@ -70,7 +74,8 @@ func ParseFromHttpResponse(hr *http.Response, response Response) (err error) {
|
|||
}
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
log.Printf("Unexpected Error occurs when parsing API response\n%s\n", string(body[:]))
|
||||
msg := fmt.Sprintf("Fail to parse json content: %s, because: %s", body, err)
|
||||
return errors.NewTencentCloudSDKError("ClientError.ParseJsonError", msg, "")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package profile
|
||||
|
||||
type ClientProfile struct {
|
||||
HttpProfile *HttpProfile
|
||||
HttpProfile *HttpProfile
|
||||
// Valid choices: HmacSHA1, HmacSHA256, TC3-HMAC-SHA256.
|
||||
// Default value is TC3-HMAC-SHA256.
|
||||
SignMethod string
|
||||
UnsignedPayload bool
|
||||
// Valid choices: zh-CN, en-US.
|
||||
// Default value is zh-CN.
|
||||
Language string
|
||||
}
|
||||
|
||||
func NewClientProfile() *ClientProfile {
|
||||
|
@ -11,5 +16,6 @@ func NewClientProfile() *ClientProfile {
|
|||
HttpProfile: NewHttpProfile(),
|
||||
SignMethod: "TC3-HMAC-SHA256",
|
||||
UnsignedPayload: false,
|
||||
Language: "zh-CN",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ type HttpProfile struct {
|
|||
ReqMethod string
|
||||
ReqTimeout int
|
||||
Endpoint string
|
||||
Protocol string
|
||||
// Deprecated, use Scheme instead
|
||||
Protocol string
|
||||
Scheme string
|
||||
}
|
||||
|
||||
func NewHttpProfile() *HttpProfile {
|
||||
|
@ -12,6 +14,6 @@ func NewHttpProfile() *HttpProfile {
|
|||
ReqMethod: "POST",
|
||||
ReqTimeout: 60,
|
||||
Endpoint: "",
|
||||
Protocol: "HTTPS",
|
||||
Scheme: "HTTPS",
|
||||
}
|
||||
}
|
||||
|
|
19
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/sign.go
generated
vendored
19
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/sign.go
generated
vendored
|
@ -1,14 +1,13 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
|
||||
)
|
||||
|
@ -65,7 +64,11 @@ func getStringToSign(request tchttp.Request) string {
|
|||
domain := request.GetDomain()
|
||||
path := request.GetPath()
|
||||
|
||||
text := method + domain + path + "?"
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(method)
|
||||
buf.WriteString(domain)
|
||||
buf.WriteString(path)
|
||||
buf.WriteString("?")
|
||||
|
||||
params := request.GetParams()
|
||||
// sort params
|
||||
|
@ -77,11 +80,15 @@ func getStringToSign(request tchttp.Request) string {
|
|||
|
||||
for i := range keys {
|
||||
k := keys[i]
|
||||
// TODO: check if server side allows empty value in url.
|
||||
if params[k] == "" {
|
||||
continue
|
||||
}
|
||||
text += fmt.Sprintf("%v=%v&", strings.Replace(k, "_", ".", -1), params[k])
|
||||
buf.WriteString(k)
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(params[k])
|
||||
buf.WriteString("&")
|
||||
}
|
||||
text = text[:len(text)-1]
|
||||
return text
|
||||
buf.Truncate(buf.Len() - 1)
|
||||
return buf.String()
|
||||
}
|
||||
|
|
83
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/client.go
generated
vendored
83
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/client.go
generated
vendored
|
@ -743,6 +743,56 @@ func (c *Client) DescribeRegions(request *DescribeRegionsRequest) (response *Des
|
|||
return
|
||||
}
|
||||
|
||||
func NewDescribeReservedInstancesRequest() (request *DescribeReservedInstancesRequest) {
|
||||
request = &DescribeReservedInstancesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("cvm", APIVersion, "DescribeReservedInstances")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeReservedInstancesResponse() (response *DescribeReservedInstancesResponse) {
|
||||
response = &DescribeReservedInstancesResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DescribeReservedInstances)可提供列出用户已购买的预留实例
|
||||
func (c *Client) DescribeReservedInstances(request *DescribeReservedInstancesRequest) (response *DescribeReservedInstancesResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDescribeReservedInstancesRequest()
|
||||
}
|
||||
response = NewDescribeReservedInstancesResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeReservedInstancesOfferingsRequest() (request *DescribeReservedInstancesOfferingsRequest) {
|
||||
request = &DescribeReservedInstancesOfferingsRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("cvm", APIVersion, "DescribeReservedInstancesOfferings")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeReservedInstancesOfferingsResponse() (response *DescribeReservedInstancesOfferingsResponse) {
|
||||
response = &DescribeReservedInstancesOfferingsResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DescribeReservedInstancesOfferings)供用户列出可购买的预留实例配置
|
||||
func (c *Client) DescribeReservedInstancesOfferings(request *DescribeReservedInstancesOfferingsRequest) (response *DescribeReservedInstancesOfferingsResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDescribeReservedInstancesOfferingsRequest()
|
||||
}
|
||||
response = NewDescribeReservedInstancesOfferingsResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeZoneInstanceConfigInfosRequest() (request *DescribeZoneInstanceConfigInfosRequest) {
|
||||
request = &DescribeZoneInstanceConfigInfosRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -863,7 +913,7 @@ func NewImportImageResponse() (response *ImportImageResponse) {
|
|||
return
|
||||
}
|
||||
|
||||
// 本接口(ImportImage)用于导入镜像,导入后的镜像可用于创建实例。
|
||||
// 本接口(ImportImage)用于导入镜像,导入后的镜像可用于创建实例。
|
||||
func (c *Client) ImportImage(request *ImportImageRequest) (response *ImportImageResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewImportImageRequest()
|
||||
|
@ -972,7 +1022,11 @@ func NewInquiryPriceResetInstanceResponse() (response *InquiryPriceResetInstance
|
|||
return
|
||||
}
|
||||
|
||||
// 本接口 (InquiryPriceResetInstance) 用于重装实例询价。* 如果指定了`ImageId`参数,则使用指定的镜像进行重装询价;否则按照当前实例使用的镜像进行重装询价。* 目前只支持[系统盘类型](/document/api/213/9452#block_device)是`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`类型的实例使用该接口实现`Linux`和`Windows`操作系统切换的重装询价。* 目前不支持海外地域的实例使用该接口实现`Linux`和`Windows`操作系统切换的重装询价。
|
||||
// 本接口 (InquiryPriceResetInstance) 用于重装实例询价。
|
||||
//
|
||||
// * 如果指定了`ImageId`参数,则使用指定的镜像进行重装询价;否则按照当前实例使用的镜像进行重装询价。
|
||||
// * 目前只支持[系统盘类型](/document/api/213/9452#block_device)是`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`类型的实例使用该接口实现`Linux`和`Windows`操作系统切换的重装询价。
|
||||
// * 目前不支持海外地域的实例使用该接口实现`Linux`和`Windows`操作系统切换的重装询价。
|
||||
func (c *Client) InquiryPriceResetInstance(request *InquiryPriceResetInstanceRequest) (response *InquiryPriceResetInstanceResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewInquiryPriceResetInstanceRequest()
|
||||
|
@ -1374,6 +1428,31 @@ func (c *Client) ModifyKeyPairAttribute(request *ModifyKeyPairAttributeRequest)
|
|||
return
|
||||
}
|
||||
|
||||
func NewPurchaseReservedInstancesOfferingRequest() (request *PurchaseReservedInstancesOfferingRequest) {
|
||||
request = &PurchaseReservedInstancesOfferingRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("cvm", APIVersion, "PurchaseReservedInstancesOffering")
|
||||
return
|
||||
}
|
||||
|
||||
func NewPurchaseReservedInstancesOfferingResponse() (response *PurchaseReservedInstancesOfferingResponse) {
|
||||
response = &PurchaseReservedInstancesOfferingResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(PurchaseReservedInstancesOffering)用于用户购买一个或者多个指定配置的预留实例
|
||||
func (c *Client) PurchaseReservedInstancesOffering(request *PurchaseReservedInstancesOfferingRequest) (response *PurchaseReservedInstancesOfferingResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewPurchaseReservedInstancesOfferingRequest()
|
||||
}
|
||||
response = NewPurchaseReservedInstancesOfferingResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewRebootInstancesRequest() (request *RebootInstancesRequest) {
|
||||
request = &RebootInstancesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
|
357
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/models.go
generated
vendored
357
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/models.go
generated
vendored
|
@ -243,19 +243,17 @@ type CreateImageRequest struct {
|
|||
// 镜像描述
|
||||
ImageDescription *string `json:"ImageDescription,omitempty" name:"ImageDescription"`
|
||||
|
||||
// 软关机失败时是否执行强制关机以制作镜像
|
||||
// 是否执行强制关机以制作镜像。
|
||||
// 取值范围:<br><li>TRUE:表示关机之后制作镜像<br><li>FALSE:表示开机状态制作镜像<br><br>默认取值:FALSE。<br><br>开机状态制作镜像,可能导致部分数据未备份,影响数据安全。
|
||||
ForcePoweroff *string `json:"ForcePoweroff,omitempty" name:"ForcePoweroff"`
|
||||
|
||||
// 创建Windows镜像时是否启用Sysprep
|
||||
Sysprep *string `json:"Sysprep,omitempty" name:"Sysprep"`
|
||||
|
||||
// 实例处于运行中时,是否允许关机执行制作镜像任务。
|
||||
Reboot *string `json:"Reboot,omitempty" name:"Reboot"`
|
||||
|
||||
// 实例需要制作镜像的数据盘Id
|
||||
DataDiskIds []*string `json:"DataDiskIds,omitempty" name:"DataDiskIds" list`
|
||||
|
||||
// 需要制作镜像的快照Id,必须包含一个系统盘快照
|
||||
// 需要制作镜像的快照ID,必须包含一个系统盘快照
|
||||
SnapshotIds []*string `json:"SnapshotIds,omitempty" name:"SnapshotIds" list`
|
||||
|
||||
// 检测请求的合法性,但不会对操作的资源产生任何影响
|
||||
|
@ -683,8 +681,11 @@ type DescribeImagesRequest struct {
|
|||
|
||||
// 过滤条件,每次请求的`Filters`的上限为0,`Filters.Values`的上限为5。参数不可以同时指定`ImageIds`和`Filters`。详细的过滤条件如下:
|
||||
// <li> image-id - String - 是否必填: 否 - (过滤条件)按照镜像ID进行过滤</li>
|
||||
// <li> image-type - String - 是否必填: 否 - (过滤条件)按照镜像类型进行过滤。取值范围:详见[镜像类型](https://cloud.tencent.com/document/product/213/9452#image_type)。</li>
|
||||
// <li> image-state - String - 是否必填: 否 - (过滤条件)按照镜像状态进行过滤。取值范围:详见[镜像状态](https://cloud.tencent.com/document/product/213/9452#image_state)。</li>
|
||||
// <li> image-type - String - 是否必填: 否 - (过滤条件)按照镜像类型进行过滤。取值范围:
|
||||
// PRIVATE_IMAGE: 私有镜像 (本帐户创建的镜像)
|
||||
// PUBLIC_IMAGE: 公共镜像 (腾讯云官方镜像)
|
||||
// MARKET_IMAGE: 服务市场 (服务市场提供的镜像)
|
||||
// SHARED_IMAGE: 共享镜像(其他账户共享给本帐户的镜像) 。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量,默认为0。关于Offset详见[API简介](/document/api/213/568#.E8.BE.93.E5.85.A5.E5.8F.82.E6.95.B0.E4.B8.8E.E8.BF.94.E5.9B.9E.E5.8F.82.E6.95.B0.E9.87.8A.E4.B9.89)。
|
||||
|
@ -1188,6 +1189,140 @@ func (r *DescribeRegionsResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeReservedInstancesOfferingsRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// 试运行, 默认为 false。
|
||||
DryRun *bool `json:"DryRun,omitempty" name:"DryRun"`
|
||||
|
||||
// 偏移量,默认为0。关于`Offset`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。
|
||||
Offset *int64 `json:"Offset,omitempty" name:"Offset"`
|
||||
|
||||
// 返回数量,默认为20,最大值为100。关于`Limit`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。
|
||||
Limit *int64 `json:"Limit,omitempty" name:"Limit"`
|
||||
|
||||
// 以最大有效期作为过滤参数。
|
||||
// 计量单位: 秒
|
||||
// 默认为 94608000。
|
||||
MaxDuration *int64 `json:"MaxDuration,omitempty" name:"MaxDuration"`
|
||||
|
||||
// 以最小有效期作为过滤参数。
|
||||
// 计量单位: 秒
|
||||
// 默认为 2592000。
|
||||
MinDuration *int64 `json:"MinDuration,omitempty" name:"MinDuration"`
|
||||
|
||||
// <li><strong>zone</strong></li>
|
||||
// <p style="padding-left: 30px;">按照预留实例计费可购买的【<strong>可用区</strong>】进行过滤。形如:ap-guangzhou-1。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:<a href="https://cloud.tencent.com/document/product/213/6091">可用区列表</a></p>
|
||||
// <li><strong>duration</strong></li>
|
||||
// <p style="padding-left: 30px;">按照预留实例计费【<strong>有效期</strong>】即预留实例计费购买时长进行过滤。形如:31536000。</p><p style="padding-left: 30px;">类型:Integer</p><p style="padding-left: 30px;">计量单位:秒</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:31536000 (1年) | 94608000(3年)</p>
|
||||
// <li><strong>instance-type</strong></li>
|
||||
// <p style="padding-left: 30px;">按照【<strong>预留实例计费类型</strong>】进行过滤。形如:S3.MEDIUM4。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:<a href="https://cloud.tencent.com/document/product/213/11518">预留实例计费类型列表</a></p>
|
||||
// <li><strong>offering-type</strong></li>
|
||||
// <p style="padding-left: 30px;">按照【<strong>付款类型</strong>】进行过滤。形如:All Upfront (预付全部费用)。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:All Upfront (预付全部费用)</p>
|
||||
// <li><strong>product-description</strong></li>
|
||||
// <p style="padding-left: 30px;">按照预留实例计费的【<strong>平台描述</strong>】(即操作系统)进行过滤。形如:linux。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:linux</p>
|
||||
// <li><strong>reserved-instances-offering-id</strong></li>
|
||||
// <p style="padding-left: 30px;">按照【<strong>预留实例计费配置ID</strong>】进行过滤。形如:650c138f-ae7e-4750-952a-96841d6e9fc1。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p>
|
||||
// 每次请求的`Filters`的上限为10,`Filter.Values`的上限为5。
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesOfferingsRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesOfferingsRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeReservedInstancesOfferingsResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 符合条件的预留实例计费数量。
|
||||
TotalCount *int64 `json:"TotalCount,omitempty" name:"TotalCount"`
|
||||
|
||||
// 符合条件的预留实例计费列表。
|
||||
ReservedInstancesOfferingsSet []*ReservedInstancesOffering `json:"ReservedInstancesOfferingsSet,omitempty" name:"ReservedInstancesOfferingsSet" list`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesOfferingsResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesOfferingsResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeReservedInstancesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// 试运行。默认为 false。
|
||||
DryRun *bool `json:"DryRun,omitempty" name:"DryRun"`
|
||||
|
||||
// 偏移量,默认为0。关于`Offset`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。
|
||||
Offset *int64 `json:"Offset,omitempty" name:"Offset"`
|
||||
|
||||
// 返回数量,默认为20,最大值为100。关于`Limit`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。
|
||||
Limit *int64 `json:"Limit,omitempty" name:"Limit"`
|
||||
|
||||
// <li><strong>zone</strong></li>
|
||||
// <p style="padding-left: 30px;">按照预留实例计费可购买的【<strong>可用区</strong>】进行过滤。形如:ap-guangzhou-1。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:<a href="https://cloud.tencent.com/document/product/213/6091">可用区列表</a></p>
|
||||
// <li><strong>duration</strong></li>
|
||||
// <p style="padding-left: 30px;">按照预留实例计费【<strong>有效期</strong>】即预留实例计费购买时长进行过滤。形如:31536000。</p><p style="padding-left: 30px;">类型:Integer</p><p style="padding-left: 30px;">计量单位:秒</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:31536000 (1年) | 94608000(3年)</p>
|
||||
// <li><strong>instance-type</strong></li>
|
||||
// <p style="padding-left: 30px;">按照【<strong>预留实例计费类型</strong>】进行过滤。形如:S3.MEDIUM4。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:<a href="https://cloud.tencent.com/document/product/213/11518">预留实例计费类型列表</a></p>
|
||||
// <li><strong>offering-type</strong></li>
|
||||
// <p style="padding-left: 30px;">按照【<strong>付款类型</strong>】进行过滤。形如:All Upfront (预付全部费用)。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:All Upfront (预付全部费用)</p>
|
||||
// <li><strong>product-description</strong></li>
|
||||
// <p style="padding-left: 30px;">按照预留实例计费的【<strong>平台描述</strong>】(即操作系统)进行过滤。形如:linux。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:linux</p>
|
||||
// <li><strong>reserved-instances-id</strong></li>
|
||||
// <p style="padding-left: 30px;">按照已购买【<strong>预留实例计费ID</strong>】进行过滤。形如:650c138f-ae7e-4750-952a-96841d6e9fc1。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p>
|
||||
// <li><strong>state</strong></li>
|
||||
// <p style="padding-left: 30px;">按照已购买【<strong>预留实例计费状态</strong>】进行过滤。形如:active。</p><p style="padding-left: 30px;">类型:String</p><p style="padding-left: 30px;">必选:否</p><p style="padding-left: 30px;">可选项:active (以创建) | pending (等待被创建) | retired (过期)</p>
|
||||
// 每次请求的`Filters`的上限为10,`Filter.Values`的上限为5。
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeReservedInstancesResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 符合条件的预留实例计费数量。
|
||||
TotalCount *int64 `json:"TotalCount,omitempty" name:"TotalCount"`
|
||||
|
||||
// 符合条件的预留实例计费列表。
|
||||
ReservedInstancesSet []*ReservedInstances `json:"ReservedInstancesSet,omitempty" name:"ReservedInstancesSet" list`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeReservedInstancesResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeZoneInstanceConfigInfosRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -2010,7 +2145,7 @@ type Instance struct {
|
|||
// 实例名称。
|
||||
InstanceName *string `json:"InstanceName,omitempty" name:"InstanceName"`
|
||||
|
||||
// 实例计费模式。取值范围:<br><li>`PREPAID`:表示预付费,即包年包月<br><li>`POSTPAID_BY_HOUR`:表示后付费,即按量计费<br><li>`CDHPAID`:`CDH`付费,即只对`CDH`计费,不对`CDH`上的实例计费。
|
||||
// 实例计费模式。取值范围:<br><li>`PREPAID`:表示预付费,即包年包月<br><li>`POSTPAID_BY_HOUR`:表示后付费,即按量计费<br><li>`CDHPAID`:`CDH`付费,即只对`CDH`计费,不对`CDH`上的实例计费。<br><li>`SPOTPAID`:表示竞价实例付费。
|
||||
InstanceChargeType *string `json:"InstanceChargeType,omitempty" name:"InstanceChargeType"`
|
||||
|
||||
// 实例系统盘信息。
|
||||
|
@ -2062,6 +2197,24 @@ type Instance struct {
|
|||
// 实例的关机计费模式。
|
||||
// 取值范围:<br><li>KEEP_CHARGING:关机继续收费<br><li>STOP_CHARGING:关机停止收费<li>NOT_APPLICABLE:实例处于非关机状态或者不适用关机停止计费的条件<br>
|
||||
StopChargingMode *string `json:"StopChargingMode,omitempty" name:"StopChargingMode"`
|
||||
|
||||
// 实例全局唯一ID
|
||||
Uuid *string `json:"Uuid,omitempty" name:"Uuid"`
|
||||
|
||||
// 实例的最新操作。例:StopInstances、ResetInstance。
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
LatestOperation *string `json:"LatestOperation,omitempty" name:"LatestOperation"`
|
||||
|
||||
// 实例的最新操作状态。取值范围:<br>
|
||||
// <li>SUCCESS:表示操作成功<br>
|
||||
// <li>OPERATING:表示操作执行中<br>
|
||||
// <li>FAILED:表示操作失败
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
LatestOperationState *string `json:"LatestOperationState,omitempty" name:"LatestOperationState"`
|
||||
|
||||
// 实例最新操作的唯一请求 ID。
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
LatestOperationRequestId *string `json:"LatestOperationRequestId,omitempty" name:"LatestOperationRequestId"`
|
||||
}
|
||||
|
||||
type InstanceChargePrepaid struct {
|
||||
|
@ -2139,7 +2292,7 @@ type InstanceTypeQuotaItem struct {
|
|||
// 实例机型。
|
||||
InstanceType *string `json:"InstanceType,omitempty" name:"InstanceType"`
|
||||
|
||||
// 实例计费模式。取值范围: <br><li>PREPAID:表示预付费,即包年包月<br><li>POSTPAID_BY_HOUR:表示后付费,即按量计费<br><li>CDHPAID:表示[CDH](https://cloud.tencent.com/document/product/416)付费,即只对CDH计费,不对CDH上的实例计费。
|
||||
// 实例计费模式。取值范围: <br><li>PREPAID:表示预付费,即包年包月<br><li>POSTPAID_BY_HOUR:表示后付费,即按量计费<br><li>CDHPAID:表示[CDH](https://cloud.tencent.com/document/product/416)付费,即只对CDH计费,不对CDH上的实例计费。<br><li>`SPOTPAID`:表示竞价实例付费。
|
||||
InstanceChargeType *string `json:"InstanceChargeType,omitempty" name:"InstanceChargeType"`
|
||||
|
||||
// 网卡类型,例如:25代表25G网卡
|
||||
|
@ -2179,10 +2332,10 @@ type InternetAccessible struct {
|
|||
// 公网出带宽上限,单位:Mbps。默认值:0Mbps。不同机型带宽上限范围不一致,具体限制详见[购买网络带宽](/document/product/213/509)。
|
||||
InternetMaxBandwidthOut *int64 `json:"InternetMaxBandwidthOut,omitempty" name:"InternetMaxBandwidthOut"`
|
||||
|
||||
// 是否分配公网IP。取值范围:<br><li>TRUE:表示分配公网IP<br><li>FALSE:表示不分配公网IP<br><br>当公网带宽大于0Mbps时,可自由选择开通与否,默认开通公网IP;当公网带宽为0,则不允许分配公网IP。
|
||||
// 是否分配公网IP。取值范围:<br><li>TRUE:表示分配公网IP<br><li>FALSE:表示不分配公网IP<br><br>当公网带宽大于0Mbps时,可自由选择开通与否,默认开通公网IP;当公网带宽为0,则不允许分配公网IP。该参数仅在RunInstances接口中作为入参使用。
|
||||
PublicIpAssigned *bool `json:"PublicIpAssigned,omitempty" name:"PublicIpAssigned"`
|
||||
|
||||
// 带宽包ID。可通过[`DescribeBandwidthPackages`](https://cloud.tencent.com/document/api/215/19209)接口返回值中的`BandwidthPackageId`获取。
|
||||
// 带宽包ID。可通过[`DescribeBandwidthPackages`](https://cloud.tencent.com/document/api/215/19209)接口返回值中的`BandwidthPackageId`获取。该参数仅在RunInstances接口中作为入参使用。
|
||||
BandwidthPackageId *string `json:"BandwidthPackageId,omitempty" name:"BandwidthPackageId"`
|
||||
}
|
||||
|
||||
|
@ -2714,6 +2867,9 @@ type Placement struct {
|
|||
|
||||
// 实例所属的专用宿主机ID列表。如果您有购买专用宿主机并且指定了该参数,则您购买的实例就会随机的部署在这些专用宿主机上。
|
||||
HostIds []*string `json:"HostIds,omitempty" name:"HostIds" list`
|
||||
|
||||
// 指定母机ip生产子机
|
||||
HostIps []*string `json:"HostIps,omitempty" name:"HostIps" list`
|
||||
}
|
||||
|
||||
type Price struct {
|
||||
|
@ -2725,6 +2881,52 @@ type Price struct {
|
|||
BandwidthPrice *ItemPrice `json:"BandwidthPrice,omitempty" name:"BandwidthPrice"`
|
||||
}
|
||||
|
||||
type PurchaseReservedInstancesOfferingRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// 购买预留实例计费数量
|
||||
InstanceCount *int64 `json:"InstanceCount,omitempty" name:"InstanceCount"`
|
||||
|
||||
// 预留实例计费配置ID
|
||||
ReservedInstancesOfferingId *string `json:"ReservedInstancesOfferingId,omitempty" name:"ReservedInstancesOfferingId"`
|
||||
|
||||
// 试运行
|
||||
DryRun *bool `json:"DryRun,omitempty" name:"DryRun"`
|
||||
|
||||
// 用于保证请求幂等性的字符串。该字符串由客户生成,需保证不同请求之间唯一,最大值不超过64个ASCII字符。若不指定该参数,则无法保证请求的幂等性。<br>更多详细信息请参阅:如何保证幂等性
|
||||
ClientToken *string `json:"ClientToken,omitempty" name:"ClientToken"`
|
||||
}
|
||||
|
||||
func (r *PurchaseReservedInstancesOfferingRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *PurchaseReservedInstancesOfferingRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type PurchaseReservedInstancesOfferingResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 已购买预留实例计费ID
|
||||
ReservedInstanceId *string `json:"ReservedInstanceId,omitempty" name:"ReservedInstanceId"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *PurchaseReservedInstancesOfferingResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *PurchaseReservedInstancesOfferingResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type RebootInstancesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -2733,6 +2935,9 @@ type RebootInstancesRequest struct {
|
|||
|
||||
// 是否在正常重启失败后选择强制重启实例。取值范围:<br><li>TRUE:表示在正常重启失败后进行强制重启<br><li>FALSE:表示在正常重启失败后不进行强制重启<br><br>默认取值:FALSE。
|
||||
ForceReboot *bool `json:"ForceReboot,omitempty" name:"ForceReboot"`
|
||||
|
||||
// 关机类型。取值范围:<br><li>SOFT:表示软关机<br><li>HARD:表示硬关机<br><li>SOFT_FIRST:表示优先软关机,失败再执行硬关机<br><br>默认取值:SOFT。
|
||||
StopType *string `json:"StopType,omitempty" name:"StopType"`
|
||||
}
|
||||
|
||||
func (r *RebootInstancesRequest) ToJsonString() string {
|
||||
|
@ -2851,6 +3056,88 @@ func (r *RenewInstancesResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ReservedInstances struct {
|
||||
|
||||
// 已购买的预留实例计费ID。形如:650c138f-ae7e-4750-952a-96841d6e9fc1。
|
||||
ReservedInstancesId *string `json:"ReservedInstancesId,omitempty" name:"ReservedInstancesId"`
|
||||
|
||||
// 预留实例计费的类型。形如:S3.MEDIUM4。
|
||||
// 返回项:<a href="https://cloud.tencent.com/document/product/213/11518">预留实例计费类型列表</a>
|
||||
InstanceType *string `json:"InstanceType,omitempty" name:"InstanceType"`
|
||||
|
||||
// 预留实例计费可购买的可用区。形如:ap-guangzhou-1。
|
||||
// 返回项:<a href="https://cloud.tencent.com/document/product/213/6091">可用区列表</a>
|
||||
Zone *string `json:"Zone,omitempty" name:"Zone"`
|
||||
|
||||
// 预留实例计费开始时间。形如:1949-10-01 00:00:00
|
||||
StartTime *string `json:"StartTime,omitempty" name:"StartTime"`
|
||||
|
||||
// 预留实例计费到期时间。形如:1949-10-01 00:00:00
|
||||
EndTime *string `json:"EndTime,omitempty" name:"EndTime"`
|
||||
|
||||
// 预留实例计费【有效期】即预留实例计费购买时长。形如:31536000。
|
||||
// 计量单位:秒。
|
||||
Duration *int64 `json:"Duration,omitempty" name:"Duration"`
|
||||
|
||||
// 已购买的预留实例计费个数。形如:10。
|
||||
InstanceCount *int64 `json:"InstanceCount,omitempty" name:"InstanceCount"`
|
||||
|
||||
// 描述预留实例计费的平台描述(即操作系统)。形如:linux。
|
||||
// 返回项: linux 。
|
||||
ProductDescription *string `json:"ProductDescription,omitempty" name:"ProductDescription"`
|
||||
|
||||
// 预留实例计费购买的状态。形如:active
|
||||
// 返回项: active (以创建) | pending (等待被创建) | retired (过期)。
|
||||
State *string `json:"State,omitempty" name:"State"`
|
||||
|
||||
// 可购买的预留实例计费类型的结算货币,使用ISO 4217标准货币代码。形如:USD。
|
||||
// 返回项:USD(美元)。
|
||||
CurrencyCode *string `json:"CurrencyCode,omitempty" name:"CurrencyCode"`
|
||||
|
||||
// 预留实例计费的付款类型。形如:All Upfront。
|
||||
// 返回项: All Upfront (预付全部费用)。
|
||||
OfferingType *string `json:"OfferingType,omitempty" name:"OfferingType"`
|
||||
}
|
||||
|
||||
type ReservedInstancesOffering struct {
|
||||
|
||||
// 预留实例计费可购买的可用区。形如:ap-guangzhou-1。
|
||||
// 返回项:<a href="https://cloud.tencent.com/document/product/213/6091">可用区列表</a>
|
||||
Zone *string `json:"Zone,omitempty" name:"Zone"`
|
||||
|
||||
// 可购买的预留实例计费类型的结算货币,使用ISO 4217标准货币代码。
|
||||
// 返回项:USD(美元)。
|
||||
CurrencyCode *string `json:"CurrencyCode,omitempty" name:"CurrencyCode"`
|
||||
|
||||
// 预留实例计费【有效期】即预留实例计费购买时长。形如:31536000。
|
||||
// 计量单位:秒
|
||||
Duration *int64 `json:"Duration,omitempty" name:"Duration"`
|
||||
|
||||
// 预留实例计费的购买价格。形如:4000.0。
|
||||
// 计量单位:与 currencyCode 一致,目前支持 USD(美元)
|
||||
FixedPrice *float64 `json:"FixedPrice,omitempty" name:"FixedPrice"`
|
||||
|
||||
// 预留实例计费的实例类型。形如:S3.MEDIUM4。
|
||||
// 返回项:<a href="https://cloud.tencent.com/product/cvm/instances">预留实例计费类型列表</a>
|
||||
InstanceType *string `json:"InstanceType,omitempty" name:"InstanceType"`
|
||||
|
||||
// 预留实例计费的付款类型。形如:All Upfront。
|
||||
// 返回项: All Upfront (预付全部费用)。
|
||||
OfferingType *string `json:"OfferingType,omitempty" name:"OfferingType"`
|
||||
|
||||
// 可购买的预留实例计费配置ID。形如:650c138f-ae7e-4750-952a-96841d6e9fc1。
|
||||
ReservedInstancesOfferingId *string `json:"ReservedInstancesOfferingId,omitempty" name:"ReservedInstancesOfferingId"`
|
||||
|
||||
// 预留实例计费的平台描述(即操作系统)。形如:linux。
|
||||
// 返回项: linux 。
|
||||
ProductDescription *string `json:"ProductDescription,omitempty" name:"ProductDescription"`
|
||||
|
||||
// 扣除预付费之后的使用价格 (按小时计费)。形如:0.0。
|
||||
// 目前,因为只支持 All Upfront 付款类型,所以默认为 0元/小时。
|
||||
// 计量单位:元/小时,货币单位与 currencyCode 一致,目前支持 USD(美元)
|
||||
UsagePrice *float64 `json:"UsagePrice,omitempty" name:"UsagePrice"`
|
||||
}
|
||||
|
||||
type ResetInstanceRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -2950,7 +3237,9 @@ type ResetInstancesPasswordRequest struct {
|
|||
// 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728) API返回值中的`InstanceId`获取。每次请求允许操作的实例数量上限是100。
|
||||
InstanceIds []*string `json:"InstanceIds,omitempty" name:"InstanceIds" list`
|
||||
|
||||
// 实例登录密码。不同操作系统类型密码复杂度限制不一样,具体如下:<br><li>`Linux`实例密码必须8到16位,至少包括两项`[a-z,A-Z]、[0-9]`和`[( ) ~ ~ ! @ # $ % ^ & * - + = _ | { } [ ] : ; ' < > , . ? /]`中的符号。密码不允许以`/`符号开头。<br><li>`Windows`实例密码必须12到16位,至少包括三项`[a-z],[A-Z],[0-9]`和`[( ) ~ ~ ! @ # $ % ^ & * - + = _ | { } [ ] : ; ' < > , . ? /]`中的符号。密码不允许以`/`符号开头。<br><li>如果实例即包含`Linux`实例又包含`Windows`实例,则密码复杂度限制按照`Windows`实例的限制。
|
||||
// 实例登录密码。不同操作系统类型密码复杂度限制不一样,具体如下:
|
||||
// Linux实例密码必须8-30位,推荐使用12位以上密码,不能以“/”开头,至少包含以下字符中的三种不同字符,字符种类:<br><li>小写字母:[a-z]<br><li>大写字母:[A-Z]<br><li>数字:0-9<br><li>特殊字符: ()\`~!@#$%^&\*-+=\_|{}[]:;'<>,.?/:
|
||||
// Windows实例密码必须12~30位,不能以“/”开头且不包括用户名,至少包含以下字符中的三种不同字符<br><li>小写字母:[a-z]<br><li>大写字母:[A-Z]<br><li>数字: 0-9<br><li>特殊字符:()\`~!@#$%^&\*-+=\_|{}[]:;' <>,.?/:<br><li>如果实例即包含`Linux`实例又包含`Windows`实例,则密码复杂度限制按照`Windows`实例的限制。
|
||||
Password *string `json:"Password,omitempty" name:"Password"`
|
||||
|
||||
// 待重置密码的实例操作系统用户名。不得超过64个字符。
|
||||
|
@ -3133,6 +3422,13 @@ type RunInstancesRequest struct {
|
|||
|
||||
// 提供给实例使用的用户数据,需要以 base64 方式编码,支持的最大数据大小为 16KB。关于获取此参数的详细介绍,请参阅[Windows](https://cloud.tencent.com/document/product/213/17526)和[Linux](https://cloud.tencent.com/document/product/213/17525)启动时运行命令。
|
||||
UserData *string `json:"UserData,omitempty" name:"UserData"`
|
||||
|
||||
// 是否只预检此次请求。
|
||||
// true:发送检查请求,不会创建实例。检查项包括是否填写了必需参数,请求格式,业务限制和云服务器库存。
|
||||
// 如果检查不通过,则返回对应错误码;
|
||||
// 如果检查通过,则返回RequestId.
|
||||
// false(默认):发送正常请求,通过检查后直接创建实例
|
||||
DryRun *bool `json:"DryRun,omitempty" name:"DryRun"`
|
||||
}
|
||||
|
||||
func (r *RunInstancesRequest) ToJsonString() string {
|
||||
|
@ -3422,6 +3718,43 @@ type VirtualPrivateCloud struct {
|
|||
type ZoneInfo struct {
|
||||
|
||||
// 可用区名称,例如,ap-guangzhou-3
|
||||
// 全网可用区名称如下:
|
||||
// <li> ap-chongqing-1 </li>
|
||||
// <li> ap-seoul-1 </li>
|
||||
// <li> ap-chengdu-1 </li>
|
||||
// <li> ap-chengdu-2 </li>
|
||||
// <li> ap-hongkong-1 </li>
|
||||
// <li> ap-hongkong-2 </li>
|
||||
// <li> ap-shenzhen-fsi-1 </li>
|
||||
// <li> ap-shenzhen-fsi-2 </li>
|
||||
// <li> ap-shenzhen-fsi-3 </li>
|
||||
// <li> ap-guangzhou-1(售罄)</li>
|
||||
// <li> ap-guangzhou-2(售罄)</li>
|
||||
// <li> ap-guangzhou-3 </li>
|
||||
// <li> ap-guangzhou-4 </li>
|
||||
// <li> ap-tokyo-1 </li>
|
||||
// <li> ap-singapore-1 </li>
|
||||
// <li> ap-shanghai-fsi-1 </li>
|
||||
// <li> ap-shanghai-fsi-2 </li>
|
||||
// <li> ap-shanghai-fsi-3 </li>
|
||||
// <li> ap-bangkok-1 </li>
|
||||
// <li> ap-shanghai-1(售罄) </li>
|
||||
// <li> ap-shanghai-2 </li>
|
||||
// <li> ap-shanghai-3 </li>
|
||||
// <li> ap-shanghai-4 </li>
|
||||
// <li> ap-mumbai-1 </li>
|
||||
// <li> ap-mumbai-2 </li>
|
||||
// <li> eu-moscow-1 </li>
|
||||
// <li> ap-beijing-1 </li>
|
||||
// <li> ap-beijing-2 </li>
|
||||
// <li> ap-beijing-3 </li>
|
||||
// <li> ap-beijing-4 </li>
|
||||
// <li> na-siliconvalley-1 </li>
|
||||
// <li> na-siliconvalley-2 </li>
|
||||
// <li> eu-frankfurt-1 </li>
|
||||
// <li> na-toronto-1 </li>
|
||||
// <li> na-ashburn-1 </li>
|
||||
// <li> na-ashburn-2 </li>
|
||||
Zone *string `json:"Zone,omitempty" name:"Zone"`
|
||||
|
||||
// 可用区描述,例如,广州三区
|
||||
|
|
330
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/client.go
generated
vendored
330
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/client.go
generated
vendored
|
@ -137,8 +137,8 @@ func NewAllocateAddressesResponse() (response *AllocateAddressesResponse) {
|
|||
|
||||
// 本接口 (AllocateAddresses) 用于申请一个或多个[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)。
|
||||
// * EIP 是专为动态云计算设计的静态 IP 地址。借助 EIP,您可以快速将 EIP 重新映射到您的另一个实例上,从而屏蔽实例故障。
|
||||
// * 您的 EIP 与腾讯云账户相关联,而不是与某个实例相关联。在您选择显式释放该地址,或欠费超过七天之前,它会一直与您的腾讯云账户保持关联。
|
||||
// * 平台对用户每地域能申请的 EIP 最大配额有所限制,可参见 [EIP 产品简介](https://cloud.tencent.com/document/product/213/5733),上述配额可通过 DescribeAddressQuota 接口获取。
|
||||
// * 您的 EIP 与腾讯云账户相关联,而不是与某个实例相关联。在您选择显式释放该地址,或欠费超过24小时之前,它会一直与您的腾讯云账户保持关联。
|
||||
// * 一个腾讯云账户在每个地域能申请的 EIP 最大配额有所限制,可参见 [EIP 产品简介](https://cloud.tencent.com/document/product/213/5733),上述配额可通过 DescribeAddressQuota 接口获取。
|
||||
func (c *Client) AllocateAddresses(request *AllocateAddressesRequest) (response *AllocateAddressesResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewAllocateAddressesRequest()
|
||||
|
@ -291,6 +291,31 @@ func (c *Client) AssociateAddress(request *AssociateAddressRequest) (response *A
|
|||
return
|
||||
}
|
||||
|
||||
func NewAssociateNatGatewayAddressRequest() (request *AssociateNatGatewayAddressRequest) {
|
||||
request = &AssociateNatGatewayAddressRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "AssociateNatGatewayAddress")
|
||||
return
|
||||
}
|
||||
|
||||
func NewAssociateNatGatewayAddressResponse() (response *AssociateNatGatewayAddressResponse) {
|
||||
response = &AssociateNatGatewayAddressResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(AssociateNatGatewayAddress)用于NAT网关绑定弹性IP(EIP)。
|
||||
func (c *Client) AssociateNatGatewayAddress(request *AssociateNatGatewayAddressRequest) (response *AssociateNatGatewayAddressResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewAssociateNatGatewayAddressRequest()
|
||||
}
|
||||
response = NewAssociateNatGatewayAddressResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewAttachCcnInstancesRequest() (request *AttachCcnInstancesRequest) {
|
||||
request = &AttachCcnInstancesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -658,6 +683,56 @@ func (c *Client) CreateIp6Translators(request *CreateIp6TranslatorsRequest) (res
|
|||
return
|
||||
}
|
||||
|
||||
func NewCreateNatGatewayRequest() (request *CreateNatGatewayRequest) {
|
||||
request = &CreateNatGatewayRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "CreateNatGateway")
|
||||
return
|
||||
}
|
||||
|
||||
func NewCreateNatGatewayResponse() (response *CreateNatGatewayResponse) {
|
||||
response = &CreateNatGatewayResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(CreateNatGateway)用于创建NAT网关。
|
||||
func (c *Client) CreateNatGateway(request *CreateNatGatewayRequest) (response *CreateNatGatewayResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewCreateNatGatewayRequest()
|
||||
}
|
||||
response = NewCreateNatGatewayResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewCreateNatGatewayDestinationIpPortTranslationNatRuleRequest() (request *CreateNatGatewayDestinationIpPortTranslationNatRuleRequest) {
|
||||
request = &CreateNatGatewayDestinationIpPortTranslationNatRuleRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "CreateNatGatewayDestinationIpPortTranslationNatRule")
|
||||
return
|
||||
}
|
||||
|
||||
func NewCreateNatGatewayDestinationIpPortTranslationNatRuleResponse() (response *CreateNatGatewayDestinationIpPortTranslationNatRuleResponse) {
|
||||
response = &CreateNatGatewayDestinationIpPortTranslationNatRuleResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(CreateNatGatewayDestinationIpPortTranslationNatRule)用于创建NAT网关端口转发规则。
|
||||
func (c *Client) CreateNatGatewayDestinationIpPortTranslationNatRule(request *CreateNatGatewayDestinationIpPortTranslationNatRuleRequest) (response *CreateNatGatewayDestinationIpPortTranslationNatRuleResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewCreateNatGatewayDestinationIpPortTranslationNatRuleRequest()
|
||||
}
|
||||
response = NewCreateNatGatewayDestinationIpPortTranslationNatRuleResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewCreateNetworkInterfaceRequest() (request *CreateNetworkInterfaceRequest) {
|
||||
request = &CreateNetworkInterfaceRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -1244,6 +1319,57 @@ func (c *Client) DeleteIp6Translators(request *DeleteIp6TranslatorsRequest) (res
|
|||
return
|
||||
}
|
||||
|
||||
func NewDeleteNatGatewayRequest() (request *DeleteNatGatewayRequest) {
|
||||
request = &DeleteNatGatewayRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DeleteNatGateway")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDeleteNatGatewayResponse() (response *DeleteNatGatewayResponse) {
|
||||
response = &DeleteNatGatewayResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DeleteNatGateway)用于删除NAT网关。
|
||||
// 删除 NAT 网关后,系统会自动删除路由表中包含此 NAT 网关的路由项,同时也会解绑弹性公网IP(EIP)。
|
||||
func (c *Client) DeleteNatGateway(request *DeleteNatGatewayRequest) (response *DeleteNatGatewayResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDeleteNatGatewayRequest()
|
||||
}
|
||||
response = NewDeleteNatGatewayResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDeleteNatGatewayDestinationIpPortTranslationNatRuleRequest() (request *DeleteNatGatewayDestinationIpPortTranslationNatRuleRequest) {
|
||||
request = &DeleteNatGatewayDestinationIpPortTranslationNatRuleRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DeleteNatGatewayDestinationIpPortTranslationNatRule")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDeleteNatGatewayDestinationIpPortTranslationNatRuleResponse() (response *DeleteNatGatewayDestinationIpPortTranslationNatRuleResponse) {
|
||||
response = &DeleteNatGatewayDestinationIpPortTranslationNatRuleResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DeleteNatGatewayDestinationIpPortTranslationNatRule)用于删除NAT网关端口转发规则。
|
||||
func (c *Client) DeleteNatGatewayDestinationIpPortTranslationNatRule(request *DeleteNatGatewayDestinationIpPortTranslationNatRuleRequest) (response *DeleteNatGatewayDestinationIpPortTranslationNatRuleResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDeleteNatGatewayDestinationIpPortTranslationNatRuleRequest()
|
||||
}
|
||||
response = NewDeleteNatGatewayDestinationIpPortTranslationNatRuleResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDeleteNetworkInterfaceRequest() (request *DeleteNetworkInterfaceRequest) {
|
||||
request = &DeleteNetworkInterfaceRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -2082,6 +2208,81 @@ func (c *Client) DescribeIp6Translators(request *DescribeIp6TranslatorsRequest)
|
|||
return
|
||||
}
|
||||
|
||||
func NewDescribeNatGatewayDestinationIpPortTranslationNatRulesRequest() (request *DescribeNatGatewayDestinationIpPortTranslationNatRulesRequest) {
|
||||
request = &DescribeNatGatewayDestinationIpPortTranslationNatRulesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DescribeNatGatewayDestinationIpPortTranslationNatRules")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeNatGatewayDestinationIpPortTranslationNatRulesResponse() (response *DescribeNatGatewayDestinationIpPortTranslationNatRulesResponse) {
|
||||
response = &DescribeNatGatewayDestinationIpPortTranslationNatRulesResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DescribeNatGatewayDestinationIpPortTranslationNatRules)用于查询NAT网关端口转发规则对象数组。
|
||||
func (c *Client) DescribeNatGatewayDestinationIpPortTranslationNatRules(request *DescribeNatGatewayDestinationIpPortTranslationNatRulesRequest) (response *DescribeNatGatewayDestinationIpPortTranslationNatRulesResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDescribeNatGatewayDestinationIpPortTranslationNatRulesRequest()
|
||||
}
|
||||
response = NewDescribeNatGatewayDestinationIpPortTranslationNatRulesResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeNatGatewaysRequest() (request *DescribeNatGatewaysRequest) {
|
||||
request = &DescribeNatGatewaysRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DescribeNatGateways")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeNatGatewaysResponse() (response *DescribeNatGatewaysResponse) {
|
||||
response = &DescribeNatGatewaysResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DescribeNatGateways)用于查询 NAT 网关。
|
||||
func (c *Client) DescribeNatGateways(request *DescribeNatGatewaysRequest) (response *DescribeNatGatewaysResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDescribeNatGatewaysRequest()
|
||||
}
|
||||
response = NewDescribeNatGatewaysResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeNetworkInterfaceLimitRequest() (request *DescribeNetworkInterfaceLimitRequest) {
|
||||
request = &DescribeNetworkInterfaceLimitRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DescribeNetworkInterfaceLimit")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeNetworkInterfaceLimitResponse() (response *DescribeNetworkInterfaceLimitResponse) {
|
||||
response = &DescribeNetworkInterfaceLimitResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DescribeNetworkInterfaceLimit)根据CVM实例ID查询弹性网卡配额,返回该CVM实例能绑定的弹性网卡配额,以及每个弹性网卡可以分配的ip配额
|
||||
func (c *Client) DescribeNetworkInterfaceLimit(request *DescribeNetworkInterfaceLimitRequest) (response *DescribeNetworkInterfaceLimitResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDescribeNetworkInterfaceLimitRequest()
|
||||
}
|
||||
response = NewDescribeNetworkInterfaceLimitResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeNetworkInterfacesRequest() (request *DescribeNetworkInterfacesRequest) {
|
||||
request = &DescribeNetworkInterfacesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -2307,6 +2508,31 @@ func (c *Client) DescribeSubnets(request *DescribeSubnetsRequest) (response *Des
|
|||
return
|
||||
}
|
||||
|
||||
func NewDescribeTaskResultRequest() (request *DescribeTaskResultRequest) {
|
||||
request = &DescribeTaskResultRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DescribeTaskResult")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeTaskResultResponse() (response *DescribeTaskResultResponse) {
|
||||
response = &DescribeTaskResultResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 查询EIP异步任务执行结果
|
||||
func (c *Client) DescribeTaskResult(request *DescribeTaskResultRequest) (response *DescribeTaskResultResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDescribeTaskResultRequest()
|
||||
}
|
||||
response = NewDescribeTaskResultResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDescribeVpcIpv6AddressesRequest() (request *DescribeVpcIpv6AddressesRequest) {
|
||||
request = &DescribeVpcIpv6AddressesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -2589,6 +2815,31 @@ func (c *Client) DisassociateAddress(request *DisassociateAddressRequest) (respo
|
|||
return
|
||||
}
|
||||
|
||||
func NewDisassociateNatGatewayAddressRequest() (request *DisassociateNatGatewayAddressRequest) {
|
||||
request = &DisassociateNatGatewayAddressRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "DisassociateNatGatewayAddress")
|
||||
return
|
||||
}
|
||||
|
||||
func NewDisassociateNatGatewayAddressResponse() (response *DisassociateNatGatewayAddressResponse) {
|
||||
response = &DisassociateNatGatewayAddressResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(DisassociateNatGatewayAddress)用于NAT网关解绑弹性IP。
|
||||
func (c *Client) DisassociateNatGatewayAddress(request *DisassociateNatGatewayAddressRequest) (response *DisassociateNatGatewayAddressResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewDisassociateNatGatewayAddressRequest()
|
||||
}
|
||||
response = NewDisassociateNatGatewayAddressResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDownloadCustomerGatewayConfigurationRequest() (request *DownloadCustomerGatewayConfigurationRequest) {
|
||||
request = &DownloadCustomerGatewayConfigurationRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -3171,6 +3422,56 @@ func (c *Client) ModifyIpv6AddressesAttribute(request *ModifyIpv6AddressesAttrib
|
|||
return
|
||||
}
|
||||
|
||||
func NewModifyNatGatewayAttributeRequest() (request *ModifyNatGatewayAttributeRequest) {
|
||||
request = &ModifyNatGatewayAttributeRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "ModifyNatGatewayAttribute")
|
||||
return
|
||||
}
|
||||
|
||||
func NewModifyNatGatewayAttributeResponse() (response *ModifyNatGatewayAttributeResponse) {
|
||||
response = &ModifyNatGatewayAttributeResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(ModifyNatGatewayAttribute)用于修改NAT网关的属性。
|
||||
func (c *Client) ModifyNatGatewayAttribute(request *ModifyNatGatewayAttributeRequest) (response *ModifyNatGatewayAttributeResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewModifyNatGatewayAttributeRequest()
|
||||
}
|
||||
response = NewModifyNatGatewayAttributeResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewModifyNatGatewayDestinationIpPortTranslationNatRuleRequest() (request *ModifyNatGatewayDestinationIpPortTranslationNatRuleRequest) {
|
||||
request = &ModifyNatGatewayDestinationIpPortTranslationNatRuleRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "ModifyNatGatewayDestinationIpPortTranslationNatRule")
|
||||
return
|
||||
}
|
||||
|
||||
func NewModifyNatGatewayDestinationIpPortTranslationNatRuleResponse() (response *ModifyNatGatewayDestinationIpPortTranslationNatRuleResponse) {
|
||||
response = &ModifyNatGatewayDestinationIpPortTranslationNatRuleResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(ModifyNatGatewayDestinationIpPortTranslationNatRule)用于修改NAT网关端口转发规则。
|
||||
func (c *Client) ModifyNatGatewayDestinationIpPortTranslationNatRule(request *ModifyNatGatewayDestinationIpPortTranslationNatRuleRequest) (response *ModifyNatGatewayDestinationIpPortTranslationNatRuleResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewModifyNatGatewayDestinationIpPortTranslationNatRuleRequest()
|
||||
}
|
||||
response = NewModifyNatGatewayDestinationIpPortTranslationNatRuleResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewModifyNetworkInterfaceAttributeRequest() (request *ModifyNetworkInterfaceAttributeRequest) {
|
||||
request = &ModifyNetworkInterfaceAttributeRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
@ -3710,6 +4011,31 @@ func (c *Client) ResetAttachCcnInstances(request *ResetAttachCcnInstancesRequest
|
|||
return
|
||||
}
|
||||
|
||||
func NewResetNatGatewayConnectionRequest() (request *ResetNatGatewayConnectionRequest) {
|
||||
request = &ResetNatGatewayConnectionRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
}
|
||||
request.Init().WithApiInfo("vpc", APIVersion, "ResetNatGatewayConnection")
|
||||
return
|
||||
}
|
||||
|
||||
func NewResetNatGatewayConnectionResponse() (response *ResetNatGatewayConnectionResponse) {
|
||||
response = &ResetNatGatewayConnectionResponse{
|
||||
BaseResponse: &tchttp.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 本接口(ResetNatGatewayConnection)用来NAT网关并发连接上限。
|
||||
func (c *Client) ResetNatGatewayConnection(request *ResetNatGatewayConnectionRequest) (response *ResetNatGatewayConnectionResponse, err error) {
|
||||
if request == nil {
|
||||
request = NewResetNatGatewayConnectionRequest()
|
||||
}
|
||||
response = NewResetNatGatewayConnectionResponse()
|
||||
err = c.Send(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewResetRoutesRequest() (request *ResetRoutesRequest) {
|
||||
request = &ResetRoutesRequest{
|
||||
BaseRequest: &tchttp.BaseRequest{},
|
||||
|
|
772
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/models.go
generated
vendored
772
vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/models.go
generated
vendored
|
@ -160,7 +160,7 @@ type Address struct {
|
|||
// `EIP`名称。
|
||||
AddressName *string `json:"AddressName,omitempty" name:"AddressName"`
|
||||
|
||||
// `EIP`状态。
|
||||
// `EIP`状态,包含'CREATING'(创建中),'BINDING'(绑定中),'BIND'(已绑定),'UNBINDING'(解绑中),'UNBIND'(已解绑),'OFFLINING'(释放中),'BIND_ENI'(绑定悬空弹性网卡)
|
||||
AddressStatus *string `json:"AddressStatus,omitempty" name:"AddressStatus"`
|
||||
|
||||
// 外网IP地址
|
||||
|
@ -236,8 +236,41 @@ type AddressTemplateSpecification struct {
|
|||
type AllocateAddressesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// 申请 EIP 数量,默认值为1。
|
||||
// EIP数量。默认值:1。
|
||||
AddressCount *int64 `json:"AddressCount,omitempty" name:"AddressCount"`
|
||||
|
||||
// EIP线路类型。默认值:BGP。
|
||||
// <ul style="margin:0"><li>已开通静态单线IP白名单的用户,可选值:<ul><li>CMCC:中国移动</li>
|
||||
// <li>CTCC:中国电信</li>
|
||||
// <li>CUCC:中国联通</li></ul>注意:仅部分地域支持静态单线IP。</li></ul>
|
||||
InternetServiceProvider *string `json:"InternetServiceProvider,omitempty" name:"InternetServiceProvider"`
|
||||
|
||||
// EIP计费方式。
|
||||
// <ul style="margin:0"><li>已开通带宽上移白名单的用户,可选值:<ul><li>BANDWIDTH_PACKAGE:[共享带宽包](https://cloud.tencent.com/document/product/684/15255)付费(需额外开通共享带宽包白名单)</li>
|
||||
// <li>BANDWIDTH_POSTPAID_BY_HOUR:带宽按小时后付费</li>
|
||||
// <li>TRAFFIC_POSTPAID_BY_HOUR:流量按小时后付费</li></ul>默认值:TRAFFIC_POSTPAID_BY_HOUR。</li>
|
||||
// <li>未开通带宽上移白名单的用户,EIP计费方式与其绑定的实例的计费方式一致,无需传递此参数。</li></ul>
|
||||
InternetChargeType *string `json:"InternetChargeType,omitempty" name:"InternetChargeType"`
|
||||
|
||||
// EIP出带宽上限,单位:Mbps。
|
||||
// <ul style="margin:0"><li>已开通带宽上移白名单的用户,可选值范围取决于EIP计费方式:<ul><li>BANDWIDTH_PACKAGE:1 Mbps 至 1000 Mbps</li>
|
||||
// <li>BANDWIDTH_POSTPAID_BY_HOUR:1 Mbps 至 100 Mbps</li>
|
||||
// <li>TRAFFIC_POSTPAID_BY_HOUR:1 Mbps 至 100 Mbps</li></ul>默认值:1 Mbps。</li>
|
||||
// <li>未开通带宽上移白名单的用户,EIP出带宽上限取决于与其绑定的实例的公网出带宽上限,无需传递此参数。</li></ul>
|
||||
InternetMaxBandwidthOut *int64 `json:"InternetMaxBandwidthOut,omitempty" name:"InternetMaxBandwidthOut"`
|
||||
|
||||
// EIP类型。默认值:EIP。
|
||||
// <ul style="margin:0"><li>已开通Anycast公网加速白名单的用户,可选值:<ul><li>AnycastEIP:加速IP,可参见 [Anycast 公网加速](https://cloud.tencent.com/document/product/644)</li></ul>注意:仅部分地域支持加速IP。</li></ul>
|
||||
AddressType *string `json:"AddressType,omitempty" name:"AddressType"`
|
||||
|
||||
// Anycast发布域。
|
||||
// <ul style="margin:0"><li>已开通Anycast公网加速白名单的用户,可选值:<ul><li>ANYCAST_ZONE_GLOBAL:全球发布域(需要额外开通Anycast全球加速白名单)</li><li>ANYCAST_ZONE_OVERSEAS:境外发布域</li></ul>默认值:ANYCAST_ZONE_OVERSEAS。</li></ul>
|
||||
AnycastZone *string `json:"AnycastZone,omitempty" name:"AnycastZone"`
|
||||
|
||||
// AnycastEIP是否用于绑定负载均衡。
|
||||
// <ul style="margin:0"><li>已开通Anycast公网加速白名单的用户,可选值:<ul><li>TRUE:AnycastEIP可绑定对象为负载均衡</li>
|
||||
// <li>FALSE:AnycastEIP可绑定对象为云服务器、NAT网关、高可用虚拟IP等</li></ul>默认值:FALSE。</li></ul>
|
||||
ApplicableForCLB *bool `json:"ApplicableForCLB,omitempty" name:"ApplicableForCLB"`
|
||||
}
|
||||
|
||||
func (r *AllocateAddressesRequest) ToJsonString() string {
|
||||
|
@ -256,6 +289,9 @@ type AllocateAddressesResponse struct {
|
|||
// 申请到的 EIP 的唯一 ID 列表。
|
||||
AddressSet []*string `json:"AddressSet,omitempty" name:"AddressSet" list`
|
||||
|
||||
// 异步任务TaskId。可以使用[DescribeTaskResult](https://cloud.tencent.com/document/api/215/36271)接口查询任务状态。
|
||||
TaskId *string `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
|
@ -399,7 +435,7 @@ type AssignPrivateIpAddressesRequest struct {
|
|||
// 指定的内网IP信息,单次最多指定10个。
|
||||
PrivateIpAddresses []*PrivateIpAddressSpecification `json:"PrivateIpAddresses,omitempty" name:"PrivateIpAddresses" list`
|
||||
|
||||
// 新申请的内网IP地址个数,内网IP地址个数总和不能超过配数。
|
||||
// 新申请的内网IP地址个数,内网IP地址个数总和不能超过配额数,详见<a href="/document/product/576/18527">弹性网卡使用限制</a>。
|
||||
SecondaryPrivateIpAddressCount *uint64 `json:"SecondaryPrivateIpAddressCount,omitempty" name:"SecondaryPrivateIpAddressCount"`
|
||||
}
|
||||
|
||||
|
@ -433,6 +469,22 @@ func (r *AssignPrivateIpAddressesResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type AssistantCidr struct {
|
||||
|
||||
// `VPC`实例`ID`。形如:`vpc-6v2ht8q5`
|
||||
VpcId *string `json:"VpcId,omitempty" name:"VpcId"`
|
||||
|
||||
// 辅助CIDR。形如:`172.16.0.0/16`
|
||||
CidrBlock *string `json:"CidrBlock,omitempty" name:"CidrBlock"`
|
||||
|
||||
// 辅助CIDR类型(0:普通辅助CIDR,1:容器辅助CIDR),默认都是0。
|
||||
AssistantType *int64 `json:"AssistantType,omitempty" name:"AssistantType"`
|
||||
|
||||
// 辅助CIDR拆分的子网。
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
SubnetSet []*Subnet `json:"SubnetSet,omitempty" name:"SubnetSet" list`
|
||||
}
|
||||
|
||||
type AssociateAddressRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -462,6 +514,9 @@ type AssociateAddressResponse struct {
|
|||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 异步任务TaskId。可以使用[DescribeTaskResult](https://cloud.tencent.com/document/api/215/36271)接口查询任务状态。
|
||||
TaskId *string `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
|
@ -476,6 +531,49 @@ func (r *AssociateAddressResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type AssociateNatGatewayAddressRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// 需要申请的弹性IP个数,系统会按您的要求生产N个弹性IP, 其中AddressCount和PublicAddresses至少传递一个。
|
||||
AddressCount *uint64 `json:"AddressCount,omitempty" name:"AddressCount"`
|
||||
|
||||
// 绑定NAT网关的弹性IP数组,其中AddressCount和PublicAddresses至少传递一个。。
|
||||
PublicIpAddresses []*string `json:"PublicIpAddresses,omitempty" name:"PublicIpAddresses" list`
|
||||
|
||||
// 弹性IP可以区,自动分配弹性IP时传递。
|
||||
Zone *string `json:"Zone,omitempty" name:"Zone"`
|
||||
}
|
||||
|
||||
func (r *AssociateNatGatewayAddressRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *AssociateNatGatewayAddressRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type AssociateNatGatewayAddressResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *AssociateNatGatewayAddressResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *AssociateNatGatewayAddressResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type AttachCcnInstancesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -910,6 +1008,12 @@ type CreateCcnRequest struct {
|
|||
|
||||
// CCN服务质量,'PT':白金,'AU':金,'AG':银,默认为‘AU’。
|
||||
QosLevel *string `json:"QosLevel,omitempty" name:"QosLevel"`
|
||||
|
||||
// 计费模式,PREPAID:表示预付费,即包年包月,POSTPAID:表示后付费,即按量计费。默认:POSTPAID。
|
||||
InstanceChargeType *string `json:"InstanceChargeType,omitempty" name:"InstanceChargeType"`
|
||||
|
||||
// 限速类型,OUTER_REGION_LIMIT表示地域出口限速,INTER_REGION_LIMIT为地域间限速,默认为OUTER_REGION_LIMIT
|
||||
BandwidthLimitType *string `json:"BandwidthLimitType,omitempty" name:"BandwidthLimitType"`
|
||||
}
|
||||
|
||||
func (r *CreateCcnRequest) ToJsonString() string {
|
||||
|
@ -1254,6 +1358,101 @@ func (r *CreateIp6TranslatorsResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type CreateNatGatewayDestinationIpPortTranslationNatRuleRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// NAT网关的端口转换规则。
|
||||
DestinationIpPortTranslationNatRules []*DestinationIpPortTranslationNatRule `json:"DestinationIpPortTranslationNatRules,omitempty" name:"DestinationIpPortTranslationNatRules" list`
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayDestinationIpPortTranslationNatRuleRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayDestinationIpPortTranslationNatRuleRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type CreateNatGatewayDestinationIpPortTranslationNatRuleResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayDestinationIpPortTranslationNatRuleResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayDestinationIpPortTranslationNatRuleResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type CreateNatGatewayRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关名称
|
||||
NatGatewayName *string `json:"NatGatewayName,omitempty" name:"NatGatewayName"`
|
||||
|
||||
// VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。
|
||||
VpcId *string `json:"VpcId,omitempty" name:"VpcId"`
|
||||
|
||||
// NAT网关最大外网出带宽(单位:Mbps),支持的参数值:`20, 50, 100, 200, 500, 1000, 2000, 5000`,默认: `100Mbps`。
|
||||
InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut,omitempty" name:"InternetMaxBandwidthOut"`
|
||||
|
||||
// NAT网关并发连接上限,支持参数值:`1000000、3000000、10000000`,默认值为`100000`。
|
||||
MaxConcurrentConnection *uint64 `json:"MaxConcurrentConnection,omitempty" name:"MaxConcurrentConnection"`
|
||||
|
||||
// 需要申请的弹性IP个数,系统会按您的要求生产N个弹性IP,其中AddressCount和PublicAddresses至少传递一个。
|
||||
AddressCount *uint64 `json:"AddressCount,omitempty" name:"AddressCount"`
|
||||
|
||||
// 绑定NAT网关的弹性IP数组,其中AddressCount和PublicAddresses至少传递一个。
|
||||
PublicIpAddresses []*string `json:"PublicIpAddresses,omitempty" name:"PublicIpAddresses" list`
|
||||
|
||||
// 可用区,形如:`ap-guangzhou-1`。
|
||||
Zone *string `json:"Zone,omitempty" name:"Zone"`
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type CreateNatGatewayResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// NAT网关对象数组。
|
||||
NatGatewaySet []*NatGateway `json:"NatGatewaySet,omitempty" name:"NatGatewaySet" list`
|
||||
|
||||
// 符合条件的 NAT网关对象数量。
|
||||
TotalCount *uint64 `json:"TotalCount,omitempty" name:"TotalCount"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *CreateNatGatewayResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type CreateNetworkInterfaceRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -1644,7 +1843,7 @@ type CreateVpcRequest struct {
|
|||
// vpc名称,最大长度不能超过60个字节。
|
||||
VpcName *string `json:"VpcName,omitempty" name:"VpcName"`
|
||||
|
||||
// vpc的cidr,只能为10.0.0.0/16,172.16.0.0/12,192.168.0.0/16这三个内网网段内。
|
||||
// vpc的cidr,只能为10.0.0.0/16,172.16.0.0/16,192.168.0.0/16这三个内网网段内。
|
||||
CidrBlock *string `json:"CidrBlock,omitempty" name:"CidrBlock"`
|
||||
|
||||
// 是否开启组播。true: 开启, false: 不开启。
|
||||
|
@ -2179,6 +2378,77 @@ func (r *DeleteIp6TranslatorsResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DeleteNatGatewayDestinationIpPortTranslationNatRuleRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// NAT网关的端口转换规则。
|
||||
DestinationIpPortTranslationNatRules []*DestinationIpPortTranslationNatRule `json:"DestinationIpPortTranslationNatRules,omitempty" name:"DestinationIpPortTranslationNatRules" list`
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayDestinationIpPortTranslationNatRuleRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayDestinationIpPortTranslationNatRuleRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DeleteNatGatewayDestinationIpPortTranslationNatRuleResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayDestinationIpPortTranslationNatRuleResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayDestinationIpPortTranslationNatRuleResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DeleteNatGatewayRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DeleteNatGatewayResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DeleteNatGatewayResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DeleteNetworkInterfaceRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -2736,7 +3006,7 @@ type DescribeAddressesRequest struct {
|
|||
// <li> address-id - String - 是否必填:否 - (过滤条件)按照 EIP 的唯一 ID 过滤。EIP 唯一 ID 形如:eip-11112222。</li>
|
||||
// <li> address-name - String - 是否必填:否 - (过滤条件)按照 EIP 名称过滤。不支持模糊过滤。</li>
|
||||
// <li> address-ip - String - 是否必填:否 - (过滤条件)按照 EIP 的 IP 地址过滤。</li>
|
||||
// <li> address-status - String - 是否必填:否 - (过滤条件)按照 EIP 的状态过滤。取值范围:[详见EIP状态列表](https://cloud.tencent.com/document/api/213/9452#eip_state)。</li>
|
||||
// <li> address-status - String - 是否必填:否 - (过滤条件)按照 EIP 的状态过滤。状态包含:'CREATING','BINDING','BIND','UNBINDING','UNBIND','OFFLINING','BIND_ENI'。</li>
|
||||
// <li> instance-id - String - 是否必填:否 - (过滤条件)按照 EIP 绑定的实例 ID 过滤。实例 ID 形如:ins-11112222。</li>
|
||||
// <li> private-ip-address - String - 是否必填:否 - (过滤条件)按照 EIP 绑定的内网 IP 过滤。</li>
|
||||
// <li> network-interface-id - String - 是否必填:否 - (过滤条件)按照 EIP 绑定的弹性网卡 ID 过滤。弹性网卡 ID 形如:eni-11112222。</li>
|
||||
|
@ -3037,6 +3307,8 @@ type DescribeCcnsRequest struct {
|
|||
// <li>ccn-name - String - (过滤条件)CCN名称。</li>
|
||||
// <li>ccn-description - String - (过滤条件)CCN描述。</li>
|
||||
// <li>state - String - (过滤条件)实例状态, 'ISOLATED': 隔离中(欠费停服),'AVAILABLE':运行中。</li>
|
||||
// <li>tag-key - String -是否必填:否- (过滤条件)按照标签键进行过滤。</li>
|
||||
// <li>tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例:查询绑定了标签的CCN列表。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量
|
||||
|
@ -3648,6 +3920,155 @@ func (r *DescribeIp6TranslatorsResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNatGatewayDestinationIpPortTranslationNatRulesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关ID。
|
||||
NatGatewayIds []*string `json:"NatGatewayIds,omitempty" name:"NatGatewayIds" list`
|
||||
|
||||
// 过滤条件:
|
||||
// 参数不支持同时指定NatGatewayIds和Filters。
|
||||
// <li> nat-gateway-id,NAT网关的ID,如`nat-0yi4hekt`</li>
|
||||
// <li> vpc-id,私有网络VPC的ID,如`vpc-0yi4hekt`</li>
|
||||
// <li> public-ip-address, 弹性IP,如`139.199.232.238`。</li>
|
||||
// <li>public-port, 公网端口。</li>
|
||||
// <li>private-ip-address, 内网IP,如`10.0.0.1`。</li>
|
||||
// <li>private-port, 内网端口。</li>
|
||||
// <li>description,规则描述。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量,默认为0。
|
||||
Offset *uint64 `json:"Offset,omitempty" name:"Offset"`
|
||||
|
||||
// 返回数量,默认为20,最大值为100。
|
||||
Limit *uint64 `json:"Limit,omitempty" name:"Limit"`
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewayDestinationIpPortTranslationNatRulesRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewayDestinationIpPortTranslationNatRulesRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNatGatewayDestinationIpPortTranslationNatRulesResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// NAT网关端口转发规则对象数组。
|
||||
NatGatewayDestinationIpPortTranslationNatRuleSet []*NatGatewayDestinationIpPortTranslationNatRule `json:"NatGatewayDestinationIpPortTranslationNatRuleSet,omitempty" name:"NatGatewayDestinationIpPortTranslationNatRuleSet" list`
|
||||
|
||||
// 符合条件的NAT网关端口转发规则对象数目。
|
||||
TotalCount *uint64 `json:"TotalCount,omitempty" name:"TotalCount"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewayDestinationIpPortTranslationNatRulesResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewayDestinationIpPortTranslationNatRulesResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNatGatewaysRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关统一 ID,形如:`nat-123xx454`。
|
||||
NatGatewayIds []*string `json:"NatGatewayIds,omitempty" name:"NatGatewayIds" list`
|
||||
|
||||
// 过滤条件,参数不支持同时指定NatGatewayIds和Filters。
|
||||
// <li>nat-gateway-id - String - (过滤条件)协议端口模板实例ID,形如:`nat-123xx454`。</li>
|
||||
// <li>vpc-id - String - (过滤条件)私有网络 唯一ID,形如:`vpc-123xx454`。</li>
|
||||
// <li>nat-gateway-name - String - (过滤条件)协议端口模板实例ID,形如:`test_nat`。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量,默认为0。
|
||||
Offset *uint64 `json:"Offset,omitempty" name:"Offset"`
|
||||
|
||||
// 返回数量,默认为20,最大值为100。
|
||||
Limit *uint64 `json:"Limit,omitempty" name:"Limit"`
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewaysRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewaysRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNatGatewaysResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// NAT网关对象数组。
|
||||
NatGatewaySet []*NatGateway `json:"NatGatewaySet,omitempty" name:"NatGatewaySet" list`
|
||||
|
||||
// 符合条件的NAT网关对象个数。
|
||||
TotalCount *uint64 `json:"TotalCount,omitempty" name:"TotalCount"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewaysResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeNatGatewaysResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNetworkInterfaceLimitRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// 要查询的CVM实例ID
|
||||
InstanceId *string `json:"InstanceId,omitempty" name:"InstanceId"`
|
||||
}
|
||||
|
||||
func (r *DescribeNetworkInterfaceLimitRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeNetworkInterfaceLimitRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNetworkInterfaceLimitResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 弹性网卡配额
|
||||
EniQuantity *int64 `json:"EniQuantity,omitempty" name:"EniQuantity"`
|
||||
|
||||
// 每个弹性网卡可以分配的ip配额
|
||||
EniPrivateIpAddressQuantity *int64 `json:"EniPrivateIpAddressQuantity,omitempty" name:"EniPrivateIpAddressQuantity"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DescribeNetworkInterfaceLimitResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeNetworkInterfaceLimitResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeNetworkInterfacesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -3662,6 +4083,9 @@ type DescribeNetworkInterfacesRequest struct {
|
|||
// <li>groups.security-group-id - String - (过滤条件)绑定的安全组实例ID,例如:sg-f9ekbxeq。</li>
|
||||
// <li>network-interface-name - String - (过滤条件)网卡实例名称。</li>
|
||||
// <li>network-interface-description - String - (过滤条件)网卡实例描述。</li>
|
||||
// <li>address-ip - String - (过滤条件)内网IPv4地址。</li>
|
||||
// <li>tag-key - String -是否必填:否- (过滤条件)按照标签键进行过滤。使用请参考示例2</li>
|
||||
// <li>tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例3。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量,默认为0。
|
||||
|
@ -3755,6 +4179,8 @@ type DescribeRouteTablesRequest struct {
|
|||
// <li>route-table-name - String - (过滤条件)路由表名称。</li>
|
||||
// <li>vpc-id - String - (过滤条件)VPC实例ID,形如:vpc-f49l6u0z。</li>
|
||||
// <li>association.main - String - (过滤条件)是否主路由表。</li>
|
||||
// <li>tag-key - String -是否必填:否- (过滤条件)按照标签键进行过滤。</li>
|
||||
// <li>tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例2。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量。
|
||||
|
@ -3878,8 +4304,11 @@ type DescribeSecurityGroupsRequest struct {
|
|||
SecurityGroupIds []*string `json:"SecurityGroupIds,omitempty" name:"SecurityGroupIds" list`
|
||||
|
||||
// 过滤条件,参数不支持同时指定SecurityGroupIds和Filters。
|
||||
// <li>security-group-id - String - (过滤条件)安全组ID。</li>
|
||||
// <li>project-id - Integer - (过滤条件)项目id。</li>
|
||||
// <li>security-group-name - String - (过滤条件)安全组名称。</li>
|
||||
// <li>tag-key - String -是否必填:否- (过滤条件)按照标签键进行过滤。使用请参考示例2。</li>
|
||||
// <li>tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例3。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量。
|
||||
|
@ -4032,6 +4461,8 @@ type DescribeSubnetsRequest struct {
|
|||
// <li>is-remote-vpc-snat - Boolean - (过滤条件)是否为VPC SNAT地址池子网。</li>
|
||||
// <li>subnet-name - String - (过滤条件)子网名称。</li>
|
||||
// <li>zone - String - (过滤条件)可用区。</li>
|
||||
// <li>tag-key - String -是否必填:否- (过滤条件)按照标签键进行过滤。</li>
|
||||
// <li>tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例2。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量
|
||||
|
@ -4074,6 +4505,49 @@ func (r *DescribeSubnetsResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeTaskResultRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// 异步任务ID
|
||||
TaskId *uint64 `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 计费订单号
|
||||
DealName *string `json:"DealName,omitempty" name:"DealName"`
|
||||
}
|
||||
|
||||
func (r *DescribeTaskResultRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeTaskResultRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeTaskResultResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 任务ID
|
||||
TaskId *uint64 `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 执行结果,包括"SUCCESS", "FAILED", "RUNNING"
|
||||
Result *string `json:"Result,omitempty" name:"Result"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DescribeTaskResultResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DescribeTaskResultResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DescribeVpcIpv6AddressesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -4174,6 +4648,8 @@ type DescribeVpcsRequest struct {
|
|||
// <li>is-default - String - (过滤条件)是否默认VPC。</li>
|
||||
// <li>vpc-id - String - (过滤条件)VPC实例ID形如:vpc-f49l6u0z。</li>
|
||||
// <li>cidr-block - String - (过滤条件)vpc的cidr。</li>
|
||||
// <li>tag-key - String -是否必填:否- (过滤条件)按照标签键进行过滤。</li>
|
||||
// <li>tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例2。</li>
|
||||
Filters []*Filter `json:"Filters,omitempty" name:"Filters" list`
|
||||
|
||||
// 偏移量
|
||||
|
@ -4326,6 +4802,27 @@ func (r *DescribeVpnGatewaysResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DestinationIpPortTranslationNatRule struct {
|
||||
|
||||
// 网络协议,可选值:`TCP`、`UDP`。
|
||||
IpProtocol *string `json:"IpProtocol,omitempty" name:"IpProtocol"`
|
||||
|
||||
// 弹性IP。
|
||||
PublicIpAddress *string `json:"PublicIpAddress,omitempty" name:"PublicIpAddress"`
|
||||
|
||||
// 公网端口。
|
||||
PublicPort *uint64 `json:"PublicPort,omitempty" name:"PublicPort"`
|
||||
|
||||
// 内网地址。
|
||||
PrivateIpAddress *string `json:"PrivateIpAddress,omitempty" name:"PrivateIpAddress"`
|
||||
|
||||
// 内网端口。
|
||||
PrivatePort *uint64 `json:"PrivatePort,omitempty" name:"PrivatePort"`
|
||||
|
||||
// NAT网关转发规则描述。
|
||||
Description *string `json:"Description,omitempty" name:"Description"`
|
||||
}
|
||||
|
||||
type DetachCcnInstancesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -4480,6 +4977,9 @@ type DirectConnectGateway struct {
|
|||
|
||||
// 是否启用BGP。
|
||||
EnableBGP *bool `json:"EnableBGP,omitempty" name:"EnableBGP"`
|
||||
|
||||
// 开启和关闭BGP的community属性。
|
||||
EnableBGPCommunity *bool `json:"EnableBGPCommunity,omitempty" name:"EnableBGPCommunity"`
|
||||
}
|
||||
|
||||
type DirectConnectGatewayCcnRoute struct {
|
||||
|
@ -4591,6 +5091,9 @@ type DisassociateAddressResponse struct {
|
|||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 异步任务TaskId。可以使用[DescribeTaskResult](https://cloud.tencent.com/document/api/215/36271)接口查询任务状态。
|
||||
TaskId *string `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
|
@ -4605,6 +5108,43 @@ func (r *DisassociateAddressResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DisassociateNatGatewayAddressRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// 绑定NAT网关的弹性IP数组。
|
||||
PublicIpAddresses []*string `json:"PublicIpAddresses,omitempty" name:"PublicIpAddresses" list`
|
||||
}
|
||||
|
||||
func (r *DisassociateNatGatewayAddressRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DisassociateNatGatewayAddressRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DisassociateNatGatewayAddressResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *DisassociateNatGatewayAddressResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *DisassociateNatGatewayAddressResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type DownloadCustomerGatewayConfigurationRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -5307,6 +5847,9 @@ type ModifyAddressAttributeRequest struct {
|
|||
|
||||
// 修改后的 EIP 名称。长度上限为20个字符。
|
||||
AddressName *string `json:"AddressName,omitempty" name:"AddressName"`
|
||||
|
||||
// 设定EIP是否直通,"TRUE"表示直通,"FALSE"表示非直通。注意该参数仅对EIP直通功能可见的用户可以设定。
|
||||
EipDirectConnection *string `json:"EipDirectConnection,omitempty" name:"EipDirectConnection"`
|
||||
}
|
||||
|
||||
func (r *ModifyAddressAttributeRequest) ToJsonString() string {
|
||||
|
@ -5445,6 +5988,9 @@ type ModifyAddressesBandwidthResponse struct {
|
|||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 异步任务TaskId。可以使用[DescribeTaskResult](https://cloud.tencent.com/document/api/215/36271)接口查询任务状态。
|
||||
TaskId *string `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
|
@ -5813,6 +6359,86 @@ func (r *ModifyIpv6AddressesAttributeResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ModifyNatGatewayAttributeRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// NAT网关的名称,形如:`test_nat`。
|
||||
NatGatewayName *string `json:"NatGatewayName,omitempty" name:"NatGatewayName"`
|
||||
|
||||
// NAT网关最大外网出带宽(单位:Mbps)。
|
||||
InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut,omitempty" name:"InternetMaxBandwidthOut"`
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayAttributeRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayAttributeRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ModifyNatGatewayAttributeResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayAttributeResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayAttributeResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ModifyNatGatewayDestinationIpPortTranslationNatRuleRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关的ID,形如:`nat-df45454`。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// 源NAT网关的端口转换规则。
|
||||
SourceNatRule *DestinationIpPortTranslationNatRule `json:"SourceNatRule,omitempty" name:"SourceNatRule"`
|
||||
|
||||
// 目的NAT网关的端口转换规则。
|
||||
DestinationNatRule *DestinationIpPortTranslationNatRule `json:"DestinationNatRule,omitempty" name:"DestinationNatRule"`
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayDestinationIpPortTranslationNatRuleRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayDestinationIpPortTranslationNatRuleRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ModifyNatGatewayDestinationIpPortTranslationNatRuleResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayDestinationIpPortTranslationNatRuleResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *ModifyNatGatewayDestinationIpPortTranslationNatRuleResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ModifyNetworkInterfaceAttributeRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -6262,6 +6888,89 @@ func (r *ModifyVpnGatewayAttributeResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type NatGateway struct {
|
||||
|
||||
// NAT网关的ID。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// NAT网关的名称。
|
||||
NatGatewayName *string `json:"NatGatewayName,omitempty" name:"NatGatewayName"`
|
||||
|
||||
// NAT网关创建的时间。
|
||||
CreatedTime *string `json:"CreatedTime,omitempty" name:"CreatedTime"`
|
||||
|
||||
// NAT网关的状态。
|
||||
// 'PENDING':生产中,'DELETING':删除中,'AVAILABLE':运行中,'UPDATING':升级中,
|
||||
// ‘FAILED’:失败。
|
||||
State *string `json:"State,omitempty" name:"State"`
|
||||
|
||||
// 网关最大外网出带宽(单位:Mbps)。
|
||||
InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut,omitempty" name:"InternetMaxBandwidthOut"`
|
||||
|
||||
// 网关并发连接上限。
|
||||
MaxConcurrentConnection *uint64 `json:"MaxConcurrentConnection,omitempty" name:"MaxConcurrentConnection"`
|
||||
|
||||
// 绑定NAT网关的公网IP对象数组。
|
||||
PublicIpAddressSet []*NatGatewayAddress `json:"PublicIpAddressSet,omitempty" name:"PublicIpAddressSet" list`
|
||||
|
||||
// NAT网关网络状态。“AVAILABLE”:运行中, “UNAVAILABLE”:不可用, “INSUFFICIENT”:欠费停服。
|
||||
NetworkState *string `json:"NetworkState,omitempty" name:"NetworkState"`
|
||||
|
||||
// NAT网关的端口转发规则。
|
||||
DestinationIpPortTranslationNatRuleSet []*DestinationIpPortTranslationNatRule `json:"DestinationIpPortTranslationNatRuleSet,omitempty" name:"DestinationIpPortTranslationNatRuleSet" list`
|
||||
|
||||
// VPC实例ID。
|
||||
VpcId *string `json:"VpcId,omitempty" name:"VpcId"`
|
||||
|
||||
// NAT网关所在的可用区。
|
||||
Zone *string `json:"Zone,omitempty" name:"Zone"`
|
||||
}
|
||||
|
||||
type NatGatewayAddress struct {
|
||||
|
||||
// 弹性公网IP(EIP)的唯一 ID,形如:`eip-11112222`。
|
||||
AddressId *string `json:"AddressId,omitempty" name:"AddressId"`
|
||||
|
||||
// 外网IP地址,形如:`123.121.34.33`。
|
||||
PublicIpAddress *string `json:"PublicIpAddress,omitempty" name:"PublicIpAddress"`
|
||||
|
||||
// 资源封堵状态。true表示弹性ip处于封堵状态,false表示弹性ip处于未封堵状态。
|
||||
IsBlocked *bool `json:"IsBlocked,omitempty" name:"IsBlocked"`
|
||||
}
|
||||
|
||||
type NatGatewayDestinationIpPortTranslationNatRule struct {
|
||||
|
||||
// 网络协议,可选值:`TCP`、`UDP`。
|
||||
IpProtocol *string `json:"IpProtocol,omitempty" name:"IpProtocol"`
|
||||
|
||||
// 弹性IP。
|
||||
PublicIpAddress *string `json:"PublicIpAddress,omitempty" name:"PublicIpAddress"`
|
||||
|
||||
// 公网端口。
|
||||
PublicPort *uint64 `json:"PublicPort,omitempty" name:"PublicPort"`
|
||||
|
||||
// 内网地址。
|
||||
PrivateIpAddress *string `json:"PrivateIpAddress,omitempty" name:"PrivateIpAddress"`
|
||||
|
||||
// 内网端口。
|
||||
PrivatePort *uint64 `json:"PrivatePort,omitempty" name:"PrivatePort"`
|
||||
|
||||
// NAT网关转发规则描述。
|
||||
Description *string `json:"Description,omitempty" name:"Description"`
|
||||
|
||||
// NAT网关的ID。
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// 私有网络VPC的ID。
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
VpcId *string `json:"VpcId,omitempty" name:"VpcId"`
|
||||
|
||||
// NAT网关转发规则创建时间。
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
CreatedTime *string `json:"CreatedTime,omitempty" name:"CreatedTime"`
|
||||
}
|
||||
|
||||
type NetworkInterface struct {
|
||||
|
||||
// 弹性网卡实例ID,例如:eni-f1xjkw1b。
|
||||
|
@ -6311,6 +7020,9 @@ type NetworkInterface struct {
|
|||
|
||||
// `IPv6`地址列表。
|
||||
Ipv6AddressSet []*Ipv6Address `json:"Ipv6AddressSet,omitempty" name:"Ipv6AddressSet" list`
|
||||
|
||||
// 标签键值对。
|
||||
TagSet []*Tag `json:"TagSet,omitempty" name:"TagSet" list`
|
||||
}
|
||||
|
||||
type NetworkInterfaceAttachment struct {
|
||||
|
@ -6434,6 +7146,9 @@ type ReleaseAddressesResponse struct {
|
|||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 异步任务TaskId。可以使用[DescribeTaskResult](https://cloud.tencent.com/document/api/215/36271)接口查询任务状态。
|
||||
TaskId *string `json:"TaskId,omitempty" name:"TaskId"`
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
|
@ -6750,6 +7465,43 @@ func (r *ResetAttachCcnInstancesResponse) FromJsonString(s string) error {
|
|||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ResetNatGatewayConnectionRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
// NAT网关ID。
|
||||
NatGatewayId *string `json:"NatGatewayId,omitempty" name:"NatGatewayId"`
|
||||
|
||||
// NAT网关并发连接上限,形如:1000000、3000000、10000000。
|
||||
MaxConcurrentConnection *uint64 `json:"MaxConcurrentConnection,omitempty" name:"MaxConcurrentConnection"`
|
||||
}
|
||||
|
||||
func (r *ResetNatGatewayConnectionRequest) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *ResetNatGatewayConnectionRequest) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ResetNatGatewayConnectionResponse struct {
|
||||
*tchttp.BaseResponse
|
||||
Response *struct {
|
||||
|
||||
// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
|
||||
RequestId *string `json:"RequestId,omitempty" name:"RequestId"`
|
||||
} `json:"Response"`
|
||||
}
|
||||
|
||||
func (r *ResetNatGatewayConnectionResponse) ToJsonString() string {
|
||||
b, _ := json.Marshal(r)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (r *ResetNatGatewayConnectionResponse) FromJsonString(s string) error {
|
||||
return json.Unmarshal([]byte(s), &r)
|
||||
}
|
||||
|
||||
type ResetRoutesRequest struct {
|
||||
*tchttp.BaseRequest
|
||||
|
||||
|
@ -7021,6 +7773,9 @@ type SecurityGroupPolicy struct {
|
|||
// 网段或IP(互斥)。
|
||||
CidrBlock *string `json:"CidrBlock,omitempty" name:"CidrBlock"`
|
||||
|
||||
// 网段或IPv6(互斥)。
|
||||
Ipv6CidrBlock *string `json:"Ipv6CidrBlock,omitempty" name:"Ipv6CidrBlock"`
|
||||
|
||||
// 安全组实例ID,例如:sg-ohuuioma。
|
||||
SecurityGroupId *string `json:"SecurityGroupId,omitempty" name:"SecurityGroupId"`
|
||||
|
||||
|
@ -7032,6 +7787,9 @@ type SecurityGroupPolicy struct {
|
|||
|
||||
// 安全组规则描述。
|
||||
PolicyDescription *string `json:"PolicyDescription,omitempty" name:"PolicyDescription"`
|
||||
|
||||
// 安全组最近修改时间。
|
||||
ModifyTime *string `json:"ModifyTime,omitempty" name:"ModifyTime"`
|
||||
}
|
||||
|
||||
type SecurityGroupPolicySet struct {
|
||||
|
@ -7418,6 +8176,10 @@ type Vpc struct {
|
|||
|
||||
// 标签键值对
|
||||
TagSet []*Tag `json:"TagSet,omitempty" name:"TagSet" list`
|
||||
|
||||
// 辅助CIDR
|
||||
// 注意:此字段可能返回 null,表示取不到有效值。
|
||||
AssistantCidrSet []*AssistantCidr `json:"AssistantCidrSet,omitempty" name:"AssistantCidrSet" list`
|
||||
}
|
||||
|
||||
type VpcIpv6Address struct {
|
||||
|
|
|
@ -484,7 +484,7 @@ github.com/stretchr/testify/assert
|
|||
github.com/stretchr/testify/require
|
||||
# github.com/temoto/robotstxt v1.1.1
|
||||
github.com/temoto/robotstxt
|
||||
# github.com/tencentcloud/tencentcloud-sdk-go v3.0.71+incompatible
|
||||
# github.com/tencentcloud/tencentcloud-sdk-go v3.0.94+incompatible
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http
|
||||
|
|
|
@ -18,8 +18,7 @@ customized images based on an existing base images.
|
|||
|
||||
The following configuration options are available for building Tencentcloud images.
|
||||
In addition to the options listed here,
|
||||
a [communicator](/docs/templates/communicator.html) can be configured for this
|
||||
builder.
|
||||
a [communicator](/docs/templates/communicator.html) can be configured for this builder.
|
||||
|
||||
### Required:
|
||||
|
||||
|
@ -31,15 +30,15 @@ builder.
|
|||
|
||||
- `region` (string) - The region where your cvm will be launch. You should
|
||||
reference [Region and Zone](https://intl.cloud.tencent.com/document/product/213/6091)
|
||||
for parameter taking.
|
||||
for parameter taking.
|
||||
|
||||
- `zone` (string) - The zone where your cvm will be launch. You should
|
||||
reference [Region and Zone](https://intl.cloud.tencent.com/document/product/213/6091)
|
||||
for parameter taking.
|
||||
for parameter taking.
|
||||
|
||||
- `instance_type` (string) - The instance type your cvm will be launched by.
|
||||
You should reference [Instace Type](https://intl.cloud.tencent.com/document/product/213/11518)
|
||||
for parameter taking.
|
||||
for parameter taking.
|
||||
|
||||
- `source_image_id` (string) - The base image id of Image you want to create
|
||||
your customized image from.
|
||||
|
@ -50,25 +49,20 @@ builder.
|
|||
|
||||
### Optional:
|
||||
|
||||
- `force_poweroff` (boolean) - Whether to force power off cvm when create image.
|
||||
Default value is `false`.
|
||||
- `force_poweroff` (boolean) - Indicates whether to perform a forced shutdown to
|
||||
create an image when soft shutdown fails. Default value is `false`.
|
||||
|
||||
Your cvm will try to shutdown normally; if shutdown failed and `force_poweroff`
|
||||
set, your cvm will be powered off, otherwise task will fail.
|
||||
- `image_description` (string) - Image description. It should no more than 60 characters.
|
||||
|
||||
- `image_description` (string) - Image description.
|
||||
|
||||
- `reboot` (boolean) - Whether shutdown cvm to create Image. Default value is
|
||||
`false`.
|
||||
|
||||
If `reboot` is not set and cvm is running, create image task will fail.
|
||||
- `reboot` (boolean, **deprecated**) - Whether shutdown cvm to create Image.
|
||||
Please refer to parameter `force_poweroff`.
|
||||
|
||||
- `sysprep` (boolean) - Whether enable Sysprep during creating windows image.
|
||||
|
||||
- `image_copy_regions` (array of strings) - regions that will be copied to after
|
||||
- `image_copy_regions` (array of strings) - Regions that will be copied to after
|
||||
your image created.
|
||||
|
||||
- `image_share_accounts` (array of strings) - accounts that will be shared to
|
||||
- `image_share_accounts` (array of strings) - Accounts that will be shared to
|
||||
after your image created.
|
||||
|
||||
- `skip_region_validation` (boolean) - Do not check region and zone when validate.
|
||||
|
@ -78,6 +72,9 @@ builder.
|
|||
|
||||
If not set, you could access your cvm from the same vpc.
|
||||
|
||||
- `internet_max_bandwidth_out` (number) - Max bandwidth out your cvm will be launched by(in MB).
|
||||
values can be set between 1 ~ 100.
|
||||
|
||||
- `instance_name` (string) - Instance name.
|
||||
|
||||
- `disk_type` (string) - Root disk type your cvm will be launched by. you could
|
||||
|
@ -103,7 +100,7 @@ builder.
|
|||
- `vpc_name` (string) - Specify vpc name you will create. if `vpc_id` is not set, packer will
|
||||
create a vpc for you named this parameter.
|
||||
|
||||
- `cidr_block` (boolean) - Specify cider block of the vpc you will create if `vpc_id` not set
|
||||
- `cidr_block` (boolean) - Specify cider block of the vpc you will create if `vpc_id` is not set.
|
||||
|
||||
- `subnet_id` (string) - Specify subnet your cvm will be launched by.
|
||||
|
||||
|
@ -111,14 +108,11 @@ builder.
|
|||
create a subnet for you named this parameter.
|
||||
|
||||
- `subnect_cidr_block` (boolean) - Specify cider block of the subnet you will create if
|
||||
`subnet_id` not set
|
||||
|
||||
- `internet_max_bandwidth_out` (number) - Max bandwidth out your cvm will be launched by(in MB).
|
||||
values can be set between 1 ~ 100.
|
||||
`subnet_id` is not set.
|
||||
|
||||
- `security_group_id` (string) - Specify security group your cvm will be launched by.
|
||||
|
||||
- `security_group_name` (string) - Specify security name you will create if `security_group_id` not set.
|
||||
- `security_group_name` (string) - Specify security name you will create if `security_group_id` is not set.
|
||||
|
||||
- `user_data` (string) - userdata.
|
||||
|
||||
|
@ -139,29 +133,34 @@ Here is a basic example for Tencentcloud.
|
|||
"secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}",
|
||||
"secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}"
|
||||
},
|
||||
"builders": [{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-3",
|
||||
"instance_type": "S3.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"ssh_username" : "root",
|
||||
"image_name": "packerTest2",
|
||||
"packer_debug": true,
|
||||
"associate_public_ip_address": true,
|
||||
"run_tags": {
|
||||
"good": "luck"
|
||||
"builders": [
|
||||
{
|
||||
"type": "tencentcloud-cvm",
|
||||
"secret_id": "{{user `secret_id`}}",
|
||||
"secret_key": "{{user `secret_key`}}",
|
||||
"region": "ap-guangzhou",
|
||||
"zone": "ap-guangzhou-4",
|
||||
"instance_type": "S4.SMALL1",
|
||||
"source_image_id": "img-oikl1tzv",
|
||||
"ssh_username": "root",
|
||||
"image_name": "PackerTest",
|
||||
"disk_type": "CLOUD_PREMIUM",
|
||||
"packer_debug": true,
|
||||
"associate_public_ip_address": true,
|
||||
"run_tags": {
|
||||
"good": "luck"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"provisioners": [{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sleep 30",
|
||||
"yum install redis.x86_64 -y"
|
||||
]
|
||||
}]
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"sleep 30",
|
||||
"yum install redis.x86_64 -y"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
- `internet_max_bandwidth_out` (int64) - Max bandwidth out your cvm will be launched by(in MB).
|
||||
values can be set between 1 ~ 100.
|
||||
|
||||
- `security_group_id` (string) - Specify security group your cvm will be launched by.
|
||||
- `security_group_id` (string) - Specify securitygroup your cvm will be launched by.
|
||||
|
||||
- `security_group_name` (string) - Specify security name you will create if security_group_id not set.
|
||||
|
||||
|
|
Loading…
Reference in New Issue