Merge pull request #8261 from shawnmssu/feature/ucloud_import

Packer Post-Processor support UCloud import
This commit is contained in:
Megan Marsh 2019-10-30 13:11:55 -07:00 committed by GitHub
commit ca64cc1237
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
114 changed files with 5262 additions and 504 deletions

View File

@ -1,12 +1,14 @@
package uhost
package common
import (
"fmt"
"net/url"
"os"
"github.com/hashicorp/packer/template/interpolate"
"github.com/hashicorp/packer/version"
"github.com/ucloud/ucloud-sdk-go/services/uaccount"
"github.com/ucloud/ucloud-sdk-go/services/ufile"
"github.com/ucloud/ucloud-sdk-go/services/uhost"
"github.com/ucloud/ucloud-sdk-go/services/unet"
"github.com/ucloud/ucloud-sdk-go/services/vpc"
@ -36,16 +38,19 @@ func (c *AccessConfig) Client() (*UCloudClient, error) {
cfg.BaseUrl = c.BaseUrl
}
cfg.UserAgent = fmt.Sprintf("Packer-UCloud/%s", version.FormattedVersion())
// set default max retry count
cfg.MaxRetries = 3
cred := auth.NewCredential()
cred.PublicKey = c.PublicKey
cred.PrivateKey = c.PrivateKey
c.client = &UCloudClient{}
c.client.uhostconn = uhost.NewClient(&cfg, &cred)
c.client.unetconn = unet.NewClient(&cfg, &cred)
c.client.vpcconn = vpc.NewClient(&cfg, &cred)
c.client.uaccountconn = uaccount.NewClient(&cfg, &cred)
c.client.UHostConn = uhost.NewClient(&cfg, &cred)
c.client.UNetConn = unet.NewClient(&cfg, &cred)
c.client.VPCConn = vpc.NewClient(&cfg, &cred)
c.client.UAccountConn = uaccount.NewClient(&cfg, &cred)
c.client.UFileConn = ufile.NewClient(&cfg, &cred)
return c.client, nil
}
@ -64,6 +69,12 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
errs = append(errs, fmt.Errorf("%q must be set", "region"))
}
if c.BaseUrl != "" {
if _, err := url.Parse(c.BaseUrl); err != nil {
errs = append(errs, fmt.Errorf("%q is invalid, should be an valid ucloud base_url, got %q, parse error: %s", "base_url", c.BaseUrl, err))
}
}
if len(errs) > 0 {
return errs
}
@ -137,7 +148,7 @@ func (c *AccessConfig) ValidateZone(region, zone string) error {
func (c *AccessConfig) getSupportedProjectIds() ([]string, error) {
client, err := c.Client()
conn := client.uaccountconn
conn := client.UAccountConn
if err != nil {
return nil, err
}
@ -150,7 +161,7 @@ func (c *AccessConfig) getSupportedProjectIds() ([]string, error) {
validProjectIds := make([]string, len(resp.ProjectSet))
for _, val := range resp.ProjectSet {
if !isStringIn(val.ProjectId, validProjectIds) {
if !IsStringIn(val.ProjectId, validProjectIds) {
validProjectIds = append(validProjectIds, val.ProjectId)
}
}
@ -160,7 +171,7 @@ func (c *AccessConfig) getSupportedProjectIds() ([]string, error) {
func (c *AccessConfig) getSupportedRegions() ([]string, error) {
client, err := c.Client()
conn := client.uaccountconn
conn := client.UAccountConn
if err != nil {
return nil, err
}
@ -173,7 +184,7 @@ func (c *AccessConfig) getSupportedRegions() ([]string, error) {
validRegions := make([]string, len(resp.Regions))
for _, val := range resp.Regions {
if !isStringIn(val.Region, validRegions) {
if !IsStringIn(val.Region, validRegions) {
validRegions = append(validRegions, val.Region)
}
}
@ -183,7 +194,7 @@ func (c *AccessConfig) getSupportedRegions() ([]string, error) {
func (c *AccessConfig) getSupportedZones(region string) ([]string, error) {
client, err := c.Client()
conn := client.uaccountconn
conn := client.UAccountConn
if err != nil {
return nil, err
}
@ -196,7 +207,7 @@ func (c *AccessConfig) getSupportedZones(region string) ([]string, error) {
validZones := make([]string, len(resp.Regions))
for _, val := range resp.Regions {
if val.Region == region && !isStringIn(val.Zone, validZones) {
if val.Region == region && !IsStringIn(val.Zone, validZones) {
validZones = append(validZones, val.Zone)
}

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"os"

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"fmt"
@ -10,7 +10,7 @@ import (
)
type Artifact struct {
UCloudImages *imageInfoSet
UCloudImages *ImageInfoSet
BuilderIdValue string
@ -56,7 +56,7 @@ func (a *Artifact) State(name string) interface{} {
}
func (a *Artifact) Destroy() error {
conn := a.Client.uhostconn
conn := a.Client.UHostConn
errors := make([]error, 0)
for _, v := range a.UCloudImages.GetAll() {

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"github.com/hashicorp/packer/packer"
@ -13,14 +13,14 @@ func TestArtifact_Impl(t *testing.T) {
func TestArtifactId(t *testing.T) {
expected := `project1:region1:foo,project2:region2:bar`
images := newImageInfoSet(nil)
images.Set(imageInfo{
images := NewImageInfoSet(nil)
images.Set(ImageInfo{
Region: "region1",
ProjectId: "project1",
ImageId: "foo",
})
images.Set(imageInfo{
images.Set(ImageInfo{
Region: "region2",
ProjectId: "project2",
ImageId: "bar",
@ -37,14 +37,14 @@ func TestArtifactId(t *testing.T) {
}
func TestArtifactState_atlasMetadata(t *testing.T) {
images := newImageInfoSet(nil)
images.Set(imageInfo{
images := NewImageInfoSet(nil)
images.Set(ImageInfo{
Region: "region1",
ProjectId: "project1",
ImageId: "foo",
})
images.Set(imageInfo{
images.Set(ImageInfo{
Region: "region2",
ProjectId: "project2",
ImageId: "bar",

View File

@ -1,7 +1,8 @@
package uhost
package common
import (
"github.com/ucloud/ucloud-sdk-go/services/uaccount"
"github.com/ucloud/ucloud-sdk-go/services/ufile"
"github.com/ucloud/ucloud-sdk-go/services/uhost"
"github.com/ucloud/ucloud-sdk-go/services/unet"
"github.com/ucloud/ucloud-sdk-go/services/vpc"
@ -10,17 +11,18 @@ import (
)
type UCloudClient struct {
uhostconn *uhost.UHostClient
unetconn *unet.UNetClient
vpcconn *vpc.VPCClient
uaccountconn *uaccount.UAccountClient
UHostConn *uhost.UHostClient
UNetConn *unet.UNetClient
VPCConn *vpc.VPCClient
UAccountConn *uaccount.UAccountClient
UFileConn *ufile.UFileClient
}
func (c *UCloudClient) describeFirewallById(sgId string) (*unet.FirewallDataSet, error) {
func (c *UCloudClient) DescribeFirewallById(sgId string) (*unet.FirewallDataSet, error) {
if sgId == "" {
return nil, newNotFoundError("security group", sgId)
return nil, NewNotFoundError("security group", sgId)
}
conn := c.unetconn
conn := c.UNetConn
req := conn.NewDescribeFirewallRequest()
req.FWId = ucloud.String(sgId)
@ -29,23 +31,23 @@ func (c *UCloudClient) describeFirewallById(sgId string) (*unet.FirewallDataSet,
if err != nil {
if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 54002 {
return nil, newNotFoundError("security group", sgId)
return nil, NewNotFoundError("security group", sgId)
}
return nil, err
}
if len(resp.DataSet) < 1 {
return nil, newNotFoundError("security group", sgId)
return nil, NewNotFoundError("security group", sgId)
}
return &resp.DataSet[0], nil
}
func (c *UCloudClient) describeSubnetById(subnetId string) (*vpc.VPCSubnetInfoSet, error) {
func (c *UCloudClient) DescribeSubnetById(subnetId string) (*vpc.VPCSubnetInfoSet, error) {
if subnetId == "" {
return nil, newNotFoundError("Subnet", subnetId)
return nil, NewNotFoundError("Subnet", subnetId)
}
conn := c.vpcconn
conn := c.VPCConn
req := conn.NewDescribeSubnetRequest()
req.SubnetIds = []string{subnetId}
@ -56,17 +58,17 @@ func (c *UCloudClient) describeSubnetById(subnetId string) (*vpc.VPCSubnetInfoSe
}
if resp == nil || len(resp.DataSet) < 1 {
return nil, newNotFoundError("Subnet", subnetId)
return nil, NewNotFoundError("Subnet", subnetId)
}
return &resp.DataSet[0], nil
}
func (c *UCloudClient) describeVPCById(vpcId string) (*vpc.VPCInfo, error) {
func (c *UCloudClient) DescribeVPCById(vpcId string) (*vpc.VPCInfo, error) {
if vpcId == "" {
return nil, newNotFoundError("VPC", vpcId)
return nil, NewNotFoundError("VPC", vpcId)
}
conn := c.vpcconn
conn := c.VPCConn
req := conn.NewDescribeVPCRequest()
req.VPCIds = []string{vpcId}
@ -77,7 +79,7 @@ func (c *UCloudClient) describeVPCById(vpcId string) (*vpc.VPCInfo, error) {
}
if resp == nil || len(resp.DataSet) < 1 {
return nil, newNotFoundError("VPC", vpcId)
return nil, NewNotFoundError("VPC", vpcId)
}
return &resp.DataSet[0], nil
@ -85,31 +87,31 @@ func (c *UCloudClient) describeVPCById(vpcId string) (*vpc.VPCInfo, error) {
func (c *UCloudClient) DescribeImageById(imageId string) (*uhost.UHostImageSet, error) {
if imageId == "" {
return nil, newNotFoundError("image", imageId)
return nil, NewNotFoundError("image", imageId)
}
req := c.uhostconn.NewDescribeImageRequest()
req := c.UHostConn.NewDescribeImageRequest()
req.ImageId = ucloud.String(imageId)
resp, err := c.uhostconn.DescribeImage(req)
resp, err := c.UHostConn.DescribeImage(req)
if err != nil {
return nil, err
}
if len(resp.ImageSet) < 1 {
return nil, newNotFoundError("image", imageId)
return nil, NewNotFoundError("image", imageId)
}
return &resp.ImageSet[0], nil
}
func (c *UCloudClient) describeUHostById(uhostId string) (*uhost.UHostInstanceSet, error) {
func (c *UCloudClient) DescribeUHostById(uhostId string) (*uhost.UHostInstanceSet, error) {
if uhostId == "" {
return nil, newNotFoundError("instance", uhostId)
return nil, NewNotFoundError("instance", uhostId)
}
req := c.uhostconn.NewDescribeUHostInstanceRequest()
req := c.UHostConn.NewDescribeUHostInstanceRequest()
req.UHostIds = []string{uhostId}
resp, err := c.uhostconn.DescribeUHostInstance(req)
resp, err := c.UHostConn.DescribeUHostInstance(req)
if err != nil {
return nil, err
}
@ -120,19 +122,19 @@ func (c *UCloudClient) describeUHostById(uhostId string) (*uhost.UHostInstanceSe
return &resp.UHostSet[0], nil
}
func (c *UCloudClient) describeImageByInfo(projectId, regionId, imageId string) (*uhost.UHostImageSet, error) {
req := c.uhostconn.NewDescribeImageRequest()
func (c *UCloudClient) DescribeImageByInfo(projectId, regionId, imageId string) (*uhost.UHostImageSet, error) {
req := c.UHostConn.NewDescribeImageRequest()
req.ProjectId = ucloud.String(projectId)
req.ImageId = ucloud.String(imageId)
req.Region = ucloud.String(regionId)
resp, err := c.uhostconn.DescribeImage(req)
resp, err := c.UHostConn.DescribeImage(req)
if err != nil {
return nil, err
}
if len(resp.ImageSet) < 1 {
return nil, newNotFoundError("image", imageId)
return nil, NewNotFoundError("image", imageId)
}
return &resp.ImageSet[0], nil

View File

@ -0,0 +1,31 @@
package common
const (
// DefaultPasswordStr, DefaultPasswordNum and DefaultPasswordSpe are used to general default value of root password of UHost instance
DefaultPasswordNum = "012346789"
DefaultPasswordStr = "abcdefghijklmnopqrstuvwxyz"
DefaultPasswordSpe = "-_"
)
const (
InstanceStateRunning = "Running"
InstanceStateStopped = "Stopped"
ImageStateAvailable = "Available"
ImageStateUnavailable = "Unavailable"
BootDiskStateNormal = "Normal"
OsTypeWindows = "Windows"
SecurityGroupNonWeb = "recommend non web"
IpTypePrivate = "Private"
)
const (
DefaultCreateImageTimeout = 3600
)
var BootDiskTypeMap = NewStringConverter(map[string]string{
"cloud_ssd": "CLOUD_SSD",
"local_normal": "LOCAL_NORMAL",
"local_ssd": "LOCAL_SSD",
})

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"fmt"
@ -12,7 +12,7 @@ type ExpectedStateError struct {
message string
}
type NotCompleteError struct {
type NotCompletedError struct {
message string
}
@ -24,38 +24,38 @@ func (e *NotFoundError) Error() string {
return e.message
}
func (e *NotCompleteError) Error() string {
func (e *NotCompletedError) Error() string {
return e.message
}
func newNotFoundError(product, id string) error {
func NewNotFoundError(product, id string) error {
return &NotFoundError{fmt.Sprintf("the %s %s is not found", product, id)}
}
func newExpectedStateError(product, id string) error {
func NewExpectedStateError(product, id string) error {
return &ExpectedStateError{fmt.Sprintf("the %s %s not be expected state", product, id)}
}
func newNotCompleteError(product string) error {
return &NotCompleteError{fmt.Sprintf("%s is not completed", product)}
func NewNotCompletedError(product string) error {
return &NotCompletedError{fmt.Sprintf("%s is not completed", product)}
}
func isNotFoundError(err error) bool {
func IsNotFoundError(err error) bool {
if _, ok := err.(*NotFoundError); ok {
return true
}
return false
}
func isExpectedStateError(err error) bool {
func IsExpectedStateError(err error) bool {
if _, ok := err.(*ExpectedStateError); ok {
return true
}
return false
}
func isNotCompleteError(err error) bool {
if _, ok := err.(*NotCompleteError); ok {
func IsNotCompleteError(err error) bool {
if _, ok := err.(*NotCompletedError); ok {
return true
}
return false

View File

@ -1,6 +1,6 @@
//go:generate mapstructure-to-hcl2 -type ImageDestination
package uhost
package common
import (
"fmt"
@ -17,19 +17,20 @@ type ImageDestination struct {
}
type ImageConfig struct {
ImageName string `mapstructure:"image_name"`
ImageDescription string `mapstructure:"image_description"`
ImageDestinations []ImageDestination `mapstructure:"image_copy_to_mappings"`
ImageName string `mapstructure:"image_name"`
ImageDescription string `mapstructure:"image_description"`
ImageDestinations []ImageDestination `mapstructure:"image_copy_to_mappings"`
WaitImageReadyTimeout int `mapstructure:"wait_image_ready_timeout"`
}
var imageNamePattern = regexp.MustCompile(`^[A-Za-z0-9\p{Han}-_\[\]:,.]{1,63}$`)
var ImageNamePattern = regexp.MustCompile(`^[A-Za-z0-9\p{Han}-_\[\]:,.]{1,63}$`)
func (c *ImageConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
imageName := c.ImageName
if imageName == "" {
errs = append(errs, fmt.Errorf("%q must be set", "image_name"))
} else if !imageNamePattern.MatchString(imageName) {
} else if !ImageNamePattern.MatchString(imageName) {
errs = append(errs, fmt.Errorf("expected %q to be 1-63 characters and only support chinese, english, numbers, '-_,.:[]', got %q", "image_name", imageName))
}
@ -43,6 +44,10 @@ func (c *ImageConfig) Prepare(ctx *interpolate.Context) []error {
}
}
if c.WaitImageReadyTimeout <= 0 {
c.WaitImageReadyTimeout = DefaultCreateImageTimeout
}
if len(errs) > 0 {
return errs
}
@ -61,7 +66,7 @@ func (imageDestination *ImageDestination) validate() []error {
errs = append(errs, fmt.Errorf("%q must be set", "image_copy_project"))
}
if imageDestination.Name != "" && !imageNamePattern.MatchString(imageDestination.Name) {
if imageDestination.Name != "" && !ImageNamePattern.MatchString(imageDestination.Name) {
errs = append(errs, fmt.Errorf("expected %q to be 1-63 characters and only support chinese, english, numbers, '-_,.:[]', got %q", "image_copy_name", imageDestination.Name))
}

View File

@ -1,5 +1,5 @@
// Code generated by "mapstructure-to-hcl2 -type ImageDestination"; DO NOT EDIT.
package uhost
package common
import (
"github.com/hashicorp/hcl/v2/hcldec"

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"testing"

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"fmt"
@ -39,7 +39,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
if c.InstanceType == "" {
errs = append(errs, fmt.Errorf("%q must be set", "instance_type"))
} else if _, err := parseInstanceType(c.InstanceType); err != nil {
} else if _, err := ParseInstanceType(c.InstanceType); err != nil {
errs = append(errs, err)
}
@ -49,7 +49,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
if c.BootDiskType == "" {
c.BootDiskType = "cloud_ssd"
} else if err := checkStringIn(c.BootDiskType,
} else if err := CheckStringIn(c.BootDiskType,
[]string{"local_normal", "local_ssd", "cloud_ssd"}); err != nil {
errs = append(errs, err)
}

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"testing"

View File

@ -0,0 +1,31 @@
package common
type stringConverter struct {
c map[string]string
r map[string]string
}
func NewStringConverter(input map[string]string) stringConverter {
reversed := make(map[string]string)
for k, v := range input {
reversed[v] = k
}
return stringConverter{
c: input,
r: reversed,
}
}
func (c stringConverter) Convert(src string) string {
if dst, ok := c.c[src]; ok {
return dst
}
return src
}
func (c stringConverter) UnConvert(dst string) string {
if src, ok := c.r[dst]; ok {
return src
}
return dst
}

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"fmt"
@ -7,14 +7,14 @@ import (
"sync"
)
type instanceType struct {
type InstanceType struct {
CPU int
Memory int
HostType string
HostScaleType string
}
func parseInstanceType(s string) (*instanceType, error) {
func ParseInstanceType(s string) (*InstanceType, error) {
split := strings.Split(s, "-")
if len(split) < 3 {
return nil, fmt.Errorf("instance type is invalid, got %q", s)
@ -26,7 +26,7 @@ func parseInstanceType(s string) (*instanceType, error) {
return parseInstanceTypeByNormal(split...)
}
func (i *instanceType) String() string {
func (i *InstanceType) String() string {
if i.Iscustomized() {
return fmt.Sprintf("%s-%s-%v-%v", i.HostType, i.HostScaleType, i.CPU, i.Memory)
} else {
@ -34,7 +34,7 @@ func (i *instanceType) String() string {
}
}
func (i *instanceType) Iscustomized() bool {
func (i *InstanceType) Iscustomized() bool {
return i.HostScaleType == "customized"
}
@ -47,13 +47,13 @@ var instanceTypeScaleMap = map[string]int{
var availableHostTypes = []string{"n"}
func parseInstanceTypeByCustomize(splited ...string) (*instanceType, error) {
func parseInstanceTypeByCustomize(splited ...string) (*InstanceType, error) {
if len(splited) != 4 {
return nil, fmt.Errorf("instance type is invalid, expected like n-customize-1-2")
}
hostType := splited[0]
err := checkStringIn(hostType, availableHostTypes)
err := CheckStringIn(hostType, availableHostTypes)
if err != nil {
return nil, err
}
@ -95,7 +95,7 @@ func parseInstanceTypeByCustomize(splited ...string) (*instanceType, error) {
return nil, fmt.Errorf("expected the number of memory must be divisible by 2 without a remainder (except single memory), got %d", memory)
}
t := &instanceType{}
t := &InstanceType{}
t.HostType = hostType
t.HostScaleType = hostScaleType
t.CPU = cpu
@ -105,13 +105,13 @@ func parseInstanceTypeByCustomize(splited ...string) (*instanceType, error) {
var availableOutstandingCpu = []int{4, 8, 16, 32, 64}
func parseInstanceTypeByNormal(split ...string) (*instanceType, error) {
func parseInstanceTypeByNormal(split ...string) (*InstanceType, error) {
if len(split) != 3 {
return nil, fmt.Errorf("instance type is invalid, expected like n-standard-1")
}
hostType := split[0]
err := checkStringIn(hostType, []string{"n", "o"})
err := CheckStringIn(hostType, []string{"n", "o"})
if err != nil {
return nil, err
}
@ -131,7 +131,7 @@ func parseInstanceTypeByNormal(split ...string) (*instanceType, error) {
}
if hostType == "o" {
if err := checkIntIn(cpu, availableOutstandingCpu); err != nil {
if err := CheckIntIn(cpu, availableOutstandingCpu); err != nil {
return nil, fmt.Errorf("expected cpu of outstanding instancetype %q", err)
}
@ -150,7 +150,7 @@ func parseInstanceTypeByNormal(split ...string) (*instanceType, error) {
memory := cpu * scale
t := &instanceType{}
t := &InstanceType{}
t.HostType = hostType
t.HostScaleType = hostScaleType
t.CPU = cpu
@ -159,46 +159,46 @@ func parseInstanceTypeByNormal(split ...string) (*instanceType, error) {
}
}
type imageInfo struct {
type ImageInfo struct {
ImageId string
ProjectId string
Region string
}
func (i *imageInfo) Id() string {
func (i *ImageInfo) Id() string {
return fmt.Sprintf("%s:%s", i.ProjectId, i.Region)
}
type imageInfoSet struct {
m map[string]imageInfo
type ImageInfoSet struct {
m map[string]ImageInfo
once sync.Once
}
func newImageInfoSet(vL []imageInfo) *imageInfoSet {
s := imageInfoSet{}
func NewImageInfoSet(vL []ImageInfo) *ImageInfoSet {
s := ImageInfoSet{}
for _, v := range vL {
s.Set(v)
}
return &s
}
func (i *imageInfoSet) init() {
i.m = make(map[string]imageInfo)
func (i *ImageInfoSet) init() {
i.m = make(map[string]ImageInfo)
}
func (i *imageInfoSet) Set(img imageInfo) {
func (i *ImageInfoSet) Set(img ImageInfo) {
i.once.Do(i.init)
i.m[img.Id()] = img
}
func (i *imageInfoSet) Remove(id string) {
func (i *ImageInfoSet) Remove(id string) {
i.once.Do(i.init)
delete(i.m, id)
}
func (i *imageInfoSet) Get(projectId, region string) *imageInfo {
func (i *ImageInfoSet) Get(projectId, region string) *ImageInfo {
k := fmt.Sprintf("%s:%s", projectId, region)
if v, ok := i.m[k]; ok {
return &v
@ -206,8 +206,8 @@ func (i *imageInfoSet) Get(projectId, region string) *imageInfo {
return nil
}
func (i *imageInfoSet) GetAll() []imageInfo {
var vL []imageInfo
func (i *ImageInfoSet) GetAll() []ImageInfo {
var vL []ImageInfo
for _, img := range i.m {
vL = append(vL, img)
}

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"testing"
@ -12,14 +12,14 @@ func Test_parseInstanceType(t *testing.T) {
tests := []struct {
name string
args args
want *instanceType
want *InstanceType
wantErr bool
}{
{"ok_highcpu", args{"n-highcpu-1"}, &instanceType{1, 1024, "n", "highcpu"}, false},
{"ok_basic", args{"n-basic-1"}, &instanceType{1, 2048, "n", "basic"}, false},
{"ok_standard", args{"n-standard-1"}, &instanceType{1, 4096, "n", "standard"}, false},
{"ok_highmem", args{"n-highmem-1"}, &instanceType{1, 8192, "n", "highmem"}, false},
{"ok_customized", args{"n-customized-1-12"}, &instanceType{1, 12288, "n", "customized"}, false},
{"ok_highcpu", args{"n-highcpu-1"}, &InstanceType{1, 1024, "n", "highcpu"}, false},
{"ok_basic", args{"n-basic-1"}, &InstanceType{1, 2048, "n", "basic"}, false},
{"ok_standard", args{"n-standard-1"}, &InstanceType{1, 4096, "n", "standard"}, false},
{"ok_highmem", args{"n-highmem-1"}, &InstanceType{1, 8192, "n", "highmem"}, false},
{"ok_customized", args{"n-customized-1-12"}, &InstanceType{1, 12288, "n", "customized"}, false},
{"err_customized", args{"n-customized-1-5"}, nil, true},
{"err_type", args{"nx-highcpu-1"}, nil, true},
@ -33,9 +33,9 @@ func Test_parseInstanceType(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseInstanceType(tt.args.s)
got, err := ParseInstanceType(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("parseInstanceType() arg %s got %#v error = %v, wantErr %v", tt.args.s, got, err, tt.wantErr)
t.Errorf("ParseInstanceType() arg %s got %#v error = %v, wantErr %v", tt.args.s, got, err, tt.wantErr)
return
}
@ -47,7 +47,7 @@ func Test_parseInstanceType(t *testing.T) {
!(tt.want.Memory == got.Memory) ||
!(tt.want.HostType == got.HostType) ||
!(tt.want.HostScaleType == got.HostScaleType) {
t.Errorf("parseInstanceType() = %v, want %v", got, tt.want)
t.Errorf("ParseInstanceType() = %v, want %v", got, tt.want)
}
})
}

View File

@ -1,4 +1,4 @@
package uhost
package common
import (
"fmt"
@ -8,7 +8,7 @@ import (
"strings"
)
func checkStringIn(val string, available []string) error {
func CheckStringIn(val string, available []string) error {
for _, choice := range available {
if val == choice {
return nil
@ -18,7 +18,7 @@ func checkStringIn(val string, available []string) error {
return fmt.Errorf("should be one of %q, got %q", strings.Join(available, ","), val)
}
func checkIntIn(val int, available []int) error {
func CheckIntIn(val int, available []int) error {
for _, choice := range available {
if val == choice {
return nil
@ -28,7 +28,7 @@ func checkIntIn(val int, available []int) error {
return fmt.Errorf("should be one of %v, got %d", available, val)
}
func isStringIn(val string, available []string) bool {
func IsStringIn(val string, available []string) bool {
for _, choice := range available {
if val == choice {
return true
@ -46,7 +46,7 @@ func SSHHost(usePrivateIp bool) func(multistep.StateBag) (string, error) {
var privateIp, publicIp string
for _, v := range instance.IPSet {
if v.Type == ipTypePrivate {
if v.Type == IpTypePrivate {
privateIp = v.IP
} else {
publicIp = v.IP
@ -61,7 +61,7 @@ func SSHHost(usePrivateIp bool) func(multistep.StateBag) (string, error) {
}
}
func halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
func Halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
if prefix != "" {

View File

@ -7,6 +7,7 @@ package uhost
import (
"context"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
@ -19,10 +20,10 @@ import (
const BuilderId = "ucloud.uhost"
type Config struct {
common.PackerConfig `mapstructure:",squash"`
AccessConfig `mapstructure:",squash"`
ImageConfig `mapstructure:",squash"`
RunConfig `mapstructure:",squash"`
common.PackerConfig `mapstructure:",squash"`
ucloudcommon.AccessConfig `mapstructure:",squash"`
ucloudcommon.ImageConfig `mapstructure:",squash"`
ucloudcommon.RunConfig `mapstructure:",squash"`
ctx interpolate.Context
}
@ -111,7 +112,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
Host: SSHHost(
Host: ucloudcommon.SSHHost(
b.config.UseSSHPrivateIp),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
@ -119,9 +120,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&stepStopInstance{},
&stepCreateImage{},
&stepCopyUCloudImage{
ImageDestinations: b.config.ImageDestinations,
RegionId: b.config.Region,
ProjectId: b.config.ProjectId,
ImageDestinations: b.config.ImageDestinations,
RegionId: b.config.Region,
ProjectId: b.config.ProjectId,
WaitImageReadyTimeout: b.config.WaitImageReadyTimeout,
},
}
@ -140,8 +142,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
// Build the artifact and return it
artifact := &Artifact{
UCloudImages: state.Get("ucloud_images").(*imageInfoSet),
artifact := &ucloudcommon.Artifact{
UCloudImages: state.Get("ucloud_images").(*ucloudcommon.ImageInfoSet),
BuilderIdValue: BuilderId,
Client: client,
}

View File

@ -3,76 +3,78 @@ package uhost
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder/ucloud/common"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
PublicKey *string `mapstructure:"public_key" cty:"public_key"`
PrivateKey *string `mapstructure:"private_key" cty:"private_key"`
Region *string `mapstructure:"region" cty:"region"`
ProjectId *string `mapstructure:"project_id" cty:"project_id"`
BaseUrl *string `mapstructure:"base_url" cty:"base_url"`
ImageName *string `mapstructure:"image_name" cty:"image_name"`
ImageDescription *string `mapstructure:"image_description" cty:"image_description"`
ImageDestinations []FlatImageDestination `mapstructure:"image_copy_to_mappings" cty:"image_copy_to_mappings"`
Zone *string `mapstructure:"availability_zone" cty:"availability_zone"`
SourceImageId *string `mapstructure:"source_image_id" cty:"source_image_id"`
InstanceType *string `mapstructure:"instance_type" cty:"instance_type"`
InstanceName *string `mapstructure:"instance_name" cty:"instance_name"`
BootDiskType *string `mapstructure:"boot_disk_type" cty:"boot_disk_type"`
VPCId *string `mapstructure:"vpc_id" cty:"vpc_id"`
SubnetId *string `mapstructure:"subnet_id" cty:"subnet_id"`
SecurityGroupId *string `mapstructure:"security_group_id" cty:"security_group_id"`
Type *string `mapstructure:"communicator" cty:"communicator"`
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
SSHPublicKey []byte `cty:"ssh_public_key"`
SSHPrivateKey []byte `cty:"ssh_private_key"`
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
UseSSHPrivateIp *bool `mapstructure:"use_ssh_private_ip" cty:"use_ssh_private_ip"`
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
PublicKey *string `mapstructure:"public_key" cty:"public_key"`
PrivateKey *string `mapstructure:"private_key" cty:"private_key"`
Region *string `mapstructure:"region" cty:"region"`
ProjectId *string `mapstructure:"project_id" cty:"project_id"`
BaseUrl *string `mapstructure:"base_url" cty:"base_url"`
ImageName *string `mapstructure:"image_name" cty:"image_name"`
ImageDescription *string `mapstructure:"image_description" cty:"image_description"`
ImageDestinations []common.FlatImageDestination `mapstructure:"image_copy_to_mappings" cty:"image_copy_to_mappings"`
WaitImageReadyTimeout *int `mapstructure:"wait_image_ready_timeout" cty:"wait_image_ready_timeout"`
Zone *string `mapstructure:"availability_zone" cty:"availability_zone"`
SourceImageId *string `mapstructure:"source_image_id" cty:"source_image_id"`
InstanceType *string `mapstructure:"instance_type" cty:"instance_type"`
InstanceName *string `mapstructure:"instance_name" cty:"instance_name"`
BootDiskType *string `mapstructure:"boot_disk_type" cty:"boot_disk_type"`
VPCId *string `mapstructure:"vpc_id" cty:"vpc_id"`
SubnetId *string `mapstructure:"subnet_id" cty:"subnet_id"`
SecurityGroupId *string `mapstructure:"security_group_id" cty:"security_group_id"`
Type *string `mapstructure:"communicator" cty:"communicator"`
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
SSHPublicKey []byte `cty:"ssh_public_key"`
SSHPrivateKey []byte `cty:"ssh_private_key"`
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
UseSSHPrivateIp *bool `mapstructure:"use_ssh_private_ip" cty:"use_ssh_private_ip"`
}
// FlatMapstructure returns a new FlatConfig.
@ -98,7 +100,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"base_url": &hcldec.AttrSpec{Name: "base_url", Type: cty.String, Required: false},
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
"image_copy_to_mappings": &hcldec.BlockListSpec{TypeName: "image_copy_to_mappings", Nested: &hcldec.BlockSpec{TypeName: "image_copy_to_mappings", Nested: hcldec.ObjectSpec((*FlatImageDestination)(nil).HCL2Spec())}},
"image_copy_to_mappings": &hcldec.BlockListSpec{TypeName: "image_copy_to_mappings", Nested: &hcldec.BlockSpec{TypeName: "image_copy_to_mappings", Nested: hcldec.ObjectSpec((*common.FlatImageDestination)(nil).HCL2Spec())}},
"wait_image_ready_timeout": &hcldec.AttrSpec{Name: "wait_image_ready_timeout", Type: cty.Number, Required: false},
"availability_zone": &hcldec.AttrSpec{Name: "availability_zone", Type: cty.String, Required: false},
"source_image_id": &hcldec.AttrSpec{Name: "source_image_id", Type: cty.String, Required: false},
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},

View File

@ -2,6 +2,7 @@ package uhost
import (
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/packer"
"github.com/stretchr/testify/assert"
"os"
@ -20,7 +21,7 @@ func TestBuilderAcc_validateRegion(t *testing.T) {
testAccPreCheck(t)
access := &AccessConfig{Region: "cn-bj2"}
access := &ucloudcommon.AccessConfig{Region: "cn-bj2"}
err := access.Config()
if err != nil {
t.Fatalf("Error on initing UCloud AccessConfig, %s", err)
@ -94,8 +95,8 @@ func TestBuilderAcc_regionCopy(t *testing.T) {
Template: testBuilderAccRegionCopy(projectId),
Check: checkRegionCopy(
projectId,
[]ImageDestination{
{projectId, "cn-sh2", "packer-test-regionCopy-sh", "test"},
[]ucloudcommon.ImageDestination{
{ProjectId: projectId, Region: "cn-sh2", Name: "packer-test-regionCopy-sh", Description: "test"},
}),
})
}
@ -121,21 +122,21 @@ func testBuilderAccRegionCopy(projectId string) string {
}`, projectId)
}
func checkRegionCopy(projectId string, imageDst []ImageDestination) builderT.TestCheckFunc {
func checkRegionCopy(projectId string, imageDst []ucloudcommon.ImageDestination) builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
artifactSet := artifacts[0]
artifact, ok := artifactSet.(*Artifact)
artifact, ok := artifactSet.(*ucloudcommon.Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactSet)
}
destSet := newImageInfoSet(nil)
destSet := ucloudcommon.NewImageInfoSet(nil)
for _, dest := range imageDst {
destSet.Set(imageInfo{
destSet.Set(ucloudcommon.ImageInfo{
Region: dest.Region,
ProjectId: dest.ProjectId,
})
@ -163,9 +164,9 @@ func checkRegionCopy(projectId string, imageDst []ImageDestination) builderT.Tes
if r.ProjectId == projectId && r.Region == "cn-bj2" {
continue
}
imageSet, err := client.describeImageByInfo(r.ProjectId, r.Region, r.ImageId)
imageSet, err := client.DescribeImageByInfo(r.ProjectId, r.Region, r.ImageId)
if err != nil {
if isNotFoundError(err) {
if ucloudcommon.IsNotFoundError(err) {
return fmt.Errorf("image %s in artifacts can not be found", r.ImageId)
}
return err
@ -196,17 +197,17 @@ func testAccPreCheck(t *testing.T) {
func TestUCloudClientBaseUrlConfigurable(t *testing.T) {
const url = "baseUrl"
access := &AccessConfig{BaseUrl: url}
access := &ucloudcommon.AccessConfig{BaseUrl: url}
client, err := access.Client()
assert.Nil(t, err)
assert.Equal(t, url, client.uaccountconn.Client.GetConfig().BaseUrl, "account conn's base url not configurable")
assert.Equal(t, url, client.uhostconn.Client.GetConfig().BaseUrl, "host conn's base url not configurable")
assert.Equal(t, url, client.unetconn.Client.GetConfig().BaseUrl, "net conn's base url not configurable")
assert.Equal(t, url, client.vpcconn.Client.GetConfig().BaseUrl, "vpc conn's base url not configurable")
assert.Equal(t, url, client.UAccountConn.Client.GetConfig().BaseUrl, "account conn's base url not configurable")
assert.Equal(t, url, client.UHostConn.Client.GetConfig().BaseUrl, "host conn's base url not configurable")
assert.Equal(t, url, client.UNetConn.Client.GetConfig().BaseUrl, "net conn's base url not configurable")
assert.Equal(t, url, client.VPCConn.Client.GetConfig().BaseUrl, "vpc conn's base url not configurable")
}
func testUCloudClient() (*UCloudClient, error) {
access := &AccessConfig{Region: "cn-bj2"}
func testUCloudClient() (*ucloudcommon.UCloudClient, error) {
access := &ucloudcommon.AccessConfig{Region: "cn-bj2"}
err := access.Config()
if err != nil {
return nil, err

View File

@ -1,6 +1,7 @@
package uhost
import (
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/packer"
"reflect"
"testing"
@ -120,7 +121,7 @@ func TestBuilderPrepare_ImageDestinations(t *testing.T) {
t.Fatalf("should not have error: %s", err)
}
if !reflect.DeepEqual(b.config.ImageDestinations, []ImageDestination{
if !reflect.DeepEqual(b.config.ImageDestinations, []ucloudcommon.ImageDestination{
{
ProjectId: "project1",
Region: "region1",

View File

@ -1,24 +0,0 @@
package uhost
const (
// defaultPasswordStr, defaultPasswordNum and defaultPasswordSpe are used to general default value of root password of UHost instance
defaultPasswordNum = "012346789"
defaultPasswordStr = "abcdefghijklmnopqrstuvwxyz"
defaultPasswordSpe = "-_"
)
const (
osTypeWindows = "Windows"
securityGroupNonWeb = "recommend non web"
instanceStateRunning = "Running"
instanceStateStopped = "Stopped"
bootDiskStateNormal = "Normal"
imageStateAvailable = "Available"
ipTypePrivate = "Private"
)
var bootDiskTypeMap = map[string]string{
"cloud_ssd": "CLOUD_SSD",
"local_normal": "LOCAL_NORMAL",
"local_ssd": "LOCAL_SSD",
}

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
@ -13,20 +14,20 @@ type stepCheckSourceImageId struct {
func (s *stepCheckSourceImageId) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(*UCloudClient)
client := state.Get("client").(*ucloudcommon.UCloudClient)
ui.Say("Querying source image id...")
imageSet, err := client.DescribeImageById(s.SourceUHostImageId)
if err != nil {
if isNotFoundError(err) {
return halt(state, err, "")
if ucloudcommon.IsNotFoundError(err) {
return ucloudcommon.Halt(state, err, "")
}
return halt(state, err, fmt.Sprintf("Error on querying specified source_image_id %q", s.SourceUHostImageId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on querying specified source_image_id %q", s.SourceUHostImageId))
}
if imageSet.OsType == osTypeWindows {
return halt(state, err, "The ucloud-uhost builder does not support Windows images yet")
if imageSet.OsType == ucloudcommon.OsTypeWindows {
return ucloudcommon.Halt(state, err, "The ucloud-uhost builder does not support Windows images yet")
}
state.Put("source_image", imageSet)

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/ucloud/ucloud-sdk-go/ucloud"
@ -13,19 +14,19 @@ type stepConfigSecurityGroup struct {
}
func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*UCloudClient)
conn := client.unetconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UNetConn
ui := state.Get("ui").(packer.Ui)
if len(s.SecurityGroupId) != 0 {
ui.Say(fmt.Sprintf("Trying to use specified security group %q...", s.SecurityGroupId))
securityGroupSet, err := client.describeFirewallById(s.SecurityGroupId)
securityGroupSet, err := client.DescribeFirewallById(s.SecurityGroupId)
if err != nil {
if isNotFoundError(err) {
if ucloudcommon.IsNotFoundError(err) {
err = fmt.Errorf("the specified security group %q does not exist", s.SecurityGroupId)
return halt(state, err, "")
return ucloudcommon.Halt(state, err, "")
}
return halt(state, err, fmt.Sprintf("Error on querying specified security group %q", s.SecurityGroupId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on querying specified security group %q", s.SecurityGroupId))
}
state.Put("security_group_id", securityGroupSet.FWId)
@ -44,7 +45,7 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
resp, err := conn.DescribeFirewall(req)
if err != nil {
return halt(state, err, "Error on querying default security group")
return ucloudcommon.Halt(state, err, "Error on querying default security group")
}
if resp == nil || len(resp.DataSet) < 1 {
@ -52,7 +53,7 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
}
for _, item := range resp.DataSet {
if item.Type == securityGroupNonWeb {
if item.Type == ucloudcommon.SecurityGroupNonWeb {
securityGroupId = item.FWId
break
}
@ -66,7 +67,7 @@ func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.State
}
if securityGroupId == "" {
return halt(state, fmt.Errorf("the default security group does not exist"), "")
return ucloudcommon.Halt(state, fmt.Errorf("the default security group does not exist"), "")
}
state.Put("security_group_id", securityGroupId)

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
@ -12,18 +13,18 @@ type stepConfigSubnet struct {
}
func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*UCloudClient)
client := state.Get("client").(*ucloudcommon.UCloudClient)
ui := state.Get("ui").(packer.Ui)
if len(s.SubnetId) != 0 {
ui.Say(fmt.Sprintf("Trying to use specified subnet %q...", s.SubnetId))
subnetSet, err := client.describeSubnetById(s.SubnetId)
subnetSet, err := client.DescribeSubnetById(s.SubnetId)
if err != nil {
if isNotFoundError(err) {
if ucloudcommon.IsNotFoundError(err) {
err = fmt.Errorf("the specified subnet %q does not exist", s.SubnetId)
return halt(state, err, "")
return ucloudcommon.Halt(state, err, "")
}
return halt(state, err, fmt.Sprintf("Error on querying specified subnet %q", s.SubnetId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on querying specified subnet %q", s.SubnetId))
}
state.Put("subnet_id", subnetSet.SubnetId)

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
@ -13,19 +14,19 @@ type stepConfigVPC struct {
}
func (s *stepConfigVPC) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*UCloudClient)
client := state.Get("client").(*ucloudcommon.UCloudClient)
ui := state.Get("ui").(packer.Ui)
if len(s.VPCId) != 0 {
ui.Say(fmt.Sprintf("Trying to use specified vpc %q...", s.VPCId))
vpcSet, err := client.describeVPCById(s.VPCId)
vpcSet, err := client.DescribeVPCById(s.VPCId)
if err != nil {
if isNotFoundError(err) {
if ucloudcommon.IsNotFoundError(err) {
err = fmt.Errorf("the specified vpc %q does not exist", s.VPCId)
return halt(state, err, "")
return ucloudcommon.Halt(state, err, "")
}
return halt(state, err, fmt.Sprintf("Error on querying specified vpc %q", s.VPCId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on querying specified vpc %q", s.VPCId))
}
state.Put("vpc_id", vpcSet.VPCId)

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/common/retry"
"strings"
"time"
@ -13,9 +14,10 @@ import (
)
type stepCopyUCloudImage struct {
ImageDestinations []ImageDestination
RegionId string
ProjectId string
ImageDestinations []ucloudcommon.ImageDestination
RegionId string
ProjectId string
WaitImageReadyTimeout int
}
func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@ -23,13 +25,13 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
return multistep.ActionContinue
}
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
ui := state.Get("ui").(packer.Ui)
srcImageId := state.Get("image_id").(string)
artifactImages := state.Get("ucloud_images").(*imageInfoSet)
expectedImages := newImageInfoSet(nil)
artifactImages := state.Get("ucloud_images").(*ucloudcommon.ImageInfoSet)
expectedImages := ucloudcommon.NewImageInfoSet(nil)
ui.Say(fmt.Sprintf("Copying images from %q...", srcImageId))
for _, v := range s.ImageDestinations {
if v.ProjectId == s.ProjectId && v.Region == s.RegionId {
@ -45,10 +47,10 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
resp, err := conn.CopyCustomImage(req)
if err != nil {
return halt(state, err, fmt.Sprintf("Error on copying image %q to %s:%s", srcImageId, v.ProjectId, v.Region))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on copying image %q to %s:%s", srcImageId, v.ProjectId, v.Region))
}
image := imageInfo{
image := ucloudcommon.ImageInfo{
Region: v.Region,
ProjectId: v.ProjectId,
ImageId: resp.TargetImageId,
@ -62,24 +64,26 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
ui.Message("Waiting for the copied images to become available...")
err := retry.Config{
Tries: 200,
ShouldRetry: func(err error) bool { return isNotCompleteError(err) },
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 12 * time.Second, Multiplier: 2}).Linear,
StartTimeout: time.Duration(s.WaitImageReadyTimeout) * time.Second,
ShouldRetry: func(err error) bool {
return ucloudcommon.IsNotCompleteError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 12 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
for _, v := range expectedImages.GetAll() {
imageSet, err := client.describeImageByInfo(v.ProjectId, v.Region, v.ImageId)
imageSet, err := client.DescribeImageByInfo(v.ProjectId, v.Region, v.ImageId)
if err != nil {
return fmt.Errorf("reading %s:%s:%s failed, %s", v.ProjectId, v.Region, v.ImageId, err)
}
if imageSet.State == imageStateAvailable {
if imageSet.State == ucloudcommon.ImageStateAvailable {
expectedImages.Remove(v.Id())
continue
}
}
if len(expectedImages.GetAll()) != 0 {
return newNotCompleteError("copying image")
return ucloudcommon.NewNotCompletedError("copying image")
}
return nil
@ -91,7 +95,7 @@ func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag)
s = append(s, fmt.Sprintf("%s:%s:%s", v.ProjectId, v.Region, v.ImageId))
}
return halt(state, err, fmt.Sprintf("Error on waiting for copying images %q to become available", strings.Join(s, ",")))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on waiting for copying images %q to become available", strings.Join(s, ",")))
}
ui.Message(fmt.Sprintf("Copying image complete"))
@ -107,7 +111,7 @@ func (s *stepCopyUCloudImage) Cleanup(state multistep.StateBag) {
}
srcImageId := state.Get("image_id").(string)
ucloudImages := state.Get("ucloud_images").(*imageInfoSet)
ucloudImages := state.Get("ucloud_images").(*ucloudcommon.ImageInfoSet)
imageInfos := ucloudImages.GetAll()
if len(imageInfos) == 0 {
return
@ -116,8 +120,8 @@ func (s *stepCopyUCloudImage) Cleanup(state multistep.StateBag) {
}
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
ui.Say(fmt.Sprintf("Deleting copied image because of cancellation or error..."))
for _, v := range imageInfos {

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/common/retry"
"time"
@ -17,8 +18,8 @@ type stepCreateImage struct {
}
func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
instance := state.Get("instance").(*uhost.UHostInstanceSet)
ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(*Config)
@ -32,14 +33,14 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
resp, err := conn.CreateCustomImage(req)
if err != nil {
return halt(state, err, "Error on creating image")
return ucloudcommon.Halt(state, err, "Error on creating image")
}
ui.Message(fmt.Sprintf("Waiting for the created image %q to become available...", resp.ImageId))
err = retry.Config{
Tries: 200,
StartTimeout: time.Duration(config.WaitImageReadyTimeout) * time.Second,
ShouldRetry: func(err error) bool {
return isExpectedStateError(err)
return ucloudcommon.IsExpectedStateError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 12 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
@ -47,26 +48,26 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
if err != nil {
return err
}
if inst == nil || inst.State != imageStateAvailable {
return newExpectedStateError("image", resp.ImageId)
if inst == nil || inst.State != ucloudcommon.ImageStateAvailable {
return ucloudcommon.NewExpectedStateError("image", resp.ImageId)
}
return nil
})
if err != nil {
return halt(state, err, fmt.Sprintf("Error on waiting for image %q to become available", resp.ImageId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on waiting for image %q to become available", resp.ImageId))
}
imageSet, err := client.DescribeImageById(resp.ImageId)
if err != nil {
return halt(state, err, fmt.Sprintf("Error on reading image when creating %q", resp.ImageId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on reading image when creating %q", resp.ImageId))
}
s.image = imageSet
state.Put("image_id", imageSet.ImageId)
images := []imageInfo{
images := []ucloudcommon.ImageInfo{
{
ImageId: imageSet.ImageId,
ProjectId: config.ProjectId,
@ -74,7 +75,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
},
}
state.Put("ucloud_images", newImageInfoSet(images))
state.Put("ucloud_images", ucloudcommon.NewImageInfoSet(images))
ui.Message(fmt.Sprintf("Creating image %q complete", imageSet.ImageId))
return multistep.ActionContinue
}
@ -89,8 +90,8 @@ func (s *stepCreateImage) Cleanup(state multistep.StateBag) {
return
}
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
ui := state.Get("ui").(packer.Ui)
ui.Say("Deleting image because of cancellation or error...")

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
@ -26,25 +27,25 @@ type stepCreateInstance struct {
}
func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
ui := state.Get("ui").(packer.Ui)
ui.Say("Creating Instance...")
resp, err := conn.CreateUHostInstance(s.buildCreateInstanceRequest(state))
if err != nil {
return halt(state, err, "Error on creating instance")
return ucloudcommon.Halt(state, err, "Error on creating instance")
}
instanceId := resp.UHostIds[0]
err = retry.Config{
Tries: 20,
ShouldRetry: func(err error) bool {
return isExpectedStateError(err)
return ucloudcommon.IsExpectedStateError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
inst, err := client.describeUHostById(instanceId)
inst, err := client.DescribeUHostById(instanceId)
if err != nil {
return err
}
@ -57,27 +58,27 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
return fmt.Errorf("install failed")
}
if inst == nil || inst.State != instanceStateRunning {
return newExpectedStateError("instance", instanceId)
if inst == nil || inst.State != ucloudcommon.InstanceStateRunning {
return ucloudcommon.NewExpectedStateError("instance", instanceId)
}
return nil
})
if err != nil {
return halt(state, err, fmt.Sprintf("Error on waiting for instance %q to become available", instanceId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on waiting for instance %q to become available", instanceId))
}
ui.Message(fmt.Sprintf("Creating instance %q complete", instanceId))
instance, err := client.describeUHostById(instanceId)
instance, err := client.DescribeUHostById(instanceId)
if err != nil {
return halt(state, err, fmt.Sprintf("Error on reading instance when creating %q", instanceId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on reading instance when creating %q", instanceId))
}
s.instanceId = instanceId
state.Put("instance", instance)
if instance.BootDiskState != bootDiskStateNormal {
if instance.BootDiskState != ucloudcommon.BootDiskStateNormal {
ui.Say("Waiting for boot disk of instance initialized")
if s.BootDiskType == "local_normal" || s.BootDiskType == "local_ssd" {
ui.Message(fmt.Sprintf("Warning: It takes around 10 mins for boot disk initialization when `boot_disk_type` is %q", s.BootDiskType))
@ -86,23 +87,23 @@ func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag)
err = retry.Config{
Tries: 200,
ShouldRetry: func(err error) bool {
return isExpectedStateError(err)
return ucloudcommon.IsExpectedStateError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 12 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
inst, err := client.describeUHostById(instanceId)
inst, err := client.DescribeUHostById(instanceId)
if err != nil {
return err
}
if inst.BootDiskState != bootDiskStateNormal {
return newExpectedStateError("boot_disk of instance", instanceId)
if inst.BootDiskState != ucloudcommon.BootDiskStateNormal {
return ucloudcommon.NewExpectedStateError("boot_disk of instance", instanceId)
}
return nil
})
if err != nil {
return halt(state, err, fmt.Sprintf("Error on waiting for boot disk of instance %q initialized", instanceId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on waiting for boot disk of instance %q initialized", instanceId))
}
ui.Message(fmt.Sprintf("Waiting for boot disk of instance %q initialized complete", instanceId))
@ -127,12 +128,12 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
ui.Say("Deleting instance...")
}
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
instance, err := client.describeUHostById(s.instanceId)
instance, err := client.DescribeUHostById(s.instanceId)
if err != nil {
if isNotFoundError(err) {
if ucloudcommon.IsNotFoundError(err) {
return
}
ui.Error(fmt.Sprintf("Error on reading instance when deleting %q, %s",
@ -140,7 +141,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
return
}
if instance.State != instanceStateStopped {
if instance.State != ucloudcommon.InstanceStateStopped {
stopReq := conn.NewStopUHostInstanceRequest()
stopReq.UHostId = ucloud.String(s.instanceId)
if _, err = conn.StopUHostInstance(stopReq); err != nil {
@ -152,17 +153,17 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
err = retry.Config{
Tries: 30,
ShouldRetry: func(err error) bool {
return isExpectedStateError(err)
return ucloudcommon.IsExpectedStateError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
instance, err := client.describeUHostById(s.instanceId)
instance, err := client.DescribeUHostById(s.instanceId)
if err != nil {
return err
}
if instance.State != instanceStateStopped {
return newExpectedStateError("instance", s.instanceId)
if instance.State != ucloudcommon.InstanceStateStopped {
return ucloudcommon.NewExpectedStateError("instance", s.instanceId)
}
return nil
@ -188,10 +189,10 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
err = retry.Config{
Tries: 30,
ShouldRetry: func(err error) bool { return !isNotFoundError(err) },
ShouldRetry: func(err error) bool { return !ucloudcommon.IsNotFoundError(err) },
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
_, err := client.describeUHostById(s.instanceId)
_, err := client.DescribeUHostById(s.instanceId)
return err
})
@ -205,8 +206,8 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
}
func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag) *uhost.CreateUHostInstanceRequest {
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
srcImage := state.Get("source_image").(*uhost.UHostImageSet)
config := state.Get("config").(*Config)
connectConfig := &config.RunConfig.Comm
@ -218,16 +219,16 @@ func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag
if password == "" {
password = fmt.Sprintf("%s%s%s",
s.randStringFromCharSet(5, defaultPasswordStr),
s.randStringFromCharSet(1, defaultPasswordSpe),
s.randStringFromCharSet(5, defaultPasswordNum))
s.randStringFromCharSet(5, ucloudcommon.DefaultPasswordStr),
s.randStringFromCharSet(1, ucloudcommon.DefaultPasswordSpe),
s.randStringFromCharSet(5, ucloudcommon.DefaultPasswordNum))
if srcImage.OsType == "Linux" {
connectConfig.SSHPassword = password
}
}
req := conn.NewCreateUHostInstanceRequest()
t, _ := parseInstanceType(s.InstanceType)
t, _ := ucloudcommon.ParseInstanceType(s.InstanceType)
req.CPU = ucloud.Int(t.CPU)
req.Memory = ucloud.Int(t.Memory)
@ -238,6 +239,12 @@ func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag
req.ChargeType = ucloud.String("Dynamic")
req.Password = ucloud.String(password)
req.MachineType = ucloud.String("N")
req.MinimalCpuPlatform = ucloud.String("Intel/Auto")
if t.HostType == "o" {
req.MachineType = ucloud.String("O")
}
if v, ok := state.GetOk("security_group_id"); ok {
req.SecurityGroupId = ucloud.String(v.(string))
}
@ -253,7 +260,7 @@ func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag
bootDisk := uhost.UHostDisk{}
bootDisk.IsBoot = ucloud.String("true")
bootDisk.Size = ucloud.Int(srcImage.ImageSize)
bootDisk.Type = ucloud.String(bootDiskTypeMap[s.BootDiskType])
bootDisk.Type = ucloud.String(ucloudcommon.BootDiskTypeMap.Convert(s.BootDiskType))
req.Disks = append(req.Disks, bootDisk)

View File

@ -2,6 +2,7 @@ package uhost
import (
"context"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
@ -10,20 +11,20 @@ type stepPreValidate struct {
ProjectId string
Region string
Zone string
ImageDestinations []ImageDestination
ImageDestinations []ucloudcommon.ImageDestination
}
func (s *stepPreValidate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if err := s.validateProjectIds(state); err != nil {
return halt(state, err, "")
return ucloudcommon.Halt(state, err, "")
}
if err := s.validateRegions(state); err != nil {
return halt(state, err, "")
return ucloudcommon.Halt(state, err, "")
}
if err := s.validateZones(state); err != nil {
return halt(state, err, "")
return ucloudcommon.Halt(state, err, "")
}
return multistep.ActionContinue

View File

@ -3,6 +3,7 @@ package uhost
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/common/retry"
"time"
@ -16,17 +17,17 @@ type stepStopInstance struct {
}
func (s *stepStopInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*UCloudClient)
conn := client.uhostconn
client := state.Get("client").(*ucloudcommon.UCloudClient)
conn := client.UHostConn
instance := state.Get("instance").(*uhost.UHostInstanceSet)
ui := state.Get("ui").(packer.Ui)
instance, err := client.describeUHostById(instance.UHostId)
instance, err := client.DescribeUHostById(instance.UHostId)
if err != nil {
return halt(state, err, fmt.Sprintf("Error on reading instance when stopping %q", instance.UHostId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on reading instance when stopping %q", instance.UHostId))
}
if instance.State != instanceStateStopped {
if instance.State != ucloudcommon.InstanceStateStopped {
stopReq := conn.NewStopUHostInstanceRequest()
stopReq.UHostId = ucloud.String(instance.UHostId)
ui.Say(fmt.Sprintf("Stopping instance %q", instance.UHostId))
@ -44,30 +45,30 @@ func (s *stepStopInstance) Run(ctx context.Context, state multistep.StateBag) mu
})
if err != nil {
return halt(state, err, fmt.Sprintf("Error on stopping instance %q", instance.UHostId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on stopping instance %q", instance.UHostId))
}
err = retry.Config{
Tries: 20,
ShouldRetry: func(err error) bool {
return isExpectedStateError(err)
return ucloudcommon.IsExpectedStateError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
instance, err := client.describeUHostById(instance.UHostId)
instance, err := client.DescribeUHostById(instance.UHostId)
if err != nil {
return err
}
if instance.State != instanceStateStopped {
return newExpectedStateError("instance", instance.UHostId)
if instance.State != ucloudcommon.InstanceStateStopped {
return ucloudcommon.NewExpectedStateError("instance", instance.UHostId)
}
return nil
})
if err != nil {
return halt(state, err, fmt.Sprintf("Error on waiting for stopping instance when stopping %q", instance.UHostId))
return ucloudcommon.Halt(state, err, fmt.Sprintf("Error on waiting for stopping instance when stopping %q", instance.UHostId))
}
ui.Message(fmt.Sprintf("Stopping instance %q complete", instance.UHostId))

View File

@ -75,6 +75,7 @@ import (
googlecomputeimportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-import"
manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest"
shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local"
ucloudimportpostprocessor "github.com/hashicorp/packer/post-processor/ucloud-import"
vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant"
vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud"
vspherepostprocessor "github.com/hashicorp/packer/post-processor/vsphere"
@ -188,6 +189,7 @@ var PostProcessors = map[string]packer.PostProcessor{
"googlecompute-import": new(googlecomputeimportpostprocessor.PostProcessor),
"manifest": new(manifestpostprocessor.PostProcessor),
"shell-local": new(shelllocalpostprocessor.PostProcessor),
"ucloud-import": new(ucloudimportpostprocessor.PostProcessor),
"vagrant": new(vagrantpostprocessor.PostProcessor),
"vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor),
"vsphere": new(vspherepostprocessor.PostProcessor),

View File

@ -4,30 +4,35 @@
"ucloud_private_key": "{{env `UCLOUD_PRIVATE_KEY`}}",
"ucloud_project_id": "{{env `UCLOUD_PROJECT_ID`}}"
},
"builders": [{
"type": "ucloud-uhost",
"public_key": "{{user `ucloud_public_key`}}",
"private_key": "{{user `ucloud_private_key`}}",
"project_id": "{{user `ucloud_project_id`}}",
"region": "cn-bj2",
"availability_zone": "cn-bj2-02",
"instance_type": "n-basic-2",
"source_image_id": "uimage-f1chxn",
"ssh_username":"root",
"image_name": "packer-test-basic-bj",
"image_copy_to_mappings": [{
"builders": [
{
"type": "ucloud-uhost",
"public_key": "{{user `ucloud_public_key`}}",
"private_key": "{{user `ucloud_private_key`}}",
"project_id": "{{user `ucloud_project_id`}}",
"region": "cn-sh2",
"description": "test",
"name": "packer-test-basic-sh"
}]
}],
"provisioners": [{
"type": "shell",
"inline": [
"yum install -y nginx"
]
}]
"region": "cn-bj2",
"availability_zone": "cn-bj2-02",
"instance_type": "n-basic-2",
"source_image_id": "uimage-f1chxn",
"ssh_username": "root",
"image_name": "packer-test-basic-bj",
"image_copy_to_mappings": [
{
"project_id": "{{user `ucloud_project_id`}}",
"region": "cn-sh2",
"description": "test",
"name": "packer-test-basic-sh"
}
]
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"yum install -y nginx"
]
}
]
}

View File

@ -0,0 +1,25 @@
install
cdrom
lang en_US.UTF-8
keyboard us
network --bootproto=dhcp
rootpw ucloud_packer
firewall --disabled
selinux --permissive
timezone UTC
unsupported_hardware
bootloader --location=mbr
text
skipx
zerombr
clearpart --all
autopart
auth --enableshadow --passalgo=sha512
firstboot --disabled
reboot
%packages --nobase --ignoremissing
sudo
gcc
make
%end

View File

@ -0,0 +1,56 @@
{"variables": {
"ucloud_public_key": "{{env `UCLOUD_PUBLIC_KEY`}}",
"ucloud_private_key": "{{env `UCLOUD_PRIVATE_KEY`}}",
"ucloud_project_id": "{{env `UCLOUD_PROJECT_ID`}}",
"disk_size": "4096",
"iso_checksum": "0da4a1206e7642906e33c0f155d2f835",
"iso_checksum_type": "md5",
"iso_name": "CentOS-6.10-x86_64-minimal.iso",
"ks_path": "centos-6.10/ks.cfg",
"mirror": "http://mirrors.ustc.edu.cn/centos",
"mirror_directory": "6.10/isos/x86_64",
"template": "centos-6.10-x86_64"
},
"builders":[
{
"type": "qemu",
"boot_command": [
"<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/{{user `ks_path`}}<enter><wait>"
],
"boot_wait": "10s",
"disk_size": "{{user `disk_size`}}",
"http_directory": "http",
"iso_checksum": "{{user `iso_checksum`}}",
"iso_checksum_type": "{{user `iso_checksum_type`}}",
"iso_url": "{{user `mirror`}}/{{user `mirror_directory`}}/{{user `iso_name`}}",
"output_directory": "packer-{{user `template`}}-qemu",
"shutdown_command": "echo 'packer'|sudo -S shutdown -P now",
"ssh_password": "ucloud_packer",
"ssh_port": 22,
"ssh_username": "root",
"ssh_timeout": "10000s",
"vm_name": "{{ user `template` }}.raw",
"net_device": "virtio-net",
"disk_interface": "virtio",
"format": "raw",
"use_default_display": "false",
"qemuargs": [
["-display", "cocoa"]
]
}
],
"post-processors":[
{
"type":"ucloud-import",
"public_key": "{{user `ucloud_public_key`}}",
"private_key": "{{user `ucloud_private_key`}}",
"project_id": "{{user `ucloud_project_id`}}",
"region":"cn-bj2",
"ufile_bucket_name": "packer-test",
"image_name": "packer_import_test",
"image_os_type": "CentOS",
"image_os_name": "CentOS 6.10 64位",
"format": "raw"
}
]
}

3
go.mod
View File

@ -133,7 +133,8 @@ require (
github.com/stretchr/testify v1.4.0
github.com/temoto/robotstxt v1.1.1 // indirect
github.com/tencentcloud/tencentcloud-sdk-go v3.0.94+incompatible
github.com/ucloud/ucloud-sdk-go v0.8.7
github.com/ucloud/ucloud-sdk-go v0.12.0
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1
github.com/ulikunitz/xz v0.5.5
github.com/vmware/govmomi v0.0.0-20170707011325-c2105a174311

4
go.sum
View File

@ -414,6 +414,10 @@ github.com/tencentcloud/tencentcloud-sdk-go v3.0.94+incompatible h1:G8i7dPMK1RCp
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/ucloud/ucloud-sdk-go v0.12.0 h1:VCFN3jWg/G4wvwjG6qG5AhFuAT1JdmGvY6+4WHbuJcw=
github.com/ucloud/ucloud-sdk-go v0.12.0/go.mod h1:lM6fpI8y6iwACtlbHUav823/uKPdXsNBlnBpRF2fj3c=
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6 h1:FAWNiqocJ04wC4Znj7Ax4PGWstZijayO6ifuHHvb+vI=
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6/go.mod h1:R5FMQxkQ+QK/9Vz+jfnJP4rZIktYrRcWmuAnbOSkROI=
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1 h1:U6ufy3mLDgg9RYupntOvAF7xCmNNquyKaYaaVHo1Nnk=
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=

View File

@ -0,0 +1,331 @@
package ucloudimport
import (
"context"
"fmt"
ucloudcommon "github.com/hashicorp/packer/builder/ucloud/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
"github.com/ucloud/ucloud-sdk-go/services/ufile"
"github.com/ucloud/ucloud-sdk-go/services/uhost"
"github.com/ucloud/ucloud-sdk-go/ucloud"
ufsdk "github.com/ufilesdk-dev/ufile-gosdk"
"log"
"net/url"
"strings"
"time"
)
const (
BuilderId = "packer.post-processor.ucloud-import"
ImageFileFormatRAW = "raw"
ImageFileFormatVHD = "vhd"
ImageFileFormatVMDK = "vmdk"
ImageFileFormatQCOW2 = "qcow2"
)
var imageFormatMap = ucloudcommon.NewStringConverter(map[string]string{
"raw": "RAW",
"vhd": "VHD",
"vmdk": "VMDK",
})
// Configuration of this post processor
type Config struct {
common.PackerConfig `mapstructure:",squash"`
ucloudcommon.AccessConfig `mapstructure:",squash"`
// Variables specific to this post processor
UFileBucket string `mapstructure:"ufile_bucket_name"`
UFileKey string `mapstructure:"ufile_key_name"`
SkipClean bool `mapstructure:"skip_clean"`
ImageName string `mapstructure:"image_name"`
ImageDescription string `mapstructure:"image_description"`
OSType string `mapstructure:"image_os_type"`
OSName string `mapstructure:"image_os_name"`
Format string `mapstructure:"format"`
WaitImageReadyTimeout int `mapstructure:"wait_image_ready_timeout"`
ctx interpolate.Context
}
type PostProcessor struct {
config Config
}
// Entry point for configuration parsing when we've defined
func (p *PostProcessor) Configure(raws ...interface{}) error {
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"ufile_key_name",
},
},
}, raws...)
if err != nil {
return err
}
// Set defaults
if p.config.UFileKey == "" {
p.config.UFileKey = "packer-import-{{timestamp}}." + p.config.Format
}
if p.config.WaitImageReadyTimeout <= 0 {
p.config.WaitImageReadyTimeout = ucloudcommon.DefaultCreateImageTimeout
}
errs := new(packer.MultiError)
// Check and render ufile_key_name
if err = interpolate.Validate(p.config.UFileKey, &p.config.ctx); err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Error parsing ufile_key_name template: %s", err))
}
// Check we have ucloud access variables defined somewhere
errs = packer.MultiErrorAppend(errs, p.config.AccessConfig.Prepare(&p.config.ctx)...)
// define all our required parameters
templates := map[string]*string{
"ufile_bucket_name": &p.config.UFileBucket,
"image_name": &p.config.ImageName,
"image_os_type": &p.config.OSType,
"image_os_name": &p.config.OSName,
"format": &p.config.Format,
}
// Check out required params are defined
for key, ptr := range templates {
if *ptr == "" {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("%s must be set", key))
}
}
imageName := p.config.ImageName
if !ucloudcommon.ImageNamePattern.MatchString(imageName) {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("expected %q to be 1-63 characters and only support chinese, english, numbers, '-_,.:[]', got %q", "image_name", imageName))
}
switch p.config.Format {
case ImageFileFormatVHD, ImageFileFormatRAW, ImageFileFormatVMDK, ImageFileFormatQCOW2:
default:
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("expected %q only be one of 'raw', 'vhd', 'vmdk', or 'qcow2', got %q", "format", p.config.Format))
}
// Anything which flagged return back up the stack
if len(errs.Errors) > 0 {
return errs
}
packer.LogSecretFilter.Set(p.config.PublicKey, p.config.PrivateKey)
log.Println(p.config)
return nil
}
func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, bool, error) {
var err error
client, err := p.config.Client()
if err != nil {
return nil, false, false, fmt.Errorf("Failed to connect ucloud client %s", err)
}
uhostconn := client.UHostConn
ufileconn := client.UFileConn
// Render this key since we didn't in the configure phase
p.config.UFileKey, err = interpolate.Render(p.config.UFileKey, &p.config.ctx)
if err != nil {
return nil, false, false, fmt.Errorf("Error rendering ufile_key_name template: %s", err)
}
ui.Message(fmt.Sprintf("Rendered ufile_key_name as %s", p.config.UFileKey))
ui.Message("Looking for image in artifact")
// Locate the files output from the builder
var source string
for _, path := range artifact.Files() {
if strings.HasSuffix(path, "."+p.config.Format) {
source = path
break
}
}
// Hope we found something useful
if source == "" {
return nil, false, false, fmt.Errorf("No %s image file found in artifact from builder", p.config.Format)
}
keyName := p.config.UFileKey
bucketName := p.config.UFileBucket
// query bucket
domain, err := queryBucket(ufileconn, bucketName)
if err != nil {
return nil, false, false, fmt.Errorf("Failed to query bucket, %s", err)
}
var bucketHost string
if p.config.BaseUrl != "" {
// skip error because it has been validated by prepare
urlObj, _ := url.Parse(p.config.BaseUrl)
bucketHost = urlObj.Host
} else {
bucketHost = "api.ucloud.cn"
}
fileHost := strings.SplitN(domain, ".", 2)[1]
config := &ufsdk.Config{
PublicKey: p.config.PublicKey,
PrivateKey: p.config.PrivateKey,
BucketName: bucketName,
FileHost: fileHost,
BucketHost: bucketHost,
}
ui.Say(fmt.Sprintf("Waiting for uploading image file %s to UFile: %s/%s...", source, bucketName, keyName))
// upload file to bucket
ufileUrl, err := uploadFile(ufileconn, config, keyName, source)
if err != nil {
return nil, false, false, fmt.Errorf("Failed to Upload image file, %s", err)
}
ui.Say(fmt.Sprintf("Image file %s has been uploaded to UFile: %s/%s", source, bucketName, keyName))
importImageRequest := p.buildImportImageRequest(uhostconn, ufileUrl)
importImageResponse, err := uhostconn.ImportCustomImage(importImageRequest)
if err != nil {
return nil, false, false, fmt.Errorf("Failed to import image from UFile: %s/%s, %s", bucketName, keyName, err)
}
ui.Say(fmt.Sprintf("Waiting for importing image from UFile: %s/%s ...", bucketName, keyName))
imageId := importImageResponse.ImageId
err = retry.Config{
StartTimeout: time.Duration(p.config.WaitImageReadyTimeout) * time.Second,
ShouldRetry: func(err error) bool {
return ucloudcommon.IsExpectedStateError(err)
},
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 12 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
image, err := client.DescribeImageById(imageId)
if err != nil {
return err
}
if image.State == ucloudcommon.ImageStateUnavailable {
return fmt.Errorf("Unavailable importing image %q", imageId)
}
if image.State != ucloudcommon.ImageStateAvailable {
return ucloudcommon.NewExpectedStateError("image", imageId)
}
return nil
})
if err != nil {
return nil, false, false, fmt.Errorf("Error on waiting for importing image %q from UFile: %s/%s, %s",
imageId, bucketName, keyName, err)
}
// Add the reported UCloud image ID to the artifact list
ui.Say(fmt.Sprintf("Importing created ucloud image %q in region %q Complete.", imageId, p.config.Region))
images := []ucloudcommon.ImageInfo{
{
ImageId: imageId,
ProjectId: p.config.ProjectId,
Region: p.config.Region,
},
}
artifact = &ucloudcommon.Artifact{
UCloudImages: ucloudcommon.NewImageInfoSet(images),
BuilderIdValue: BuilderId,
Client: client,
}
if !p.config.SkipClean {
ui.Message(fmt.Sprintf("Deleting import source UFile: %s/%s", p.config.UFileBucket, p.config.UFileKey))
if err = deleteFile(config, p.config.UFileKey); err != nil {
return nil, false, false, fmt.Errorf("Failed to delete UFile: %s/%s, %s", p.config.UFileBucket, p.config.UFileKey, err)
}
}
return artifact, false, false, nil
}
func (p *PostProcessor) buildImportImageRequest(conn *uhost.UHostClient, privateUrl string) *uhost.ImportCustomImageRequest {
req := conn.NewImportCustomImageRequest()
req.ImageName = ucloud.String(p.config.ImageName)
req.ImageDescription = ucloud.String(p.config.ImageDescription)
req.UFileUrl = ucloud.String(privateUrl)
req.OsType = ucloud.String(p.config.OSType)
req.OsName = ucloud.String(p.config.OSName)
req.Format = ucloud.String(imageFormatMap.Convert(p.config.Format))
req.Auth = ucloud.Bool(true)
return req
}
func queryBucket(conn *ufile.UFileClient, bucketName string) (string, error) {
req := conn.NewDescribeBucketRequest()
req.BucketName = ucloud.String(bucketName)
resp, err := conn.DescribeBucket(req)
if err != nil {
return "", fmt.Errorf("error on reading bucket %q when create bucket, %s", bucketName, err)
}
if len(resp.DataSet) < 1 {
return "", fmt.Errorf("the bucket %s is not exit", bucketName)
}
return resp.DataSet[0].Domain.Src[0], nil
}
func uploadFile(conn *ufile.UFileClient, config *ufsdk.Config, keyName, source string) (string, error) {
reqFile, err := ufsdk.NewFileRequest(config, nil)
if err != nil {
return "", fmt.Errorf("error on building upload file request, %s", err)
}
// upload file in segments
err = reqFile.AsyncMPut(source, keyName, "")
if err != nil {
return "", fmt.Errorf("error on upload file, %s, details: %s", err, reqFile.DumpResponse(true))
}
reqBucket := conn.NewDescribeBucketRequest()
reqBucket.BucketName = ucloud.String(config.BucketName)
resp, err := conn.DescribeBucket(reqBucket)
if err != nil {
return "", fmt.Errorf("error on reading bucket list when upload file, %s", err)
}
if resp.DataSet[0].Type == "private" {
return reqFile.GetPrivateURL(keyName, time.Duration(24*60*60)*time.Second), nil
}
return reqFile.GetPublicURL(keyName), nil
}
func deleteFile(config *ufsdk.Config, keyName string) error {
req, err := ufsdk.NewFileRequest(config, nil)
if err != nil {
return fmt.Errorf("error on new deleting file, %s", err)
}
req.DeleteFile(keyName)
if err != nil {
return fmt.Errorf("error on deleting file, %s", err)
}
return nil
}

View File

@ -57,7 +57,10 @@ func ValueAtPath(v interface{}, path string) (interface{}, error) {
}
if rv.Kind() == reflect.Struct {
itemV := rv.FieldByName(components[0])
itemV := rv.FieldByNameFunc(func(s string) bool {
return strings.ToLower(s) == strings.ToLower(components[0])
})
if !itemV.IsValid() {
return nil, errors.Errorf("path %s is invalid for struct", path)
}

View File

@ -1,3 +1,5 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package uaccount
import (
@ -12,7 +14,8 @@ type UAccountClient struct {
// NewClient will return a instance of UAccountClient
func NewClient(config *ucloud.Config, credential *auth.Credential) *UAccountClient {
client := ucloud.NewClient(config, credential)
meta := ucloud.ClientMeta{Product: "UAccount"}
client := ucloud.NewClientWithMeta(config, credential, meta)
return &UAccountClient{
client,
}

View File

@ -0,0 +1,21 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
)
// UFileClient is the client of UFile
type UFileClient struct {
*ucloud.Client
}
// NewClient will return a instance of UFileClient
func NewClient(config *ucloud.Config, credential *auth.Credential) *UFileClient {
client := ucloud.NewClient(config, credential)
return &UFileClient{
client,
}
}

View File

@ -0,0 +1,63 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// CreateBucketRequest is request schema for CreateBucket action
type CreateBucketRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 待创建Bucket的名称具有全局唯一性
BucketName *string `required:"true"`
// Bucket访问类型public或private; 默认为private
Type *string `required:"false"`
}
// CreateBucketResponse is response schema for CreateBucket action
type CreateBucketResponse struct {
response.CommonBase
// 已创建Bucket的ID
BucketId string
// 已创建Bucket的名称
BucketName string
}
// NewCreateBucketRequest will create request of CreateBucket action.
func (c *UFileClient) NewCreateBucketRequest() *CreateBucketRequest {
req := &CreateBucketRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(false)
return req
}
// CreateBucket - 创建Bucket
func (c *UFileClient) CreateBucket(req *CreateBucketRequest) (*CreateBucketResponse, error) {
var err error
var res CreateBucketResponse
reqCopier := *req
err = c.Client.InvokeAction("CreateBucket", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,69 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// CreateUFileTokenRequest is request schema for CreateUFileToken action
type CreateUFileTokenRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"false"`
// 令牌允许操作的bucket默认*表示全部
AllowedBuckets []string `required:"false"`
// 令牌允许执行的操作,[ TOKEN_ALLOW_NONE , TOKEN_ALLOW_READ , TOKEN_ALLOW_WRITE , TOKEN_ALLOW_DELETE , TOKEN_ALLOW_LIST, TOKEN_ALLOW_IOP , TOKEN_ALLOW_DP ]。默认TOKEN_ALLOW_NONE
AllowedOps []string `required:"false"`
// 令牌允许操作的key前缀默认*表示全部
AllowedPrefixes []string `required:"false"`
// 令牌的超时时间点(时间戳),默认一天;注意:过期时间不能超过 4102416000
ExpireTime *int `required:"false"`
// 令牌名称
TokenName *string `required:"true"`
}
// CreateUFileTokenResponse is response schema for CreateUFileToken action
type CreateUFileTokenResponse struct {
response.CommonBase
// 创建令牌的token_id
TokenId string
}
// NewCreateUFileTokenRequest will create request of CreateUFileToken action.
func (c *UFileClient) NewCreateUFileTokenRequest() *CreateUFileTokenRequest {
req := &CreateUFileTokenRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(false)
return req
}
// CreateUFileToken - 创建ufile令牌
func (c *UFileClient) CreateUFileToken(req *CreateUFileTokenRequest) (*CreateUFileTokenResponse, error) {
var err error
var res CreateUFileTokenResponse
reqCopier := *req
err = c.Client.InvokeAction("CreateUFileToken", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,60 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DeleteBucketRequest is request schema for DeleteBucket action
type DeleteBucketRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// 待删除Bucket的名称
BucketName *string `required:"true"`
}
// DeleteBucketResponse is response schema for DeleteBucket action
type DeleteBucketResponse struct {
response.CommonBase
// Bucket的ID
BucketId string
// Bucket的名称
BucketName string
}
// NewDeleteBucketRequest will create request of DeleteBucket action.
func (c *UFileClient) NewDeleteBucketRequest() *DeleteBucketRequest {
req := &DeleteBucketRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DeleteBucket - 删除Bucket
func (c *UFileClient) DeleteBucket(req *DeleteBucketRequest) (*DeleteBucketResponse, error) {
var err error
var res DeleteBucketResponse
reqCopier := *req
// In order to ignore the parameters about Region
reqCopier.Region = ucloud.String("")
err = c.Client.InvokeAction("DeleteBucket", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,54 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DeleteUFileTokenRequest is request schema for DeleteUFileToken action
type DeleteUFileTokenRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 令牌ID
TokenId *string `required:"true"`
}
// DeleteUFileTokenResponse is response schema for DeleteUFileToken action
type DeleteUFileTokenResponse struct {
response.CommonBase
}
// NewDeleteUFileTokenRequest will create request of DeleteUFileToken action.
func (c *UFileClient) NewDeleteUFileTokenRequest() *DeleteUFileTokenRequest {
req := &DeleteUFileTokenRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DeleteUFileToken - 删除令牌
func (c *UFileClient) DeleteUFileToken(req *DeleteUFileTokenRequest) (*DeleteUFileTokenResponse, error) {
var err error
var res DeleteUFileTokenResponse
reqCopier := *req
err = c.Client.InvokeAction("DeleteUFileToken", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,64 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DescribeBucketRequest is request schema for DescribeBucket action
type DescribeBucketRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// 待获取Bucket的名称若不提供则获取所有Bucket
BucketName *string `required:"false"`
// 获取所有Bucket列表的限制数目默认为20
Limit *int `required:"false"`
// 获取所有Bucket列表的偏移数目默认为0
Offset *int `required:"false"`
}
// DescribeBucketResponse is response schema for DescribeBucket action
type DescribeBucketResponse struct {
response.CommonBase
// Bucket的描述信息 参数见 UFileBucketSet
DataSet []UFileBucketSet
}
// NewDescribeBucketRequest will create request of DescribeBucket action.
func (c *UFileClient) NewDescribeBucketRequest() *DescribeBucketRequest {
req := &DescribeBucketRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DescribeBucket - 获取Bucket的描述信息
func (c *UFileClient) DescribeBucket(req *DescribeBucketRequest) (*DescribeBucketResponse, error) {
var err error
var res DescribeBucketResponse
reqCopier := *req
// In order to ignore the parameters about Region
reqCopier.Region = ucloud.String("")
err = c.Client.InvokeAction("DescribeBucket", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,66 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DescribeUFileTokenRequest is request schema for DescribeUFileToken action
type DescribeUFileTokenRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"false"`
// 0表示显示部分token信息不传递和其他情况表示显示全部token信息
Display *int `required:"false"`
// 令牌ID只返回指定ID信息否则拉取所有令牌
TokenId *string `required:"false"`
}
// DescribeUFileTokenResponse is response schema for DescribeUFileToken action
type DescribeUFileTokenResponse struct {
response.CommonBase
// 操作名称
Action string
// 令牌描述信息
DataSet []UFileTokenSet
// 返回码
RetCode int
}
// NewDescribeUFileTokenRequest will create request of DescribeUFileToken action.
func (c *UFileClient) NewDescribeUFileTokenRequest() *DescribeUFileTokenRequest {
req := &DescribeUFileTokenRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DescribeUFileToken - 获取令牌信息
func (c *UFileClient) DescribeUFileToken(req *DescribeUFileTokenRequest) (*DescribeUFileTokenResponse, error) {
var err error
var res DescribeUFileTokenResponse
reqCopier := *req
err = c.Client.InvokeAction("DescribeUFileToken", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,13 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
/*
Package ufile include resources of ucloud ufile product
See also
- API: https://docs.ucloud.cn/api/ufile-api/index
- Product: https://www.ucloud.cn/site/product/ufile.html
for detail.
*/
package ufile

View File

@ -0,0 +1,45 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
/*
UFileBucketSet - DescribeBucket
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type UFileBucketSet struct {
// Bucket所属业务, general或vod或udb general: 普通业务; vod: 视频云业务; udb: 云数据库业务
Biz string
// Bucket的ID
BucketId string
// Bucket名称
BucketName string
// 与Bucket关联的CND加速域名的ID列表
CdnDomainId []string
// Bucket的创建时间
CreateTime int
// Bucket的域名集合 参数见 UFileDomainSet
Domain UFileDomainSet
// 是否存在自定义域名。0不存在1存在2错误
HasUserDomain int
// Bucket的修改时间
ModifyTime int
// Bucket所属地域
Region string
// 所属业务组
Tag string
// Bucket访问类型
Type string
}

View File

@ -0,0 +1,24 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
/*
UFileDomainSet - DescribeBucket
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type UFileDomainSet struct {
// UCDN加速域名
Cdn []string
// 用户自定义CDN加速域名
CustomCdn []string
// 用户自定义源站域名
CustomSrc []string
// 源站域名
Src []string
}

View File

@ -0,0 +1,45 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
/*
UFileTokenSet - ufile令牌集合
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type UFileTokenSet struct {
// 令牌允许操作的bucket
AllowedBuckets []string
// 令牌允许执行的操作,[ TOKEN_ALLOW_NONE , TOKEN_ALLOW_READ , TOKEN_ALLOW_WRITE , TOKEN_ALLOW_DELETE , TOKEN_ALLOW_LIST, TOKEN_ALLOW_IOP , TOKEN_ALLOW_DP ]
AllowedOps []string
// 令牌允许操作的key前缀
AllowedPrefixes []string
// 创建时间
CreateTime int
// 令牌的超时时间点
ExpireTime int
// 修改时间
ModifyTime int
// 令牌私钥
PrivateKey string
// 令牌公钥
PublicKey string
// 所属地区
Region string
// 令牌ID
TokenId string
// 令牌名称
TokenName string
}

View File

@ -0,0 +1,62 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// UpdateBucketRequest is request schema for UpdateBucket action
type UpdateBucketRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// 待修改Bucket的名称
BucketName *string `required:"true"`
// Bucket访问类型;public或private
Type *string `required:"true"`
}
// UpdateBucketResponse is response schema for UpdateBucket action
type UpdateBucketResponse struct {
response.CommonBase
// Bucket的ID
BucketId string
// Bucket的名称
BucketName string
}
// NewUpdateBucketRequest will create request of UpdateBucket action.
func (c *UFileClient) NewUpdateBucketRequest() *UpdateBucketRequest {
req := &UpdateBucketRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// UpdateBucket - 更改Bucket的属性
func (c *UFileClient) UpdateBucket(req *UpdateBucketRequest) (*UpdateBucketResponse, error) {
var err error
var res UpdateBucketResponse
reqCopier := *req
reqCopier.Region = ucloud.String("")
err = c.Client.InvokeAction("UpdateBucket", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,69 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package ufile
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// UpdateUFileTokenRequest is request schema for UpdateUFileToken action
type UpdateUFileTokenRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"false"`
// 令牌允许操作的bucket
AllowedBuckets []string `required:"false"`
// 令牌允许执行的操作,[ TOKEN_ALLOW_NONE , TOKEN_ALLOW_READ , TOKEN_ALLOW_WRITE , TOKEN_ALLOW_DELETE , TOKEN_ALLOW_LIST, TOKEN_ALLOW_IOP , TOKEN_ALLOW_DP ]
AllowedOps []string `required:"false"`
// 令牌允许操作的key前缀
AllowedPrefixes []string `required:"false"`
// 令牌的超时时间点(时间戳);注意:过期时间不能超过 4102416000
ExpireTime *int `required:"false"`
// 令牌ID
TokenId *string `required:"true"`
// 令牌名称
TokenName *string `required:"false"`
}
// UpdateUFileTokenResponse is response schema for UpdateUFileToken action
type UpdateUFileTokenResponse struct {
response.CommonBase
}
// NewUpdateUFileTokenRequest will create request of UpdateUFileToken action.
func (c *UFileClient) NewUpdateUFileTokenRequest() *UpdateUFileTokenRequest {
req := &UpdateUFileTokenRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// UpdateUFileToken - 更新令牌的操作权限可操作key的前缀可操作bucket和令牌超时时间点
func (c *UFileClient) UpdateUFileToken(req *UpdateUFileTokenRequest) (*UpdateUFileTokenResponse, error) {
var err error
var res UpdateUFileTokenResponse
reqCopier := *req
err = c.Client.InvokeAction("UpdateUFileToken", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -1,3 +1,5 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package uhost
import (
@ -12,7 +14,8 @@ type UHostClient struct {
// NewClient will return a instance of UHostClient
func NewClient(config *ucloud.Config, credential *auth.Credential) *UHostClient {
client := ucloud.NewClient(config, credential)
meta := ucloud.ClientMeta{Product: "UHost"}
client := ucloud.NewClientWithMeta(config, credential, meta)
return &UHostClient{
client,
}

View File

@ -0,0 +1,59 @@
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
//go:generate ucloud-gen-go-api UHost CreateIsolationGroup
package uhost
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// CreateIsolationGroupRequest is request schema for CreateIsolationGroup action
type CreateIsolationGroupRequest struct {
request.CommonBase
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// [公共参数] 项目id
// ProjectId *string `required:"false"`
// 硬件隔离组名称。请遵照[[api:uhost-api:specification|字段规范]]设定隔离组名称。
GroupName *string `required:"true"`
// 备注。请遵照[[api:uhost-api:specification|字段规范]]设定隔离组备注。
Remark *string `required:"false"`
}
// CreateIsolationGroupResponse is response schema for CreateIsolationGroup action
type CreateIsolationGroupResponse struct {
response.CommonBase
// 硬件隔离组id
GroupId string
}
// NewCreateIsolationGroupRequest will create request of CreateIsolationGroup action.
func (c *UHostClient) NewCreateIsolationGroupRequest() *CreateIsolationGroupRequest {
req := &CreateIsolationGroupRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(false)
return req
}
// CreateIsolationGroup - 创建硬件隔离组,组内机器严格隔离在不同宿主机上。
func (c *UHostClient) CreateIsolationGroup(req *CreateIsolationGroupRequest) (*CreateIsolationGroupResponse, error) {
var err error
var res CreateIsolationGroupResponse
err = c.Client.InvokeAction("CreateIsolationGroup", req, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -90,6 +90,9 @@ type CreateUHostInstanceRequest struct {
// 防火墙Id默认Web推荐防火墙。如何查询SecurityGroupId请参见 [DescribeSecurityGroup](../unet-api/describe_security_group.html)
SecurityGroupId *string `required:"false"`
// 硬件隔离组id。可通过DescribeIsolationGroup获取。
IsolationGroup *string `required:"false"`
// 【暂不支持】cloudinit方式下用户初始化脚本
UserDataScript *string `required:"false"`
@ -111,6 +114,12 @@ type CreateUHostInstanceRequest struct {
// 最低cpu平台枚举值["Intel/Auto", "Intel/LvyBridge", "Intel/Haswell", "Intel/Broadwell", "Intel/Skylake", "Intel/Cascadelake"(只有O型云主机可选)]
MinimalCpuPlatform *string `required:"false"`
// 【批量创建主机时必填】最大创建主机数量,取值范围是[1,100];
MaxCount *int `required:"false"`
// GPU类型枚举值["K80", "P40", "V100"]MachineType为G时必填
GpuType *string `required:"false"`
// NetworkInterface
NetworkInterface []CreateUHostInstanceParamNetworkInterface
}

View File

@ -0,0 +1,56 @@
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
//go:generate ucloud-gen-go-api UHost DeleteIsolationGroup
package uhost
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DeleteIsolationGroupRequest is request schema for DeleteIsolationGroup action
type DeleteIsolationGroupRequest struct {
request.CommonBase
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// [公共参数] 项目id
// ProjectId *string `required:"false"`
// 硬件隔离组id
GroupId *string `required:"true"`
}
// DeleteIsolationGroupResponse is response schema for DeleteIsolationGroup action
type DeleteIsolationGroupResponse struct {
response.CommonBase
// 硬件隔离组id
GroupId string
}
// NewDeleteIsolationGroupRequest will create request of DeleteIsolationGroup action.
func (c *UHostClient) NewDeleteIsolationGroupRequest() *DeleteIsolationGroupRequest {
req := &DeleteIsolationGroupRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DeleteIsolationGroup - 删除硬件隔离组。
func (c *UHostClient) DeleteIsolationGroup(req *DeleteIsolationGroupRequest) (*DeleteIsolationGroupResponse, error) {
var err error
var res DeleteIsolationGroupResponse
err = c.Client.InvokeAction("DeleteIsolationGroup", req, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,62 @@
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
//go:generate ucloud-gen-go-api UHost DescribeIsolationGroup
package uhost
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DescribeIsolationGroupRequest is request schema for DescribeIsolationGroup action
type DescribeIsolationGroupRequest struct {
request.CommonBase
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// [公共参数] 项目id
// ProjectId *string `required:"false"`
// 待查的硬件隔离组id
GroupId *string `required:"false"`
// 列表起始位置偏移量默认为0
Offset *int `required:"false"`
// 返回数据长度默认为20最大100
Limit *int `required:"false"`
}
// DescribeIsolationGroupResponse is response schema for DescribeIsolationGroup action
type DescribeIsolationGroupResponse struct {
response.CommonBase
// 硬件隔离组集合。参见数据结构IsolationGroup。
IsolationGroupSet []IsolationGroup
}
// NewDescribeIsolationGroupRequest will create request of DescribeIsolationGroup action.
func (c *UHostClient) NewDescribeIsolationGroupRequest() *DescribeIsolationGroupRequest {
req := &DescribeIsolationGroupRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DescribeIsolationGroup - 查询硬件隔离组列表。
func (c *UHostClient) DescribeIsolationGroup(req *DescribeIsolationGroupRequest) (*DescribeIsolationGroupResponse, error) {
var err error
var res DescribeIsolationGroupResponse
err = c.Client.InvokeAction("DescribeIsolationGroup", req, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,62 @@
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
//go:generate ucloud-gen-go-api UHost LeaveIsolationGroup
package uhost
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// LeaveIsolationGroupRequest is request schema for LeaveIsolationGroup action
type LeaveIsolationGroupRequest struct {
request.CommonBase
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// [公共参数] 可用区信息
// Zone *string `required:"false"`
// [公共参数] 项目id
// ProjectId *string `required:"false"`
// 硬件隔离组id
GroupId *string `required:"true"`
// 主机id
UHostId *string `required:"true"`
}
// LeaveIsolationGroupResponse is response schema for LeaveIsolationGroup action
type LeaveIsolationGroupResponse struct {
response.CommonBase
// 主机id
UHostId string
}
// NewLeaveIsolationGroupRequest will create request of LeaveIsolationGroup action.
func (c *UHostClient) NewLeaveIsolationGroupRequest() *LeaveIsolationGroupRequest {
req := &LeaveIsolationGroupRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// LeaveIsolationGroup - 移除硬件隔离组中的主机
func (c *UHostClient) LeaveIsolationGroup(req *LeaveIsolationGroupRequest) (*LeaveIsolationGroupResponse, error) {
var err error
var res LeaveIsolationGroupResponse
err = c.Client.InvokeAction("LeaveIsolationGroup", req, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,22 @@
package uhost
/*
IsolationGroup - 硬件隔离组信息
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn for detail.
*/
type IsolationGroup struct {
// 硬件隔离组名称
GroupName string
// 硬件隔离组id
GroupId string
// 每个可用区中的机器数量。参见数据结构SpreadInfo。
SpreadInfoSet []SpreadInfo
// 备注
Remark string
}

View File

@ -0,0 +1,16 @@
package uhost
/*
SpreadInfo - 每个可用区中硬件隔离组信息
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn for detail.
*/
type SpreadInfo struct {
// 可用区信息
Zone string
// 可用区中硬件隔离组中云主机的数量不超过7。
UHostCount int
}

View File

@ -1,3 +1,5 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package unet
import (
@ -12,7 +14,8 @@ type UNetClient struct {
// NewClient will return a instance of UNetClient
func NewClient(config *ucloud.Config, credential *auth.Credential) *UNetClient {
client := ucloud.NewClient(config, credential)
meta := ucloud.ClientMeta{Product: "UNet"}
client := ucloud.NewClientWithMeta(config, credential, meta)
return &UNetClient{
client,
}

View File

@ -1,5 +1,4 @@
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
//go:generate ucloud-gen-go-api UNet DescribeVIP
// Code is generated by ucloud-model, DO NOT EDIT IT.
package unet
@ -12,17 +11,17 @@ import (
type DescribeVIPRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// [公共参数] 可用区。参见 [可用区列表](../summary/regionlist.html)
// Zone *string `required:"false"`
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// vpc的id,指定SubnetId时必填
VPCId *string `required:"false"`
// 业务组
BusinessId *string `required:"false"`
// 子网id不指定则获取VPCId下的所有vip
SubnetId *string `required:"false"`
@ -30,22 +29,25 @@ type DescribeVIPRequest struct {
// 业务组名称, 默认为 Default
Tag *string `required:"false"`
// 业务组
BusinessId *string `required:"false"`
// VIP ID
VIPId *string `required:"false"`
// vpc的id,指定SubnetId时必填
VPCId *string `required:"false"`
}
// DescribeVIPResponse is response schema for DescribeVIP action
type DescribeVIPResponse struct {
response.CommonBase
// 内网VIP详情请见VIPDetailSet
VIPSet []VIPDetailSet
// 内网VIP地址列表
DataSet []string
// vip数量
TotalCount int
// 内网VIP详情请见VIPDetailSet
VIPSet []VIPDetailSet
}
// NewDescribeVIPRequest will create request of DescribeVIP action.
@ -65,7 +67,9 @@ func (c *UNetClient) DescribeVIP(req *DescribeVIPRequest) (*DescribeVIPResponse,
var err error
var res DescribeVIPResponse
err = c.Client.InvokeAction("DescribeVIP", req, &res)
reqCopier := *req
err = c.Client.InvokeAction("DescribeVIP", &reqCopier, &res)
if err != nil {
return &res, err
}

View File

@ -1,34 +1,42 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package unet
/*
VIPDetailSet - VIPDetailSet
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn for detail.
you can also see https://docs.ucloud.cn/api for detail.
*/
type VIPDetailSet struct {
// 地域
Zone string
// 虚拟ip id
VIPId string
// 创建时间
CreateTime int
// VIP名称
Name string
// 真实主机ip
RealIp string
// 虚拟ip
VIP string
// VIP备注
Remark string
// 子网id
SubnetId string
// VIP所属业务组
Tag string
// 虚拟ip
VIP string
// 虚拟ip id
VIPId string
// VPC id
VPCId string
// Virtual IP 名称
Name string
// 地域
Zone string
}

View File

@ -0,0 +1,63 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package unet
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// UpdateVIPAttributeRequest is request schema for UpdateVIPAttribute action
type UpdateVIPAttributeRequest struct {
request.CommonBase
// [公共参数] 项目ID。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 内网VIP的名称
Name *string `required:"false"`
// 内网VIP的备注
Remark *string `required:"false"`
// 内网VIP所属的业务组
Tag *string `required:"false"`
// 内网VIP的资源Id
VIPId *string `required:"true"`
}
// UpdateVIPAttributeResponse is response schema for UpdateVIPAttribute action
type UpdateVIPAttributeResponse struct {
response.CommonBase
}
// NewUpdateVIPAttributeRequest will create request of UpdateVIPAttribute action.
func (c *UNetClient) NewUpdateVIPAttributeRequest() *UpdateVIPAttributeRequest {
req := &UpdateVIPAttributeRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// UpdateVIPAttribute - 更新VIP信息
func (c *UNetClient) UpdateVIPAttribute(req *UpdateVIPAttributeRequest) (*UpdateVIPAttributeResponse, error) {
var err error
var res UpdateVIPAttributeResponse
reqCopier := *req
err = c.Client.InvokeAction("UpdateVIPAttribute", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// AddWhiteListResourceRequest is request schema for AddWhiteListResource action
type AddWhiteListResourceRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// 可添加白名单的资源Id
ResourceIds []string `required:"true"`
}
// AddWhiteListResourceResponse is response schema for AddWhiteListResource action
type AddWhiteListResourceResponse struct {
response.CommonBase
}
// NewAddWhiteListResourceRequest will create request of AddWhiteListResource action.
func (c *VPCClient) NewAddWhiteListResourceRequest() *AddWhiteListResourceRequest {
req := &AddWhiteListResourceRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(false)
return req
}
// AddWhiteListResource - 添加NAT网关白名单
func (c *VPCClient) AddWhiteListResource(req *AddWhiteListResourceRequest) (*AddWhiteListResourceResponse, error) {
var err error
var res AddWhiteListResourceResponse
reqCopier := *req
err = c.Client.InvokeAction("AddWhiteListResource", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -1,3 +1,5 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
@ -5,14 +7,15 @@ import (
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
)
// VPCClient is the client of VPC2.0
// VPCClient is the client of VPC
type VPCClient struct {
*ucloud.Client
}
// NewClient will return a instance of VPCClient
func NewClient(config *ucloud.Config, credential *auth.Credential) *VPCClient {
client := ucloud.NewClient(config, credential)
meta := ucloud.ClientMeta{Product: "VPC2.0"}
client := ucloud.NewClientWithMeta(config, credential, meta)
return &VPCClient{
client,
}

View File

@ -0,0 +1,78 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// CreateNATGWRequest is request schema for CreateNATGW action
type CreateNATGWRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关绑定的EIPId
EIPIds []string `required:"true"`
// NAT网关绑定的防火墙Id
FirewallId *string `required:"true"`
// 白名单开关标记。0表示关闭1表示开启。默认为0
IfOpen *int `required:"false"`
// NAT网关名称
NATGWName *string `required:"true"`
// 备注。默认为空
Remark *string `required:"false"`
// NAT网关绑定的子网Id
SubnetworkIds []string `required:"true"`
// 业务组。默认为空
Tag *string `required:"false"`
// NAT网关所属的VPC Id。默认为Default VPC Id
VPCId *string `required:"false"`
}
// CreateNATGWResponse is response schema for CreateNATGW action
type CreateNATGWResponse struct {
response.CommonBase
// 申请到的NATGateWay Id
NATGWId string
}
// NewCreateNATGWRequest will create request of CreateNATGW action.
func (c *VPCClient) NewCreateNATGWRequest() *CreateNATGWRequest {
req := &CreateNATGWRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(false)
return req
}
// CreateNATGW - 创建NAT网关
func (c *VPCClient) CreateNATGW(req *CreateNATGWRequest) (*CreateNATGWResponse, error) {
var err error
var res CreateNATGWResponse
reqCopier := *req
err = c.Client.InvokeAction("CreateNATGW", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,75 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// CreateNATGWPolicyRequest is request schema for CreateNATGWPolicy action
type CreateNATGWPolicyRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 目标IP。填写对应的目标IP地址
DstIP *string `required:"true"`
// 目标端口。可填写固定端口也可填写端口范围。支持的端口范围为1-65535
DstPort *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// 转发策略名称。默认为空
PolicyName *string `required:"false"`
// 协议类型。枚举值为TCP、UDP
Protocol *string `required:"true"`
// 源IP。填写对应的EIP Id
SrcEIPId *string `required:"true"`
// 源端口。可填写固定端口也可填写端口范围。支持的端口范围为1-65535
SrcPort *string `required:"true"`
}
// CreateNATGWPolicyResponse is response schema for CreateNATGWPolicy action
type CreateNATGWPolicyResponse struct {
response.CommonBase
// 创建时分配的策略Id
PolicyId string
}
// NewCreateNATGWPolicyRequest will create request of CreateNATGWPolicy action.
func (c *VPCClient) NewCreateNATGWPolicyRequest() *CreateNATGWPolicyRequest {
req := &CreateNATGWPolicyRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(false)
return req
}
// CreateNATGWPolicy - 添加NAT网关端口转发规则
func (c *VPCClient) CreateNATGWPolicy(req *CreateNATGWPolicyRequest) (*CreateNATGWPolicyResponse, error) {
var err error
var res CreateNATGWPolicyResponse
reqCopier := *req
err = c.Client.InvokeAction("CreateNATGWPolicy", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DeleteNATGWRequest is request schema for DeleteNATGW action
type DeleteNATGWRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// 是否释放绑定的EIP。true解绑并释放false只解绑不释放。默认为false
ReleaseEip *bool `required:"false"`
}
// DeleteNATGWResponse is response schema for DeleteNATGW action
type DeleteNATGWResponse struct {
response.CommonBase
}
// NewDeleteNATGWRequest will create request of DeleteNATGW action.
func (c *VPCClient) NewDeleteNATGWRequest() *DeleteNATGWRequest {
req := &DeleteNATGWRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DeleteNATGW - 删除NAT网关
func (c *VPCClient) DeleteNATGW(req *DeleteNATGWRequest) (*DeleteNATGWResponse, error) {
var err error
var res DeleteNATGWResponse
reqCopier := *req
err = c.Client.InvokeAction("DeleteNATGW", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DeleteNATGWPolicyRequest is request schema for DeleteNATGWPolicy action
type DeleteNATGWPolicyRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// 端口转发规则Id
PolicyId *string `required:"true"`
}
// DeleteNATGWPolicyResponse is response schema for DeleteNATGWPolicy action
type DeleteNATGWPolicyResponse struct {
response.CommonBase
}
// NewDeleteNATGWPolicyRequest will create request of DeleteNATGWPolicy action.
func (c *VPCClient) NewDeleteNATGWPolicyRequest() *DeleteNATGWPolicyRequest {
req := &DeleteNATGWPolicyRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DeleteNATGWPolicy - 删除NAT网关端口转发规则
func (c *VPCClient) DeleteNATGWPolicy(req *DeleteNATGWPolicyRequest) (*DeleteNATGWPolicyResponse, error) {
var err error
var res DeleteNATGWPolicyResponse
reqCopier := *req
err = c.Client.InvokeAction("DeleteNATGWPolicy", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DeleteWhiteListResourceRequest is request schema for DeleteWhiteListResource action
type DeleteWhiteListResourceRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// 删除白名单的资源Id
ResourceIds []string `required:"true"`
}
// DeleteWhiteListResourceResponse is response schema for DeleteWhiteListResource action
type DeleteWhiteListResourceResponse struct {
response.CommonBase
}
// NewDeleteWhiteListResourceRequest will create request of DeleteWhiteListResource action.
func (c *VPCClient) NewDeleteWhiteListResourceRequest() *DeleteWhiteListResourceRequest {
req := &DeleteWhiteListResourceRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DeleteWhiteListResource - 删除NAT网关白名单列表
func (c *VPCClient) DeleteWhiteListResource(req *DeleteWhiteListResourceRequest) (*DeleteWhiteListResourceResponse, error) {
var err error
var res DeleteWhiteListResourceResponse
reqCopier := *req
err = c.Client.InvokeAction("DeleteWhiteListResource", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,66 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DescribeNATGWRequest is request schema for DescribeNATGW action
type DescribeNATGWRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 数据分页值。默认为20
Limit *int `required:"false"`
// NAT网关Id。默认为该项目下所有NAT网关
NATGWIds []string `required:"false"`
// 数据偏移量。默认为0
Offset *int `required:"false"`
}
// DescribeNATGWResponse is response schema for DescribeNATGW action
type DescribeNATGWResponse struct {
response.CommonBase
// 查到的NATGW信息列表
DataSet []NatGatewayDataSet
// 满足条件的实例的总数
TotalCount int
}
// NewDescribeNATGWRequest will create request of DescribeNATGW action.
func (c *VPCClient) NewDescribeNATGWRequest() *DescribeNATGWRequest {
req := &DescribeNATGWRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DescribeNATGW - 获取NAT网关信息
func (c *VPCClient) DescribeNATGW(req *DescribeNATGWRequest) (*DescribeNATGWResponse, error) {
var err error
var res DescribeNATGWResponse
reqCopier := *req
err = c.Client.InvokeAction("DescribeNATGW", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,66 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DescribeNATGWPolicyRequest is request schema for DescribeNATGWPolicy action
type DescribeNATGWPolicyRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 返回数据长度默认为10000
Limit *int `required:"false"`
// NAT网关Id
NATGWId *string `required:"true"`
// 列表起始位置偏移量默认为0
Offset *int `required:"false"`
}
// DescribeNATGWPolicyResponse is response schema for DescribeNATGWPolicy action
type DescribeNATGWPolicyResponse struct {
response.CommonBase
// 查到的NATGW 转发策略的详细信息
DataSet []NATGWPolicyDataSet
// 满足条件的转发策略总数
TotalCount int
}
// NewDescribeNATGWPolicyRequest will create request of DescribeNATGWPolicy action.
func (c *VPCClient) NewDescribeNATGWPolicyRequest() *DescribeNATGWPolicyRequest {
req := &DescribeNATGWPolicyRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DescribeNATGWPolicy - 展示NAT网关端口转发规则
func (c *VPCClient) DescribeNATGWPolicy(req *DescribeNATGWPolicyRequest) (*DescribeNATGWPolicyResponse, error) {
var err error
var res DescribeNATGWPolicyResponse
reqCopier := *req
err = c.Client.InvokeAction("DescribeNATGWPolicy", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,60 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// DescribeWhiteListResourceRequest is request schema for DescribeWhiteListResource action
type DescribeWhiteListResourceRequest struct {
request.CommonBase
// [公共参数] 项目id
// ProjectId *string `required:"true"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关的Id
NATGWIds []string `required:"true"`
}
// DescribeWhiteListResourceResponse is response schema for DescribeWhiteListResource action
type DescribeWhiteListResourceResponse struct {
response.CommonBase
// 白名单资源的详细信息详见DescribeResourceWhiteListDataSet
DataSet []NatGWWhitelistDataSet
// 上述DataSet总数量
TotalCount int
}
// NewDescribeWhiteListResourceRequest will create request of DescribeWhiteListResource action.
func (c *VPCClient) NewDescribeWhiteListResourceRequest() *DescribeWhiteListResourceRequest {
req := &DescribeWhiteListResourceRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// DescribeWhiteListResource - 展示NAT网关白名单资源列表
func (c *VPCClient) DescribeWhiteListResource(req *DescribeWhiteListResourceRequest) (*DescribeWhiteListResourceResponse, error) {
var err error
var res DescribeWhiteListResourceResponse
reqCopier := *req
err = c.Client.InvokeAction("DescribeWhiteListResource", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// EnableWhiteListRequest is request schema for EnableWhiteList action
type EnableWhiteListRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 白名单开关标记。0关闭1开启。默认为0
IfOpen *int `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
}
// EnableWhiteListResponse is response schema for EnableWhiteList action
type EnableWhiteListResponse struct {
response.CommonBase
}
// NewEnableWhiteListRequest will create request of EnableWhiteList action.
func (c *VPCClient) NewEnableWhiteListRequest() *EnableWhiteListRequest {
req := &EnableWhiteListRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// EnableWhiteList - 修改NAT网关白名单开关
func (c *VPCClient) EnableWhiteList(req *EnableWhiteListRequest) (*EnableWhiteListResponse, error) {
var err error
var res EnableWhiteListResponse
reqCopier := *req
err = c.Client.InvokeAction("EnableWhiteList", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,63 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// GetAvailableResourceForPolicyRequest is request schema for GetAvailableResourceForPolicy action
type GetAvailableResourceForPolicyRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 返回数据长度默认为10000
Limit *int `required:"false"`
// NAT网关Id
NATGWId *string `required:"true"`
// 列表起始位置偏移量默认为0
Offset *int `required:"false"`
}
// GetAvailableResourceForPolicyResponse is response schema for GetAvailableResourceForPolicy action
type GetAvailableResourceForPolicyResponse struct {
response.CommonBase
// 支持资源类型的信息
DataSet []GetAvailableResourceForPolicyDataSet
}
// NewGetAvailableResourceForPolicyRequest will create request of GetAvailableResourceForPolicy action.
func (c *VPCClient) NewGetAvailableResourceForPolicyRequest() *GetAvailableResourceForPolicyRequest {
req := &GetAvailableResourceForPolicyRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// GetAvailableResourceForPolicy - 获取NAT网关可配置端口转发规则的资源信息
func (c *VPCClient) GetAvailableResourceForPolicy(req *GetAvailableResourceForPolicyRequest) (*GetAvailableResourceForPolicyResponse, error) {
var err error
var res GetAvailableResourceForPolicyResponse
reqCopier := *req
err = c.Client.InvokeAction("GetAvailableResourceForPolicy", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,60 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// GetAvailableResourceForWhiteListRequest is request schema for GetAvailableResourceForWhiteList action
type GetAvailableResourceForWhiteListRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
}
// GetAvailableResourceForWhiteListResponse is response schema for GetAvailableResourceForWhiteList action
type GetAvailableResourceForWhiteListResponse struct {
response.CommonBase
// 返回白名单列表的详细信息
DataSet []GetAvailableResourceForWhiteListDataSet
// 白名单资源列表的总的个数
TotalCount int
}
// NewGetAvailableResourceForWhiteListRequest will create request of GetAvailableResourceForWhiteList action.
func (c *VPCClient) NewGetAvailableResourceForWhiteListRequest() *GetAvailableResourceForWhiteListRequest {
req := &GetAvailableResourceForWhiteListRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// GetAvailableResourceForWhiteList - 获取NAT网关可添加白名单的资源
func (c *VPCClient) GetAvailableResourceForWhiteList(req *GetAvailableResourceForWhiteListRequest) (*GetAvailableResourceForWhiteListResponse, error) {
var err error
var res GetAvailableResourceForWhiteListResponse
reqCopier := *req
err = c.Client.InvokeAction("GetAvailableResourceForWhiteList", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// ListSubnetForNATGWRequest is request schema for ListSubnetForNATGW action
type ListSubnetForNATGWRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关所属VPC Id。默认值为Default VPC Id
VPCId *string `required:"false"`
}
// ListSubnetForNATGWResponse is response schema for ListSubnetForNATGW action
type ListSubnetForNATGWResponse struct {
response.CommonBase
// 具体参数请见NatgwSubnetDataSet
DataSet []NatgwSubnetDataSet
}
// NewListSubnetForNATGWRequest will create request of ListSubnetForNATGW action.
func (c *VPCClient) NewListSubnetForNATGWRequest() *ListSubnetForNATGWRequest {
req := &ListSubnetForNATGWRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// ListSubnetForNATGW - 展示NAT网关可绑定的子网列表
func (c *VPCClient) ListSubnetForNATGW(req *ListSubnetForNATGWRequest) (*ListSubnetForNATGWResponse, error) {
var err error
var res ListSubnetForNATGWResponse
reqCopier := *req
err = c.Client.InvokeAction("ListSubnetForNATGW", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,60 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// SetGwDefaultExportRequest is request schema for SetGwDefaultExport action
type SetGwDefaultExportRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关绑定的EIP Id。ExportIp和ExportEipId必填一个
ExportEipId *string `required:"false"`
// NAT网关绑定的EIP。ExportIp和ExportEipId必填一个
ExportIp *string `required:"false"`
// NAT网关Id
NATGWId *string `required:"true"`
}
// SetGwDefaultExportResponse is response schema for SetGwDefaultExport action
type SetGwDefaultExportResponse struct {
response.CommonBase
}
// NewSetGwDefaultExportRequest will create request of SetGwDefaultExport action.
func (c *VPCClient) NewSetGwDefaultExportRequest() *SetGwDefaultExportRequest {
req := &SetGwDefaultExportRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// SetGwDefaultExport - 设置NAT网关的默认出口
func (c *VPCClient) SetGwDefaultExport(req *SetGwDefaultExportRequest) (*SetGwDefaultExportResponse, error) {
var err error
var res SetGwDefaultExportResponse
reqCopier := *req
err = c.Client.InvokeAction("SetGwDefaultExport", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,39 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
DescribeWhiteListResourceObjectIPInfo - DescribeWhiteListResource
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type DescribeWhiteListResourceObjectIPInfo struct {
// natgw字符串
GwType string
// 白名单资源的内网IP
PrivateIP string
// 白名单资源Id信息
ResourceId string
// 白名单资源名称
ResourceName string
// 白名单资源类型
ResourceType string
// 资源绑定的虚拟网卡的实例ID
SubResourceId string
// 资源绑定的虚拟网卡的实例名称
SubResourceName string
// 资源绑定的虚拟网卡的类型
SubResourceType string
// 白名单资源所属VPCId
VPCId string
}

View File

@ -0,0 +1,21 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
GetAvailableResourceForPolicyDataSet - GetAvailableResourceForPolicy
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type GetAvailableResourceForPolicyDataSet struct {
// 资源对应的内网Ip
PrivateIP string
// 资源的Id
ResourceId string
// 资源类型。"uhost":云主机; "upm",物理云主机; "hadoophost"hadoop节点 "fortresshost":堡垒机: "udockhost",容器
ResourceType string
}

View File

@ -0,0 +1,39 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
GetAvailableResourceForWhiteListDataSet - GetAvailableResourceForWhiteList
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type GetAvailableResourceForWhiteListDataSet struct {
// 资源的内网Ip
PrivateIP string
// 资源类型Id
ResourceId string
// 资源名称
ResourceName string
// 资源类型。"uhost":云主机; "upm",物理云主机; "hadoophost"hadoop节点 "fortresshost":堡垒机: "udockhost",容器
ResourceType string
// 资源绑定的虚拟网卡的实例ID
SubResouceId string
// 资源绑定的虚拟网卡的实例类型
SubResouceType string
// 资源绑定的虚拟网卡的实例名称
SubResourceName string
// 资源所属子网Id
SubnetworkId string
// 资源所属VPCId
VPCId string
}

View File

@ -0,0 +1,45 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NatGatewayDataSet - natgw的信息
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NatGatewayDataSet struct {
// natgw创建时间
CreateTime int
// 绑定的防火墙Id
FirewallId string
// 绑定的EIP 信息
IPSet []NatGatewayIPSet
// natgw id
NATGWId string
// natgw名称
NATGWName string
// 转发策略Id
PolicyId []string
// 备注
Remark string
// 子网 Id
SubnetSet []NatGatewaySubnetSet
// 业务组
Tag string
// 所属VPC Id
VPCId string
// 所属VPC 信息
VPCInfo string
}

View File

@ -0,0 +1,27 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NatGatewayIPSet - IPSet信息
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NatGatewayIPSet struct {
// 带宽
Bandwidth int
// EIP带宽类型
BandwidthType string
// 外网IP的 EIPId
EIPId string
// 外网IP信息
IPResInfo []NatGWIPResInfo
// 权重为100的为出口
Weight int
}

View File

@ -0,0 +1,21 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NatGatewaySubnetSet - natgw里面的子网信息
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NatGatewaySubnetSet struct {
// 子网网段
Subnet string
// 子网名字
SubnetName string
// 子网id
SubnetworkId string
}

View File

@ -0,0 +1,18 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NatGWIPResInfo - IP信息
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NatGWIPResInfo struct {
// 外网IP
EIP string
// IP的运营商信息
OperatorName string
}

View File

@ -0,0 +1,21 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NatGWWhitelistDataSet - nat网关白名单数据
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NatGWWhitelistDataSet struct {
// 白名单开关标记
IfOpen int
// NATGateWay Id
NATGWId string
// 白名单详情
ObjectIPInfo []DescribeWhiteListResourceObjectIPInfo
}

View File

@ -0,0 +1,39 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NATGWPolicyDataSet - DescribeNATGWPolicy
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NATGWPolicyDataSet struct {
// 目的地址
DstIP string
// 目的端口
DstPort string
// NAT网关Id
NATGWId string
// 转发策略Id
PolicyId string
// 转发策略名称
PolicyName string
// 协议类型
Protocol string
// 端口转发前端EIP
SrcEIP string
// 端口转发前端EIP Id
SrcEIPId string
// 源端口
SrcPort string
}

View File

@ -0,0 +1,27 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
/*
NatgwSubnetDataSet - natgw可以绑定的子网
this model is auto created by ucloud code generater for open api,
you can also see https://docs.ucloud.cn/api for detail.
*/
type NatgwSubnetDataSet struct {
// 是否绑定NATGW
HasNATGW bool
// 掩码
Netmask string
// 子网网段
Subnet string
// 子网id
SubnetId string
// 子网名字
SubnetName string
}

View File

@ -0,0 +1,75 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// UpdateNATGWPolicyRequest is request schema for UpdateNATGWPolicy action
type UpdateNATGWPolicyRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// 目标IP。填写对饮的目标IP地址
DstIP *string `required:"true"`
// 目标端口。可填写固定端口也可填写端口范围。支持的端口范围为1-65535
DstPort *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// 转发策略Id
PolicyId *string `required:"true"`
// 转发策略名称。默认为空
PolicyName *string `required:"false"`
// 协议类型。枚举值为TCP 、 UDP
Protocol *string `required:"true"`
// 源IP。填写对应的EIP Id
SrcEIPId *string `required:"true"`
// 源端口。可填写固定端口也可填写端口范围。支持的端口范围为1-6553
SrcPort *string `required:"true"`
}
// UpdateNATGWPolicyResponse is response schema for UpdateNATGWPolicy action
type UpdateNATGWPolicyResponse struct {
response.CommonBase
}
// NewUpdateNATGWPolicyRequest will create request of UpdateNATGWPolicy action.
func (c *VPCClient) NewUpdateNATGWPolicyRequest() *UpdateNATGWPolicyRequest {
req := &UpdateNATGWPolicyRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// UpdateNATGWPolicy - 更新NAT网关端口转发规则
func (c *VPCClient) UpdateNATGWPolicy(req *UpdateNATGWPolicyRequest) (*UpdateNATGWPolicyResponse, error) {
var err error
var res UpdateNATGWPolicyResponse
reqCopier := *req
err = c.Client.InvokeAction("UpdateNATGWPolicy", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -0,0 +1,57 @@
// Code is generated by ucloud-model, DO NOT EDIT IT.
package vpc
import (
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
// UpdateNATGWSubnetRequest is request schema for UpdateNATGWSubnet action
type UpdateNATGWSubnetRequest struct {
request.CommonBase
// [公共参数] 项目Id。不填写为默认项目子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
// ProjectId *string `required:"false"`
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
// Region *string `required:"true"`
// NAT网关Id
NATGWId *string `required:"true"`
// NAT网关绑定的子网Id
SubnetworkIds []string `required:"true"`
}
// UpdateNATGWSubnetResponse is response schema for UpdateNATGWSubnet action
type UpdateNATGWSubnetResponse struct {
response.CommonBase
}
// NewUpdateNATGWSubnetRequest will create request of UpdateNATGWSubnet action.
func (c *VPCClient) NewUpdateNATGWSubnetRequest() *UpdateNATGWSubnetRequest {
req := &UpdateNATGWSubnetRequest{}
// setup request with client config
c.Client.SetupRequest(req)
// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}
// UpdateNATGWSubnet - 更新NAT网关绑定的子网
func (c *VPCClient) UpdateNATGWSubnet(req *UpdateNATGWSubnetRequest) (*UpdateNATGWSubnetResponse, error) {
var err error
var res UpdateNATGWSubnetResponse
reqCopier := *req
err = c.Client.InvokeAction("UpdateNATGWSubnet", &reqCopier, &res)
if err != nil {
return &res, err
}
return &res, nil
}

View File

@ -9,13 +9,23 @@ import (
"io"
"net/url"
"sort"
"strings"
"time"
)
// Credential is the information of credential keys
type Credential struct {
PublicKey string
// UCloud Public Key
PublicKey string
// UCloud Private Key
PrivateKey string
// UCloud STS token for temporary usage
SecurityToken string
// Time the credentials will expire.
CanExpire bool
Expires time.Time
}
// NewCredential will return credential config with default values
@ -25,32 +35,51 @@ func NewCredential() Credential {
// CreateSign will encode query string to credential signature.
func (c *Credential) CreateSign(query string) string {
// replace "=" "&"
str := strings.Replace(query, "&", "", -1)
str = strings.Replace(str, "=", "", -1)
// crypto by SHA1
strUnescaped, _ := url.QueryUnescape(str)
h := sha1.New()
s := strUnescaped + c.PrivateKey
io.WriteString(h, s)
bs := h.Sum(nil)
result := hex.EncodeToString(bs)
return result
urlValues, err := url.ParseQuery(query)
if err != nil {
return ""
}
urlValues.Set("PublicKey", c.PublicKey)
return c.verifyAc(urlValues)
}
// BuildCredentialedQuery will build query string with signature query param.
func (c *Credential) BuildCredentialedQuery(query map[string]string) string {
var queryList []string
for k, v := range query {
queryList = append(queryList, k+"="+url.QueryEscape(v))
func (c *Credential) BuildCredentialedQuery(params map[string]string) string {
urlValues := url.Values{}
for k, v := range params {
urlValues.Set(k, v)
}
queryList = append(queryList, "PublicKey="+url.QueryEscape(c.PublicKey))
sort.Strings(queryList)
queryString := strings.Join(queryList, "&")
sign := c.CreateSign(queryString)
queryString = queryString + "&Signature=" + sign
return queryString
if len(c.SecurityToken) != 0 {
urlValues.Set("SecurityToken", c.SecurityToken)
}
urlValues.Set("PublicKey", c.PublicKey)
urlValues.Set("Signature", c.verifyAc(urlValues))
return urlValues.Encode()
}
func (c *Credential) IsExpired() bool {
return c.CanExpire && time.Now().After(c.Expires)
}
func (c *Credential) verifyAc(urlValues url.Values) string {
// sort keys
var keys []string
for k := range urlValues {
keys = append(keys, k)
}
sort.Strings(keys)
signQuery := ""
for _, k := range keys {
signQuery += k + urlValues.Get(k)
}
signQuery += c.PrivateKey
return encodeSha1(signQuery)
}
func encodeSha1(s string) string {
h := sha1.New()
_, _ = io.WriteString(h, s)
bs := h.Sum(nil)
return hex.EncodeToString(bs)
}

View File

@ -4,6 +4,7 @@ Package ucloud is a package of utilities to setup ucloud sdk and improve using e
package ucloud
import (
"fmt"
"time"
"github.com/ucloud/ucloud-sdk-go/private/utils"
@ -16,6 +17,10 @@ import (
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
)
type ClientMeta struct {
Product string
}
// Client 客户端
type Client struct {
// configurations
@ -31,6 +36,9 @@ type Client struct {
httpRequestHandlers []HttpRequestHandler
responseHandlers []ResponseHandler
httpResponseHandlers []HttpResponseHandler
// client information injection
meta ClientMeta
}
// NewClient will create an client of ucloud sdk
@ -38,6 +46,7 @@ func NewClient(config *Config, credential *auth.Credential) *Client {
client := Client{
credential: credential,
config: config,
meta: ClientMeta{},
}
client.requestHandlers = append(client.requestHandlers, defaultRequestHandlers...)
@ -51,13 +60,19 @@ func NewClient(config *Config, credential *auth.Credential) *Client {
return &client
}
func NewClientWithMeta(config *Config, credential *auth.Credential, meta ClientMeta) *Client {
client := NewClient(config, credential)
client.meta = meta
return client
}
// SetHttpClient will setup a http client
func (c *Client) SetHttpClient(httpClient http.Client) error {
c.httpClient = httpClient
return nil
}
// GetCredential will return the creadential config of client.
// GetCredential will return the credential config of client.
func (c *Client) GetCredential() *auth.Credential {
return c.credential
}
@ -67,6 +82,11 @@ func (c *Client) GetConfig() *Config {
return c.config
}
// GetMeta will return the meta data of client.
func (c *Client) GetMeta() ClientMeta {
return c.meta
}
// SetLogger will set the logger of client
func (c *Client) SetLogger(logger log.Logger) {
c.logger = logger
@ -89,6 +109,13 @@ func (c *Client) InvokeActionWithPatcher(action string, req request.Common, resp
req.SetRequestTime(time.Now())
resp.SetRequest(req)
if c.credential.CanExpire && c.credential.IsExpired() {
return uerr.NewClientError(
uerr.ErrCredentialExpired,
fmt.Errorf("credential is expired at %s", c.credential.Expires.Format(time.RFC3339)),
)
}
for _, handler := range c.requestHandlers {
req, err = handler(c, req)
if err != nil {
@ -123,7 +150,7 @@ func (c *Client) InvokeActionWithPatcher(action string, req request.Common, resp
if err == nil {
// use patch object to resolve the http response body
// in general, it will be fix common server error before server bugfix is released.
// in general, it will be fix common server error before server bug fix is released.
body := httpResp.GetBody()
for _, patch := range patches {
@ -131,6 +158,9 @@ func (c *Client) InvokeActionWithPatcher(action string, req request.Common, resp
}
err = c.unmarshalHTTPResponse(body, resp)
uuid := httpResp.GetHeaders().Get(headerKeyRequestUUID)
resp.SetRequestUUID(uuid)
}
// use response middle to build and convert response when response has been created.

View File

@ -4,8 +4,14 @@ import (
"time"
"github.com/ucloud/ucloud-sdk-go/ucloud/log"
"github.com/ucloud/ucloud-sdk-go/ucloud/version"
)
// Version is the version of sdk
const Version = version.Version
const headerKeyRequestUUID = "X-UCLOUD-REQUEST-UUID"
// Config is the config of ucloud sdk, use for setting up client
type Config struct {
// Region is the region of backend service

View File

@ -20,6 +20,8 @@ var (
// ErrUnexpected is the error for any unexpected error
ErrUnexpected = "client.UnexpectedError"
ErrCredentialExpired = "client.CredentialExpiredError"
)
// ClientError is the ucloud common errorfor server response

View File

@ -59,7 +59,6 @@ type CommonBase struct {
retryCount int
timeout time.Duration
requestTime time.Time
requestUUID string
}
// SetRetryCount will set retry count of request

View File

@ -1,12 +1,18 @@
package request
import (
"encoding/base64"
"errors"
"fmt"
"reflect"
"strconv"
)
// ToBase64Query will encode a wrapped string as base64 wrapped string
func ToBase64Query(s *string) *string {
return String(base64.StdEncoding.EncodeToString([]byte(StringValue(s))))
}
// ToQueryMap will convert a request to string map
func ToQueryMap(req Common) (map[string]string, error) {
v := reflect.ValueOf(req)

View File

@ -0,0 +1,70 @@
package request
import (
"time"
)
// String will return a pointer to string
func String(val string) *string {
return &val
}
// StringValue will return a string from string pointer
func StringValue(ptr *string) string {
if ptr != nil {
return *ptr
}
return ""
}
// Int will return a pointer to int
func Int(val int) *int {
return &val
}
// IntValue will return a int from int pointer
func IntValue(ptr *int) int {
if ptr != nil {
return *ptr
}
return 0
}
// Bool will return a pointer to bool
func Bool(val bool) *bool {
return &val
}
// BoolValue will return a bool from bool pointer
func BoolValue(ptr *bool) bool {
if ptr != nil {
return *ptr
}
return false
}
// Float64 will return a pointer to float64
func Float64(val float64) *float64 {
return &val
}
// Float64Value will return a float64 from float64 pointer
func Float64Value(ptr *float64) float64 {
if ptr != nil {
return *ptr
}
return 0.0
}
// TimeDuration will return a pointer to time.Duration
func TimeDuration(val time.Duration) *time.Duration {
return &val
}
// TimeDurationValue will return a time.Duration from a time.Duration pointer
func TimeDurationValue(ptr *time.Duration) time.Duration {
if ptr != nil {
return *ptr
}
return 0
}

View File

@ -16,6 +16,9 @@ type Common interface {
GetRequest() request.Common
SetRequest(request.Common)
SetRequestUUID(string)
GetRequestUUID() string
}
// CommonBase has common attribute and method,
@ -25,6 +28,8 @@ type CommonBase struct {
RetCode int
Message string
requestUUID string
request request.Common
}
@ -53,3 +58,13 @@ func (c *CommonBase) GetRequest() request.Common {
func (c *CommonBase) SetRequest(req request.Common) {
c.request = req
}
// SetRequestUUID will set uuid of request
func (c *CommonBase) SetRequestUUID(uuid string) {
c.requestUUID = uuid
}
// GetRequestUUID will get uuid of request
func (c *CommonBase) GetRequestUUID() string {
return c.requestUUID
}

View File

@ -1,75 +1,18 @@
package ucloud
import (
"time"
"github.com/ucloud/ucloud-sdk-go/ucloud/version"
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
)
// Version is the version of sdk
const Version = version.Version
// String will return a pointer to string
func String(val string) *string {
return &val
}
// StringValue will return a string from string pointer
func StringValue(ptr *string) string {
if ptr != nil {
return *ptr
}
return ""
}
// Int will return a pointer to int
func Int(val int) *int {
return &val
}
// IntValue will return a int from int pointer
func IntValue(ptr *int) int {
if ptr != nil {
return *ptr
}
return 0
}
// Bool will return a pointer to bool
func Bool(val bool) *bool {
return &val
}
// BoolValue will return a bool from bool pointer
func BoolValue(ptr *bool) bool {
if ptr != nil {
return *ptr
}
return false
}
// Float64 will return a pointer to float64
func Float64(val float64) *float64 {
return &val
}
// Float64Value will return a float64 from float64 pointer
func Float64Value(ptr *float64) float64 {
if ptr != nil {
return *ptr
}
return 0.0
}
// TimeDuration will return a pointer to time.Duration
func TimeDuration(val time.Duration) *time.Duration {
return &val
}
// TimeDurationValue will return a time.Duration from a time.Duration pointer
func TimeDurationValue(ptr *time.Duration) time.Duration {
if ptr != nil {
return *ptr
}
return 0
}
var (
String = request.String
StringValue = request.StringValue
Int = request.Int
IntValue = request.IntValue
Bool = request.Bool
BoolValue = request.BoolValue
Float64 = request.Float64
Float64Value = request.Float64Value
TimeDuration = request.TimeDuration
TimeDurationValue = request.TimeDurationValue
)

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