add ucloud packer
This commit is contained in:
parent
838f2ad0ad
commit
c8bab9b382
2
Makefile
2
Makefile
|
@ -58,7 +58,7 @@ dev: deps ## Build and install a development build
|
|||
fi
|
||||
@mkdir -p pkg/$(GOOS)_$(GOARCH)
|
||||
@mkdir -p bin
|
||||
@go install -ldflags '$(GOLDFLAGS)'
|
||||
@go install -mod=vendor -ldflags '$(GOLDFLAGS)'
|
||||
@cp $(GOPATH)/bin/packer bin/packer
|
||||
@cp $(GOPATH)/bin/packer pkg/$(GOOS)_$(GOARCH)
|
||||
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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/uhost"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/unet"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/vpc"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
|
||||
"os"
|
||||
)
|
||||
|
||||
type AccessConfig struct {
|
||||
PublicKey string `mapstructure:"public_key"`
|
||||
PrivateKey string `mapstructure:"private_key"`
|
||||
Region string `mapstructure:"region"`
|
||||
ProjectId string `mapstructure:"project_id"`
|
||||
|
||||
client *UCloudClient
|
||||
}
|
||||
|
||||
func (c *AccessConfig) Client() (*UCloudClient, error) {
|
||||
if c.client != nil {
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
cfg := ucloud.NewConfig()
|
||||
cfg.Region = c.Region
|
||||
cfg.ProjectId = c.ProjectId
|
||||
cfg.UserAgent = fmt.Sprintf("Packer-UCloud/%s", version.FormattedVersion())
|
||||
|
||||
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)
|
||||
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
var errs []error
|
||||
if err := c.Config(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if c.Region == "" {
|
||||
c.Region = os.Getenv("UCLOUD_REGION")
|
||||
}
|
||||
|
||||
if c.Region == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set", "region"))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) Config() error {
|
||||
if c.PublicKey == "" {
|
||||
c.PublicKey = os.Getenv("UCLOUD_PUBLIC_KEY")
|
||||
}
|
||||
if c.PrivateKey == "" {
|
||||
c.PrivateKey = os.Getenv("UCLOUD_PRIVATE_KEY")
|
||||
}
|
||||
|
||||
if c.ProjectId == "" {
|
||||
c.ProjectId = os.Getenv("UCLOUD_PROJECT_ID")
|
||||
}
|
||||
|
||||
if c.PublicKey == "" || c.PrivateKey == "" || c.ProjectId == "" {
|
||||
return fmt.Errorf("%q, %q, and %q must be set", "public_key", "private_key", "project_id")
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (c *AccessConfig) ValidateRegion(region string) error {
|
||||
|
||||
supportedRegions, err := c.getSupportedRegions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, supportedRegion := range supportedRegions {
|
||||
if region == supportedRegion {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%q is valid, should be an valid ucloud region, got %q", "region", region)
|
||||
}
|
||||
|
||||
func (c *AccessConfig) ValidateZone(region, zone string) error {
|
||||
|
||||
supportedZones, err := c.getSupportedZones(region)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, supportedZone := range supportedZones {
|
||||
if zone == supportedZone {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%q is valid, should be an valid ucloud zone, got %q", "availability_zone", zone)
|
||||
}
|
||||
|
||||
func (c *AccessConfig) getSupportedRegions() ([]string, error) {
|
||||
client, err := c.Client()
|
||||
conn := client.uaccountconn
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := conn.NewGetRegionRequest()
|
||||
resp, err := conn.GetRegion(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validRegions := make([]string, len(resp.Regions))
|
||||
for _, val := range resp.Regions {
|
||||
if !isStringIn(val.Region, validRegions) {
|
||||
validRegions = append(validRegions, val.Region)
|
||||
}
|
||||
}
|
||||
|
||||
return validRegions, nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) getSupportedZones(region string) ([]string, error) {
|
||||
client, err := c.Client()
|
||||
conn := client.uaccountconn
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := conn.NewGetRegionRequest()
|
||||
resp, err := conn.GetRegion(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validZones := make([]string, len(resp.Regions))
|
||||
for _, val := range resp.Regions {
|
||||
if val.Region == region && !isStringIn(val.Zone, validZones) {
|
||||
validZones = append(validZones, val.Zone)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return validZones, nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testAccessConfig() *AccessConfig {
|
||||
return &AccessConfig{
|
||||
PublicKey: "test_pub",
|
||||
PrivateKey: "test_pri",
|
||||
ProjectId: "test_pro",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAccessConfigPrepareRegion(t *testing.T) {
|
||||
c := testAccessConfig()
|
||||
|
||||
c.Region = ""
|
||||
if err := c.Prepare(nil); err == nil {
|
||||
t.Fatalf("should have err")
|
||||
}
|
||||
|
||||
c.Region = "cn-sh2"
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
|
||||
os.Setenv("UCLOUD_REGION", "cn-bj2")
|
||||
c.Region = ""
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"log"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Artifact struct {
|
||||
UCloudImages *imageInfoSet
|
||||
|
||||
BuilderIdValue string
|
||||
|
||||
Client *UCloudClient
|
||||
}
|
||||
|
||||
func (a *Artifact) BuilderId() string {
|
||||
return a.BuilderIdValue
|
||||
}
|
||||
|
||||
func (*Artifact) Files() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Artifact) Id() string {
|
||||
m := make([]string, 0, len(a.UCloudImages.GetAll()))
|
||||
|
||||
for _, v := range a.UCloudImages.GetAll() {
|
||||
m = append(m, fmt.Sprintf("%s:%s:%s", v.ProjectId, v.Region, v.ImageId))
|
||||
}
|
||||
|
||||
sort.Strings(m)
|
||||
return strings.Join(m, ",")
|
||||
}
|
||||
|
||||
func (a *Artifact) String() string {
|
||||
m := make([]string, 0, len(a.UCloudImages.GetAll()))
|
||||
for _, v := range a.UCloudImages.GetAll() {
|
||||
m = append(m, fmt.Sprintf("%s: %s: %s", v.ProjectId, v.Region, v.ImageId))
|
||||
}
|
||||
|
||||
sort.Strings(m)
|
||||
return fmt.Sprintf("UCloud images were created:\n\n%s", strings.Join(m, "\n"))
|
||||
}
|
||||
|
||||
func (a *Artifact) State(name string) interface{} {
|
||||
switch name {
|
||||
case "atlas.artifact.metadata":
|
||||
return a.stateAtlasMetadata()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Artifact) Destroy() error {
|
||||
conn := a.Client.uhostconn
|
||||
errors := make([]error, 0)
|
||||
|
||||
for _, v := range a.UCloudImages.GetAll() {
|
||||
log.Printf("Delete ucloud image %s from %s:%s", v.ImageId, v.ProjectId, v.Region)
|
||||
req := conn.NewTerminateCustomImageRequest()
|
||||
req.ProjectId = ucloud.String(v.ProjectId)
|
||||
req.Region = ucloud.String(v.Region)
|
||||
req.ImageId = ucloud.String(v.ImageId)
|
||||
|
||||
if _, err := conn.TerminateCustomImage(req); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
if len(errors) == 1 {
|
||||
return errors[0]
|
||||
} else {
|
||||
return &packer.MultiError{Errors: errors}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Artifact) stateAtlasMetadata() interface{} {
|
||||
metadata := make(map[string]string)
|
||||
for _, v := range a.UCloudImages.GetAll() {
|
||||
k := fmt.Sprintf("%s:%s", v.ProjectId, v.Region)
|
||||
metadata[k] = v.ImageId
|
||||
}
|
||||
|
||||
return metadata
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestArtifact_Impl(t *testing.T) {
|
||||
var _ packer.Artifact = new(Artifact)
|
||||
}
|
||||
|
||||
func TestArtifactId(t *testing.T) {
|
||||
expected := `project1:region1:foo,project2:region2:bar`
|
||||
|
||||
images := newImageInfoSet(nil)
|
||||
images.Set(imageInfo{
|
||||
Region: "region1",
|
||||
ProjectId: "project1",
|
||||
ImageId: "foo",
|
||||
})
|
||||
|
||||
images.Set(imageInfo{
|
||||
Region: "region2",
|
||||
ProjectId: "project2",
|
||||
ImageId: "bar",
|
||||
})
|
||||
|
||||
a := &Artifact{
|
||||
UCloudImages: images,
|
||||
}
|
||||
|
||||
result := a.Id()
|
||||
if result != expected {
|
||||
t.Fatalf("bad: %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArtifactState_atlasMetadata(t *testing.T) {
|
||||
images := newImageInfoSet(nil)
|
||||
images.Set(imageInfo{
|
||||
Region: "region1",
|
||||
ProjectId: "project1",
|
||||
ImageId: "foo",
|
||||
})
|
||||
|
||||
images.Set(imageInfo{
|
||||
Region: "region2",
|
||||
ProjectId: "project2",
|
||||
ImageId: "bar",
|
||||
})
|
||||
|
||||
a := &Artifact{
|
||||
UCloudImages: images,
|
||||
}
|
||||
|
||||
actual := a.State("atlas.artifact.metadata")
|
||||
expected := map[string]string{
|
||||
"project1:region1": "foo",
|
||||
"project2:region2": "bar",
|
||||
}
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
// The ucloud-uhost contains a packer.Builder implementation that
|
||||
// builds uhost images for UCloud UHost instance.
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/config"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
)
|
||||
|
||||
// The unique ID for this builder
|
||||
const BuilderId = "ucloud.uhost"
|
||||
|
||||
type Config struct {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
AccessConfig `mapstructure:",squash"`
|
||||
ImageConfig `mapstructure:",squash"`
|
||||
RunConfig `mapstructure:",squash"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateContext: &b.config.ctx,
|
||||
InterpolateFilter: &interpolate.RenderFilter{
|
||||
Exclude: []string{
|
||||
"run_command",
|
||||
},
|
||||
},
|
||||
}, raws...)
|
||||
b.config.ctx.EnableEnv = true
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Accumulate any errors
|
||||
var errs *packer.MultiError
|
||||
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.ImageConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
packer.LogSecretFilter.Set(b.config.PublicKey, b.config.PrivateKey)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
|
||||
client, err := b.config.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Setup the state bag and initial state for the steps
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("client", client)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
|
||||
var steps []multistep.Step
|
||||
|
||||
// Build the steps
|
||||
steps = []multistep.Step{
|
||||
&stepPreValidate{
|
||||
Region: b.config.Region,
|
||||
Zone: b.config.Zone,
|
||||
ImageDestinations: b.config.ImageDestinations,
|
||||
},
|
||||
|
||||
&stepCheckSourceImageId{
|
||||
SourceUHostImageId: b.config.SourceImageId,
|
||||
},
|
||||
|
||||
&stepConfigVPC{
|
||||
VPCId: b.config.VPCId,
|
||||
},
|
||||
&stepConfigSubnet{
|
||||
SubnetId: b.config.SubnetId,
|
||||
},
|
||||
&stepConfigSecurityGroup{
|
||||
SecurityGroupId: b.config.SecurityGroupId,
|
||||
},
|
||||
|
||||
&stepCreateInstance{
|
||||
InstanceType: b.config.InstanceType,
|
||||
Region: b.config.Region,
|
||||
Zone: b.config.Zone,
|
||||
SourceImageId: b.config.SourceImageId,
|
||||
InstanceName: b.config.InstanceName,
|
||||
BootDiskType: b.config.BootDiskType,
|
||||
UsePrivateIp: b.config.UseSSHPrivateIp,
|
||||
},
|
||||
&communicator.StepConnect{
|
||||
Config: &b.config.RunConfig.Comm,
|
||||
Host: SSHHost(
|
||||
b.config.UseSSHPrivateIp),
|
||||
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
|
||||
},
|
||||
&common.StepProvision{},
|
||||
&stepStopInstance{},
|
||||
&stepCreateImage{},
|
||||
&stepCopyUCloudImage{
|
||||
ImageDestinations: b.config.ImageDestinations,
|
||||
RegionId: b.config.Region,
|
||||
ProjectId: b.config.ProjectId,
|
||||
},
|
||||
}
|
||||
|
||||
// Run!
|
||||
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
|
||||
b.runner.Run(ctx, state)
|
||||
|
||||
// If there was an error, return that
|
||||
if rawErr, ok := state.GetOk("error"); ok {
|
||||
return nil, rawErr.(error)
|
||||
}
|
||||
|
||||
// If there are no ucloud images, then just return
|
||||
if _, ok := state.GetOk("ucloud_images"); !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Build the artifact and return it
|
||||
artifact := &Artifact{
|
||||
UCloudImages: state.Get("ucloud_images").(*imageInfoSet),
|
||||
BuilderIdValue: BuilderId,
|
||||
Client: client,
|
||||
}
|
||||
|
||||
return artifact, nil
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
builderT "github.com/hashicorp/packer/helper/builder/testing"
|
||||
)
|
||||
|
||||
func TestBuilderAcc_validateRegion(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if os.Getenv(builderT.TestEnvVar) == "" {
|
||||
t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", builderT.TestEnvVar))
|
||||
return
|
||||
}
|
||||
|
||||
testAccPreCheck(t)
|
||||
|
||||
access := &AccessConfig{Region: "cn-bj2"}
|
||||
err := access.Config()
|
||||
if err != nil {
|
||||
t.Fatalf("Error on initing UCloud AccessConfig, %s", err)
|
||||
}
|
||||
|
||||
err = access.ValidateRegion("cn-sh2")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected pass with valid region but failed: %s", err)
|
||||
}
|
||||
|
||||
err = access.ValidateRegion("invalidRegion")
|
||||
if err == nil {
|
||||
t.Fatal("Expected failure due to invalid region but passed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderAcc_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Builder: &Builder{},
|
||||
Template: testBuilderAccBasic,
|
||||
})
|
||||
}
|
||||
|
||||
const testBuilderAccBasic = `
|
||||
{ "builders": [{
|
||||
"type": "test",
|
||||
"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_{{timestamp}}"
|
||||
}]
|
||||
}`
|
||||
|
||||
func TestBuilderAcc_ubuntu(t *testing.T) {
|
||||
t.Parallel()
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Builder: &Builder{},
|
||||
Template: testBuilderAccUbuntu,
|
||||
})
|
||||
}
|
||||
|
||||
const testBuilderAccUbuntu = `
|
||||
{ "builders": [{
|
||||
"type": "test",
|
||||
"region": "cn-bj2",
|
||||
"availability_zone": "cn-bj2-02",
|
||||
"instance_type": "n-basic-2",
|
||||
"source_image_id":"uimage-irofn4",
|
||||
"ssh_username":"ubuntu",
|
||||
"image_name": "packer-test-basic_{{timestamp}}"
|
||||
}]
|
||||
}`
|
||||
|
||||
func TestBuilderAcc_regionCopy(t *testing.T) {
|
||||
t.Parallel()
|
||||
projectId := os.Getenv("UCLOUD_PROJECT_ID")
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Builder: &Builder{},
|
||||
Template: testBuilderAccRegionCopy,
|
||||
Check: checkRegionCopy(
|
||||
projectId,
|
||||
[]ImageDestination{
|
||||
{"org-fthbzm", "cn-sh2", "packer-test-regionCopy-sh", "test"},
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
const testBuilderAccRegionCopy = `
|
||||
{
|
||||
"builders": [{
|
||||
"type": "test",
|
||||
"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-regionCopy_{{timestamp}}",
|
||||
"image_copy_mappings": [{
|
||||
"image_copy_project_id": "org-fthbzm",
|
||||
"image_copy_region": "cn-sh2",
|
||||
"image_copy_name": "packer-test-regionCopy-sh",
|
||||
"image_copy_description": "test"
|
||||
}]
|
||||
}]
|
||||
}`
|
||||
|
||||
func checkRegionCopy(projectId string, imageDst []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)
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown artifact: %#v", artifactSet)
|
||||
}
|
||||
|
||||
destSet := newImageInfoSet(nil)
|
||||
for _, dest := range imageDst {
|
||||
destSet.Set(imageInfo{
|
||||
Region: dest.Region,
|
||||
ProjectId: dest.ProjectId,
|
||||
})
|
||||
}
|
||||
|
||||
for _, r := range artifact.UCloudImages.GetAll() {
|
||||
if r.ProjectId == projectId && r.Region == "cn-bj2" {
|
||||
destSet.Remove(r.Id())
|
||||
continue
|
||||
}
|
||||
|
||||
if destSet.Get(r.ProjectId, r.Region) == nil {
|
||||
return fmt.Errorf("project%s : region%s is not the target but found in artifacts", r.ProjectId, r.Region)
|
||||
}
|
||||
|
||||
destSet.Remove(r.Id())
|
||||
}
|
||||
|
||||
if len(destSet.GetAll()) > 0 {
|
||||
return fmt.Errorf("the following copying targets not found in corresponding artifacts : %#v", destSet.GetAll())
|
||||
}
|
||||
|
||||
client, _ := testUCloudClient()
|
||||
for _, r := range artifact.UCloudImages.GetAll() {
|
||||
if r.ProjectId == projectId && r.Region == "cn-bj2" {
|
||||
continue
|
||||
}
|
||||
imageSet, err := client.describeImageByInfo(r.ProjectId, r.Region, r.ImageId)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
return fmt.Errorf("image %s in artifacts can not be found", r.ImageId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if r.Region == "cn-sh2" && imageSet.ImageName != "packer-test-regionCopy-sh" {
|
||||
return fmt.Errorf("the name of image %q in artifacts should be %s, got %s", r.ImageId, "packer-test-regionCopy-sh", imageSet.ImageName)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccPreCheck(t *testing.T) {
|
||||
if v := os.Getenv("UCLOUD_PUBLIC_KEY"); v == "" {
|
||||
t.Fatal("UCLOUD_PUBLIC_KEY must be set for acceptance tests")
|
||||
}
|
||||
|
||||
if v := os.Getenv("UCLOUD_PRIVATE_KEY"); v == "" {
|
||||
t.Fatal("UCLOUD_PRIVATE_KEY must be set for acceptance tests")
|
||||
}
|
||||
|
||||
if v := os.Getenv("UCLOUD_PROJECT_ID"); v == "" {
|
||||
t.Fatal("UCLOUD_PROJECT_ID must be set for acceptance tests")
|
||||
}
|
||||
}
|
||||
|
||||
func testUCloudClient() (*UCloudClient, error) {
|
||||
access := &AccessConfig{Region: "cn-bj2"}
|
||||
err := access.Config()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := access.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testBuilderConfig() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"public_key": "foo",
|
||||
"private_key": "bar",
|
||||
"project_id": "foo",
|
||||
"source_image_id": "bar",
|
||||
"availability_zone": "cn-bj2-02",
|
||||
"instance_type": "n-basic-2",
|
||||
"region": "cn-bj2",
|
||||
"ssh_username": "root",
|
||||
"image_name": "foo",
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilder_ImplementsBuilder(t *testing.T) {
|
||||
var raw interface{}
|
||||
raw = &Builder{}
|
||||
if _, ok := raw.(packer.Builder); !ok {
|
||||
t.Fatalf("Builder should be a builder")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilder_Prepare_BadType(t *testing.T) {
|
||||
b := &Builder{}
|
||||
c := map[string]interface{}{
|
||||
"public_key": []string{},
|
||||
}
|
||||
|
||||
warnings, err := b.Prepare(c)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("prepare should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_ImageName(t *testing.T) {
|
||||
var b Builder
|
||||
config := testBuilderConfig()
|
||||
|
||||
// Test good
|
||||
config["image_name"] = "foo"
|
||||
warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test bad
|
||||
config["image_name"] = "foo {{"
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test bad
|
||||
delete(config, "image_name")
|
||||
b = Builder{}
|
||||
warnings, err = b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
||||
var b Builder
|
||||
config := testBuilderConfig()
|
||||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_ImageDestinations(t *testing.T) {
|
||||
var b Builder
|
||||
config := testBuilderConfig()
|
||||
config["image_copy_mappings"] = []map[string]interface{}{
|
||||
{
|
||||
"image_copy_project_id": "project1",
|
||||
"image_copy_region": "region1",
|
||||
"image_copy_name": "bar",
|
||||
"image_copy_description": "foo",
|
||||
},
|
||||
{
|
||||
"image_copy_project_id": "project2",
|
||||
"image_copy_region": "region2",
|
||||
"image_copy_name": "foo",
|
||||
"image_copy_description": "bar",
|
||||
},
|
||||
}
|
||||
warnings, err := b.Prepare(config)
|
||||
if len(warnings) > 0 {
|
||||
t.Fatalf("bad: %#v", warnings)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(b.config.ImageDestinations, []ImageDestination{
|
||||
{
|
||||
ProjectId: "project1",
|
||||
Region: "region1",
|
||||
Name: "bar",
|
||||
Description: "foo",
|
||||
},
|
||||
{
|
||||
ProjectId: "project2",
|
||||
Region: "region2",
|
||||
Name: "foo",
|
||||
Description: "bar",
|
||||
},
|
||||
}) {
|
||||
t.Fatalf("image_copy_mappings are not set properly, got: %#v", b.config.ImageDestinations)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/services/uaccount"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/uhost"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/unet"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/vpc"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/error"
|
||||
)
|
||||
|
||||
type UCloudClient struct {
|
||||
uhostconn *uhost.UHostClient
|
||||
unetconn *unet.UNetClient
|
||||
vpcconn *vpc.VPCClient
|
||||
uaccountconn *uaccount.UAccountClient
|
||||
}
|
||||
|
||||
func (c *UCloudClient) describeFirewallById(sgId string) (*unet.FirewallDataSet, error) {
|
||||
if sgId == "" {
|
||||
return nil, newNotFoundError("security group", sgId)
|
||||
}
|
||||
conn := c.unetconn
|
||||
|
||||
req := conn.NewDescribeFirewallRequest()
|
||||
req.FWId = ucloud.String(sgId)
|
||||
|
||||
resp, err := conn.DescribeFirewall(req)
|
||||
|
||||
// [API-STYLE] Fire wall api has not found err code, but others don't have
|
||||
if err != nil {
|
||||
if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 54002 {
|
||||
return nil, newNotFoundError("security group", sgId)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(resp.DataSet) < 1 {
|
||||
return nil, newNotFoundError("security group", sgId)
|
||||
}
|
||||
|
||||
return &resp.DataSet[0], nil
|
||||
}
|
||||
|
||||
func (c *UCloudClient) describeSubnetById(subnetId string) (*vpc.VPCSubnetInfoSet, error) {
|
||||
if subnetId == "" {
|
||||
return nil, newNotFoundError("Subnet", subnetId)
|
||||
}
|
||||
conn := c.vpcconn
|
||||
|
||||
req := conn.NewDescribeSubnetRequest()
|
||||
req.SubnetIds = []string{subnetId}
|
||||
|
||||
resp, err := conn.DescribeSubnet(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == nil || len(resp.DataSet) < 1 {
|
||||
return nil, newNotFoundError("Subnet", subnetId)
|
||||
}
|
||||
|
||||
return &resp.DataSet[0], nil
|
||||
}
|
||||
|
||||
func (c *UCloudClient) describeVPCById(vpcId string) (*vpc.VPCInfo, error) {
|
||||
if vpcId == "" {
|
||||
return nil, newNotFoundError("VPC", vpcId)
|
||||
}
|
||||
conn := c.vpcconn
|
||||
|
||||
req := conn.NewDescribeVPCRequest()
|
||||
req.VPCIds = []string{vpcId}
|
||||
|
||||
resp, err := conn.DescribeVPC(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == nil || len(resp.DataSet) < 1 {
|
||||
return nil, newNotFoundError("VPC", vpcId)
|
||||
}
|
||||
|
||||
return &resp.DataSet[0], nil
|
||||
}
|
||||
|
||||
func (c *UCloudClient) DescribeImageById(imageId string) (*uhost.UHostImageSet, error) {
|
||||
if imageId == "" {
|
||||
return nil, newNotFoundError("image", imageId)
|
||||
}
|
||||
req := c.uhostconn.NewDescribeImageRequest()
|
||||
req.ImageId = ucloud.String(imageId)
|
||||
|
||||
resp, err := c.uhostconn.DescribeImage(req)
|
||||
if err != nil {
|
||||
//if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 8889 {
|
||||
// return nil, newNotFoundError("image", imageId)
|
||||
//}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(resp.ImageSet) < 1 {
|
||||
return nil, newNotFoundError("image", imageId)
|
||||
}
|
||||
|
||||
return &resp.ImageSet[0], nil
|
||||
}
|
||||
|
||||
func (c *UCloudClient) describeUHostById(uhostId string) (*uhost.UHostInstanceSet, error) {
|
||||
if uhostId == "" {
|
||||
return nil, newNotFoundError("instance", uhostId)
|
||||
}
|
||||
req := c.uhostconn.NewDescribeUHostInstanceRequest()
|
||||
req.UHostIds = []string{uhostId}
|
||||
|
||||
resp, err := c.uhostconn.DescribeUHostInstance(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(resp.UHostSet) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &resp.UHostSet[0], nil
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
//if uErr, ok := err.(uerr.Error); ok && uErr.Code() == 8889 {
|
||||
// return nil, newNotFoundError("image", imageId)
|
||||
//}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(resp.ImageSet) < 1 {
|
||||
return nil, newNotFoundError("image", imageId)
|
||||
}
|
||||
|
||||
return &resp.ImageSet[0], nil
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package uhost
|
||||
|
||||
const (
|
||||
// defaultPasswordStr, defaultPasswordNum and defaultPasswordSpe are used to general default value of root password of UHost instance
|
||||
defaultPasswordNum = "012346789"
|
||||
defaultPasswordStr = "abcdefghijklmnopqrstuvwxyz"
|
||||
defaultPasswordSpe = "-_"
|
||||
)
|
||||
|
||||
var bootDiskTypeMap = map[string]string{
|
||||
"cloud_ssd": "CLOUD_SSD",
|
||||
"local_normal": "LOCAL_NORMAL",
|
||||
"local_ssd": "LOCAL_SSD",
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type NotFoundError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
type ExpectedStateError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
type NotCompleteError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e *ExpectedStateError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (e *NotFoundError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (e *NotCompleteError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func newNotFoundError(product, id string) error {
|
||||
return &NotFoundError{fmt.Sprintf("the %s %s is not found", product, id)}
|
||||
}
|
||||
|
||||
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 isNotFoundError(err error) bool {
|
||||
if _, ok := err.(*NotFoundError); ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isExpectedStateError(err error) bool {
|
||||
if _, ok := err.(*ExpectedStateError); ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isNotCompleteError(err error) bool {
|
||||
if _, ok := err.(*NotCompleteError); ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type ImageDestination struct {
|
||||
ProjectId string `mapstructure:"project_id"`
|
||||
Region string `mapstructure:"region"`
|
||||
Name string `mapstructure:"name"`
|
||||
Description string `mapstructure:"description"`
|
||||
}
|
||||
|
||||
type ImageConfig struct {
|
||||
ImageName string `mapstructure:"image_name"`
|
||||
ImageDescription string `mapstructure:"image_description"`
|
||||
ImageDestinations []ImageDestination `mapstructure:"image_copy_to_mappings"`
|
||||
}
|
||||
|
||||
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) {
|
||||
errs = append(errs, fmt.Errorf("expected %q to be 1-63 characters and only support chinese, english, numbers, '-_,.:[]', got %q", "image_name", imageName))
|
||||
}
|
||||
|
||||
if len(c.ImageDestinations) > 0 {
|
||||
for _, imageDestination := range c.ImageDestinations {
|
||||
if imageDestination.Name == "" {
|
||||
imageDestination.Name = imageName
|
||||
}
|
||||
errs = append(errs, imageDestination.validate()...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (imageDestination *ImageDestination) validate() []error {
|
||||
var errs []error
|
||||
|
||||
if imageDestination.Region == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set", "image_copy_region"))
|
||||
}
|
||||
|
||||
if imageDestination.ProjectId == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set", "image_copy_project"))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testImageConfig() *ImageConfig {
|
||||
return &ImageConfig{
|
||||
ImageName: "foo",
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageConfigPrepare_name(t *testing.T) {
|
||||
c := testImageConfig()
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
|
||||
c.ImageName = ""
|
||||
if err := c.Prepare(nil); err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageConfigPrepare_destinations(t *testing.T) {
|
||||
c := testImageConfig()
|
||||
c.ImageDestinations = nil
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("shouldn't have err: %s", err)
|
||||
}
|
||||
|
||||
c.ImageDestinations = []ImageDestination{
|
||||
{
|
||||
ProjectId: "foo",
|
||||
Region: "cn-bj2",
|
||||
Name: "bar",
|
||||
},
|
||||
|
||||
{
|
||||
ProjectId: "bar",
|
||||
Region: "cn-sh2",
|
||||
Name: "foo",
|
||||
},
|
||||
}
|
||||
if err := c.Prepare(nil); err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
|
||||
c.ImageDestinations = []ImageDestination{
|
||||
{
|
||||
ProjectId: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
|
||||
{
|
||||
ProjectId: "bar",
|
||||
Region: "cn-sh2",
|
||||
},
|
||||
}
|
||||
if err := c.Prepare(nil); err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/common/uuid"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type RunConfig struct {
|
||||
Zone string `mapstructure:"availability_zone"`
|
||||
SourceImageId string `mapstructure:"source_image_id"`
|
||||
InstanceType string `mapstructure:"instance_type"`
|
||||
InstanceName string `mapstructure:"instance_name"`
|
||||
BootDiskType string `mapstructure:"boot_disk_type"`
|
||||
VPCId string `mapstructure:"vpc_id"`
|
||||
SubnetId string `mapstructure:"subnet_id"`
|
||||
SecurityGroupId string `mapstructure:"security_group_id"`
|
||||
|
||||
// Communicator settings
|
||||
Comm communicator.Config `mapstructure:",squash"`
|
||||
UseSSHPrivateIp bool `mapstructure:"use_ssh_private_ip"`
|
||||
}
|
||||
|
||||
var instanceNamePattern = regexp.MustCompile(`^[A-Za-z0-9\p{Han}-_.]{1,63}$`)
|
||||
|
||||
func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
errs := c.Comm.Prepare(ctx)
|
||||
|
||||
if c.Zone == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set", "availability_zone"))
|
||||
}
|
||||
|
||||
if c.SourceImageId == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set", "source_image_id"))
|
||||
}
|
||||
|
||||
if c.InstanceType == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set", "instance_type"))
|
||||
} else if _, err := parseInstanceType(c.InstanceType); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if (c.VPCId != "" && c.SubnetId == "") || (c.VPCId == "" && c.SubnetId != "") {
|
||||
errs = append(errs, fmt.Errorf("expected both %q and %q to set or not set", "vpc_id", "subnet_id"))
|
||||
}
|
||||
|
||||
if c.BootDiskType == "" {
|
||||
c.BootDiskType = "cloud_ssd"
|
||||
} else if err := checkStringIn(c.BootDiskType,
|
||||
[]string{"local_normal", "local_ssd", "cloud_normal", "cloud_ssd"}); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if c.InstanceName == "" {
|
||||
c.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()[:8])
|
||||
} else if !instanceNamePattern.MatchString(c.InstanceName) {
|
||||
errs = append(errs, fmt.Errorf("expected %q to be 1-63 characters and only support chinese, english, numbers, '-_.', got %q", "instance_name", c.InstanceName))
|
||||
}
|
||||
|
||||
if c.UseSSHPrivateIp == true && c.VPCId == "" {
|
||||
errs = append(errs, fmt.Errorf("%q must be set when use_ssh_private_ip is true", "vpc_id"))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testConfig() *RunConfig {
|
||||
return &RunConfig{
|
||||
SourceImageId: "ucloud_image",
|
||||
InstanceType: "n-basic-2",
|
||||
Zone: "cn-bj2-02",
|
||||
Comm: communicator.Config{
|
||||
SSHUsername: "ucloud",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunConfigPrepare(t *testing.T) {
|
||||
c := testConfig()
|
||||
err := c.Prepare(nil)
|
||||
if len(err) > 0 {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunConfigPrepare_InstanceType(t *testing.T) {
|
||||
c := testConfig()
|
||||
c.InstanceType = ""
|
||||
if err := c.Prepare(nil); len(err) != 1 {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunConfigPrepare_SourceImage(t *testing.T) {
|
||||
c := testConfig()
|
||||
c.SourceImageId = ""
|
||||
if err := c.Prepare(nil); len(err) != 1 {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunConfigPrepare_SSHPort(t *testing.T) {
|
||||
c := testConfig()
|
||||
c.Comm.SSHPort = 0
|
||||
if err := c.Prepare(nil); len(err) != 0 {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if c.Comm.SSHPort != 22 {
|
||||
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
|
||||
}
|
||||
|
||||
c.Comm.SSHPort = 44
|
||||
if err := c.Prepare(nil); len(err) != 0 {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if c.Comm.SSHPort != 44 {
|
||||
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type stepCheckSourceImageId struct {
|
||||
SourceUHostImageId string
|
||||
}
|
||||
|
||||
func (s *stepCheckSourceImageId) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
|
||||
ui.Say("Querying source image id...")
|
||||
|
||||
imageSet, err := client.DescribeImageById(s.SourceUHostImageId)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying source_image_id")
|
||||
}
|
||||
|
||||
if imageSet.OsType == "Windows" {
|
||||
return halt(state, err, "The builder of ucloud-uhost not support make Windows image yet")
|
||||
}
|
||||
|
||||
state.Put("source_image", imageSet)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepCheckSourceImageId) Cleanup(multistep.StateBag) {}
|
|
@ -0,0 +1,76 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
)
|
||||
|
||||
type stepConfigSecurityGroup struct {
|
||||
SecurityGroupId string
|
||||
}
|
||||
|
||||
func (s *stepConfigSecurityGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(*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)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
err = fmt.Errorf("the specified security group %q not exist", s.SecurityGroupId)
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying security group")
|
||||
}
|
||||
|
||||
state.Put("security_group_id", securityGroupSet.FWId)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
ui.Say("Trying to use default security group...")
|
||||
var securityGroupId string
|
||||
var limit = 100
|
||||
var offset int
|
||||
|
||||
for {
|
||||
req := conn.NewDescribeFirewallRequest()
|
||||
req.Limit = ucloud.Int(limit)
|
||||
req.Offset = ucloud.Int(offset)
|
||||
|
||||
resp, err := conn.DescribeFirewall(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on querying security group")
|
||||
}
|
||||
|
||||
if resp == nil || len(resp.DataSet) < 1 {
|
||||
break
|
||||
}
|
||||
|
||||
for _, item := range resp.DataSet {
|
||||
if item.Type == "recommend non web" {
|
||||
securityGroupId = item.FWId
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(resp.DataSet) < limit {
|
||||
break
|
||||
}
|
||||
|
||||
offset = offset + limit
|
||||
}
|
||||
|
||||
if securityGroupId != "" {
|
||||
state.Put("security_group_id", securityGroupId)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepConfigSecurityGroup) Cleanup(state multistep.StateBag) {
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type stepConfigSubnet struct {
|
||||
SubnetId string
|
||||
}
|
||||
|
||||
func (s *stepConfigSubnet) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(*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)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
err = fmt.Errorf("the specified subnet %q not exist", s.SubnetId)
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying subnet")
|
||||
}
|
||||
|
||||
state.Put("subnet_id", subnetSet.SubnetId)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Trying to use default subnet..."))
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepConfigSubnet) Cleanup(state multistep.StateBag) {
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type stepConfigVPC struct {
|
||||
VPCId string
|
||||
}
|
||||
|
||||
func (s *stepConfigVPC) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(*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)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
err = fmt.Errorf("the specified vpc %q not exist", s.VPCId)
|
||||
return halt(state, err, "")
|
||||
}
|
||||
return halt(state, err, "Error on querying vpc")
|
||||
}
|
||||
|
||||
state.Put("vpc_id", vpcSet.VPCId)
|
||||
return multistep.ActionContinue
|
||||
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Trying to use default vpc..."))
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepConfigVPC) Cleanup(state multistep.StateBag) {
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
)
|
||||
|
||||
type stepCopyUCloudImage struct {
|
||||
ImageDestinations []ImageDestination
|
||||
RegionId string
|
||||
ProjectId string
|
||||
}
|
||||
|
||||
func (s *stepCopyUCloudImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
if len(s.ImageDestinations) == 0 {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
client := state.Get("client").(*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)
|
||||
|
||||
ui.Say(fmt.Sprintf("Copying image with %q...", srcImageId))
|
||||
for _, imageDestination := range s.ImageDestinations {
|
||||
if imageDestination.ProjectId == s.ProjectId && imageDestination.Region == s.RegionId {
|
||||
continue
|
||||
}
|
||||
|
||||
req := conn.NewCopyCustomImageRequest()
|
||||
req.TargetProjectId = ucloud.String(imageDestination.ProjectId)
|
||||
req.TargetRegion = ucloud.String(imageDestination.Region)
|
||||
req.SourceImageId = ucloud.String(srcImageId)
|
||||
req.TargetImageName = ucloud.String(imageDestination.Name)
|
||||
|
||||
resp, err := conn.CopyCustomImage(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on copying images")
|
||||
}
|
||||
|
||||
image := imageInfo{
|
||||
Region: imageDestination.Region,
|
||||
ProjectId: imageDestination.ProjectId,
|
||||
ImageId: resp.TargetImageId,
|
||||
}
|
||||
expectedImages.Set(image)
|
||||
artifactImages.Set(image)
|
||||
|
||||
ui.Message(fmt.Sprintf("Copying image from %s:%s:%s to %s:%s:%s)",
|
||||
s.ProjectId, s.RegionId, srcImageId, imageDestination.ProjectId, imageDestination.Region, resp.TargetImageId))
|
||||
}
|
||||
|
||||
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,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
for _, v := range expectedImages.GetAll() {
|
||||
imageSet, err := client.describeImageByInfo(v.ProjectId, v.Region, v.ImageId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if imageSet.State == "Available" {
|
||||
expectedImages.Remove(v.Id())
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if len(expectedImages.GetAll()) != 0 {
|
||||
return newNotCompleteError("copying image")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for copying image finished"))
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Copy image complete"))
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepCopyUCloudImage) Cleanup(state multistep.StateBag) {
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
|
||||
if !cancelled && !halted {
|
||||
return
|
||||
}
|
||||
|
||||
srcImageId := state.Get("image_id").(string)
|
||||
ucloudImages := state.Get("ucloud_images").(*imageInfoSet)
|
||||
imageInfos := ucloudImages.GetAll()
|
||||
if len(imageInfos) == 0 {
|
||||
return
|
||||
} else if len(imageInfos) == 1 && imageInfos[0].ImageId == srcImageId {
|
||||
return
|
||||
}
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
ui.Say(fmt.Sprintf("Deleting copied image because cancellation or error..."))
|
||||
|
||||
for _, v := range imageInfos {
|
||||
if v.ImageId == srcImageId {
|
||||
continue
|
||||
}
|
||||
|
||||
req := conn.NewTerminateCustomImageRequest()
|
||||
req.ProjectId = ucloud.String(v.ProjectId)
|
||||
req.Region = ucloud.String(v.Region)
|
||||
req.ImageId = ucloud.String(v.ImageId)
|
||||
_, err := conn.TerminateCustomImage(req)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on deleting copied image %q", v.ImageId))
|
||||
}
|
||||
}
|
||||
|
||||
ui.Message("Delete copied image complete")
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/uhost"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
)
|
||||
|
||||
type stepCreateImage struct {
|
||||
image *uhost.UHostImageSet
|
||||
}
|
||||
|
||||
func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
instance := state.Get("instance").(*uhost.UHostInstanceSet)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config := state.Get("config").(*Config)
|
||||
|
||||
ui.Say(fmt.Sprintf("Creating image %s", config.ImageName))
|
||||
|
||||
req := conn.NewCreateCustomImageRequest()
|
||||
req.ImageName = ucloud.String(config.ImageName)
|
||||
req.ImageDescription = ucloud.String(config.ImageDescription)
|
||||
req.UHostId = ucloud.String(instance.UHostId)
|
||||
|
||||
resp, err := conn.CreateCustomImage(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 200,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return 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.DescribeImageById(resp.ImageId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if inst == nil || inst.State != "Available" {
|
||||
return newExpectedStateError("image", resp.ImageId)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on waiting for image to available")
|
||||
}
|
||||
|
||||
imageSet, err := client.DescribeImageById(resp.ImageId)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on reading image")
|
||||
}
|
||||
|
||||
s.image = imageSet
|
||||
state.Put("image_id", imageSet.ImageId)
|
||||
|
||||
images := []imageInfo{
|
||||
{
|
||||
ImageId: imageSet.ImageId,
|
||||
ProjectId: config.ProjectId,
|
||||
Region: config.Region,
|
||||
},
|
||||
}
|
||||
|
||||
state.Put("ucloud_images", newImageInfoSet(images))
|
||||
ui.Message(fmt.Sprintf("Create image %q complete", imageSet.ImageId))
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepCreateImage) Cleanup(state multistep.StateBag) {
|
||||
if s.image == nil {
|
||||
return
|
||||
}
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
if !cancelled && !halted {
|
||||
return
|
||||
}
|
||||
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Deleting image because of cancellation or error...")
|
||||
req := conn.NewTerminateCustomImageRequest()
|
||||
req.ImageId = ucloud.String(s.image.ImageId)
|
||||
_, err := conn.TerminateCustomImage(req)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on deleting image %q", s.image.ImageId))
|
||||
}
|
||||
ui.Message(fmt.Sprintf("Delete image %q complete", s.image.ImageId))
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/uhost"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type stepCreateInstance struct {
|
||||
Region string
|
||||
Zone string
|
||||
InstanceType string
|
||||
InstanceName string
|
||||
BootDiskType string
|
||||
SourceImageId string
|
||||
UsePrivateIp bool
|
||||
|
||||
instanceId string
|
||||
}
|
||||
|
||||
func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Creating Instance...")
|
||||
req, err := s.buildCreateInstanceRequest(state)
|
||||
if err != nil {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
|
||||
resp, err := conn.CreateUHostInstance(req)
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on creating instance")
|
||||
}
|
||||
instanceId := resp.UHostIds[0]
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 20,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return 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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if inst == nil || inst.State != "Running" {
|
||||
return newExpectedStateError("instance", instanceId)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on waiting for instance to available")
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Create instance %q complete", instanceId))
|
||||
instance, err := client.describeUHostById(instanceId)
|
||||
if err != nil {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
|
||||
s.instanceId = instanceId
|
||||
state.Put("instance", instance)
|
||||
|
||||
if instance.BootDiskState == "Initializing" {
|
||||
ui.Say(fmt.Sprintf("Waiting for boot disk of instance initialized when boot_disk_type is %q", s.BootDiskType))
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 200,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return 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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if inst.BootDiskState != "Normal" {
|
||||
return newExpectedStateError("boot_disk of instance", instanceId)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, "Error on waiting for boot disk of instance initialized")
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Waite for boot disk of instance %q initialized complete", instanceId))
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
||||
if s.instanceId == "" {
|
||||
return
|
||||
}
|
||||
_, cancelled := state.GetOk(multistep.StateCancelled)
|
||||
_, halted := state.GetOk(multistep.StateHalted)
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
ctx := context.TODO()
|
||||
|
||||
if cancelled || halted {
|
||||
ui.Say("Deleting instance because of cancellation or error...")
|
||||
} else {
|
||||
ui.Say("Deleting instance...")
|
||||
}
|
||||
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
|
||||
stopReq := conn.NewPoweroffUHostInstanceRequest()
|
||||
stopReq.UHostId = ucloud.String(s.instanceId)
|
||||
|
||||
instance, err := client.describeUHostById(s.instanceId)
|
||||
if err != nil {
|
||||
if isNotFoundError(err) {
|
||||
return
|
||||
}
|
||||
ui.Error(fmt.Sprintf("Error on reading instance when delete %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if instance.State != "Stopped" {
|
||||
err = retry.Config{
|
||||
Tries: 5,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return err != nil
|
||||
},
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
if _, err = conn.PoweroffUHostInstance(stopReq); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on stopping instance when delete %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 30,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return 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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if instance.State != "Stopped" {
|
||||
return newExpectedStateError("instance", s.instanceId)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on waiting for instance %q to stopped, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
deleteReq := conn.NewTerminateUHostInstanceRequest()
|
||||
deleteReq.UHostId = ucloud.String(s.instanceId)
|
||||
deleteReq.ReleaseUDisk = ucloud.Bool(true)
|
||||
deleteReq.ReleaseEIP = ucloud.Bool(true)
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 5,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return err != nil
|
||||
},
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
if _, err = conn.TerminateUHostInstance(deleteReq); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on deleting instance %q, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
err = retry.Config{
|
||||
Tries: 30,
|
||||
ShouldRetry: func(err error) bool { return !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)
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error on waiting for deleting instance %q completed, %s",
|
||||
s.instanceId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Delete instance %q complete", s.instanceId))
|
||||
}
|
||||
|
||||
func (s *stepCreateInstance) buildCreateInstanceRequest(state multistep.StateBag) (*uhost.CreateUHostInstanceRequest, error) {
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
srcImage := state.Get("source_image").(*uhost.UHostImageSet)
|
||||
config := state.Get("config").(*Config)
|
||||
connectConfig := &config.RunConfig.Comm
|
||||
|
||||
var password string
|
||||
if srcImage.OsType == "Linux" {
|
||||
password = config.Comm.SSHPassword
|
||||
}
|
||||
|
||||
if password == "" {
|
||||
password = fmt.Sprintf("%s%s%s",
|
||||
s.randStringFromCharSet(5, defaultPasswordStr),
|
||||
s.randStringFromCharSet(1, defaultPasswordSpe),
|
||||
s.randStringFromCharSet(5, defaultPasswordNum))
|
||||
if srcImage.OsType == "Linux" {
|
||||
connectConfig.SSHPassword = password
|
||||
}
|
||||
}
|
||||
|
||||
req := conn.NewCreateUHostInstanceRequest()
|
||||
t, _ := parseInstanceType(s.InstanceType)
|
||||
|
||||
req.CPU = ucloud.Int(t.CPU)
|
||||
req.Memory = ucloud.Int(t.Memory)
|
||||
req.Name = ucloud.String(s.InstanceName)
|
||||
req.LoginMode = ucloud.String("Password")
|
||||
req.Zone = ucloud.String(s.Zone)
|
||||
req.ImageId = ucloud.String(s.SourceImageId)
|
||||
req.ChargeType = ucloud.String("Dynamic")
|
||||
req.Password = ucloud.String(password)
|
||||
|
||||
if v, ok := state.GetOk("security_group_id"); ok {
|
||||
req.SecurityGroupId = ucloud.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := state.GetOk("vpc_id"); ok {
|
||||
req.VPCId = ucloud.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := state.GetOk("subnet_id"); ok {
|
||||
req.SubnetId = ucloud.String(v.(string))
|
||||
}
|
||||
|
||||
bootDisk := uhost.UHostDisk{}
|
||||
bootDisk.IsBoot = ucloud.String("true")
|
||||
bootDisk.Size = ucloud.Int(srcImage.ImageSize)
|
||||
bootDisk.Type = ucloud.String(bootDiskTypeMap[s.BootDiskType])
|
||||
|
||||
req.Disks = append(req.Disks, bootDisk)
|
||||
|
||||
if !s.UsePrivateIp {
|
||||
operatorName := ucloud.String("International")
|
||||
if strings.HasPrefix(s.Region, "cn-") {
|
||||
operatorName = ucloud.String("Bgp")
|
||||
}
|
||||
networkInterface := uhost.CreateUHostInstanceParamNetworkInterface{
|
||||
EIP: &uhost.CreateUHostInstanceParamNetworkInterfaceEIP{
|
||||
Bandwidth: ucloud.Int(30),
|
||||
PayMode: ucloud.String("Traffic"),
|
||||
OperatorName: operatorName,
|
||||
},
|
||||
}
|
||||
|
||||
req.NetworkInterface = append(req.NetworkInterface, networkInterface)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (s *stepCreateInstance) randStringFromCharSet(strlen int, charSet string) string {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
result := make([]byte, strlen)
|
||||
for i := 0; i < strlen; i++ {
|
||||
result[i] = charSet[rand.Intn(len(charSet))]
|
||||
}
|
||||
return string(result)
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type stepPreValidate struct {
|
||||
Region string
|
||||
Zone string
|
||||
ImageDestinations []ImageDestination
|
||||
}
|
||||
|
||||
func (s *stepPreValidate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
if err := s.validateRegions(state); err != nil {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
|
||||
if err := s.validateZones(state); err != nil {
|
||||
return halt(state, err, "")
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepPreValidate) validateRegions(state multistep.StateBag) error {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config := state.Get("config").(*Config)
|
||||
|
||||
ui.Say("Validating region and copied regions...")
|
||||
|
||||
var errs *packer.MultiError
|
||||
if err := config.ValidateRegion(s.Region); err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
for _, imageDestination := range s.ImageDestinations {
|
||||
if err := config.ValidateRegion(imageDestination.Region); err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepPreValidate) validateZones(state multistep.StateBag) error {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config := state.Get("config").(*Config)
|
||||
|
||||
ui.Say("Validating availability_zone...")
|
||||
|
||||
var errs *packer.MultiError
|
||||
if err := config.ValidateZone(s.Region, s.Zone); err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepPreValidate) Cleanup(multistep.StateBag) {}
|
|
@ -0,0 +1,80 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/common/retry"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/uhost"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
)
|
||||
|
||||
type stepStopInstance struct {
|
||||
}
|
||||
|
||||
func (s *stepStopInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
client := state.Get("client").(*UCloudClient)
|
||||
conn := client.uhostconn
|
||||
instance := state.Get("instance").(*uhost.UHostInstanceSet)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
instance, err := client.describeUHostById(instance.UHostId)
|
||||
if err != nil {
|
||||
return halt(state, err, fmt.Sprintf("Error on reading instance when stop %q", instance.UHostId))
|
||||
}
|
||||
|
||||
if instance.State != "Stopped" {
|
||||
stopReq := conn.NewPoweroffUHostInstanceRequest()
|
||||
stopReq.UHostId = ucloud.String(instance.UHostId)
|
||||
ui.Say(fmt.Sprintf("Stopping instance %q", instance.UHostId))
|
||||
err = retry.Config{
|
||||
Tries: 5,
|
||||
ShouldRetry: func(err error) bool {
|
||||
return err != nil
|
||||
},
|
||||
RetryDelay: (&retry.Backoff{InitialBackoff: 2 * time.Second, MaxBackoff: 6 * time.Second, Multiplier: 2}).Linear,
|
||||
}.Run(ctx, func(ctx context.Context) error {
|
||||
if _, err = conn.PoweroffUHostInstance(stopReq); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return 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)
|
||||
},
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if instance.State != "Stopped" {
|
||||
return newExpectedStateError("instance", instance.UHostId)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return halt(state, err, fmt.Sprintf("Error on waiting for instance %q to stopped", instance.UHostId))
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Stop instance %q complete", instance.UHostId))
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepStopInstance) Cleanup(multistep.StateBag) {
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type instanceType struct {
|
||||
CPU int
|
||||
Memory int
|
||||
HostType string
|
||||
HostScaleType string
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
if split[1] == "customized" {
|
||||
return parseInstanceTypeByCustomize(split...)
|
||||
}
|
||||
|
||||
return parseInstanceTypeByNormal(split...)
|
||||
}
|
||||
func (i *instanceType) String() string {
|
||||
if i.Iscustomized() {
|
||||
return fmt.Sprintf("%s-%s-%v-%v", i.HostType, i.HostScaleType, i.CPU, i.Memory)
|
||||
} else {
|
||||
return fmt.Sprintf("%s-%s-%v", i.HostType, i.HostScaleType, i.CPU)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *instanceType) Iscustomized() bool {
|
||||
return i.HostScaleType == "customized"
|
||||
}
|
||||
|
||||
var instanceTypeScaleMap = map[string]int{
|
||||
"highcpu": 1 * 1024,
|
||||
"basic": 2 * 1024,
|
||||
"standard": 4 * 1024,
|
||||
"highmem": 8 * 1024,
|
||||
}
|
||||
|
||||
var availableHostTypes = []string{"n"}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hostScaleType := splited[1]
|
||||
|
||||
cpu, err := strconv.Atoi(splited[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cpu count is invalid, please use a number")
|
||||
}
|
||||
|
||||
memory, err := strconv.Atoi(splited[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("memory count is invalid, please use a number")
|
||||
}
|
||||
|
||||
if cpu/memory > 2 || memory/cpu > 12 {
|
||||
return nil, fmt.Errorf("the ratio of cpu to memory should be range of 2:1 ~ 1:12, got %d:%d", cpu, memory)
|
||||
}
|
||||
|
||||
if memory/cpu == 1 || memory/cpu == 2 || memory/cpu == 4 || memory/cpu == 8 {
|
||||
return nil, fmt.Errorf("instance type is invalid, expected %q like %q,"+
|
||||
"the Type can be highcpu, basic, standard, highmem when the ratio of cpu to memory is 1:1, 1:2, 1:4, 1:8", "n-Type-CPU", "n-standard-1")
|
||||
}
|
||||
|
||||
if cpu < 1 || 32 < cpu {
|
||||
return nil, fmt.Errorf("expected cpu to be in the range (1 - 32), got %d", cpu)
|
||||
}
|
||||
|
||||
if memory < 1 || 128 < memory {
|
||||
return nil, fmt.Errorf("expected memory to be in the range (1 - 128),got %d", memory)
|
||||
}
|
||||
|
||||
if cpu != 1 && (cpu%2) != 0 {
|
||||
return nil, fmt.Errorf("expected the number of cores of cpu must be divisible by 2 without a remainder (except single core), got %d", cpu)
|
||||
}
|
||||
|
||||
if memory != 1 && (memory%2) != 0 {
|
||||
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.HostType = hostType
|
||||
t.HostScaleType = hostScaleType
|
||||
t.CPU = cpu
|
||||
t.Memory = memory * 1024
|
||||
return t, nil
|
||||
}
|
||||
|
||||
var availableOutstandingCpu = []int{4, 8, 16, 32, 64}
|
||||
|
||||
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"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hostScaleType := split[1]
|
||||
|
||||
if scale, ok := instanceTypeScaleMap[hostScaleType]; !ok {
|
||||
return nil, fmt.Errorf("instance type is invalid, expected like n-standard-1")
|
||||
} else {
|
||||
cpu, err := strconv.Atoi(split[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cpu count is invalid, please use a number")
|
||||
}
|
||||
|
||||
if cpu != 1 && (cpu%2) != 0 {
|
||||
return nil, fmt.Errorf("expected the number of cores of cpu must be divisible by 2 without a remainder (except single core), got %d", cpu)
|
||||
}
|
||||
|
||||
if hostType == "o" {
|
||||
if err := checkIntIn(cpu, availableOutstandingCpu); err != nil {
|
||||
return nil, fmt.Errorf("expected cpu of outstanding instancetype %q", err)
|
||||
}
|
||||
|
||||
if hostScaleType == "highmem" && cpu == 64 {
|
||||
return nil, fmt.Errorf("this instance type %q is not supported, please refer to instance type document", "o-highmem-64")
|
||||
}
|
||||
} else {
|
||||
if hostScaleType == "highmem" && cpu > 16 {
|
||||
return nil, fmt.Errorf("expected cpu to be in the range (1 - 16) for normal highmem instance type, got %d", cpu)
|
||||
}
|
||||
|
||||
if cpu < 1 || 32 < cpu {
|
||||
return nil, fmt.Errorf("expected cpu to be in the range (1 - 32) for normal instance type, got %d", cpu)
|
||||
}
|
||||
}
|
||||
|
||||
memory := cpu * scale
|
||||
|
||||
t := &instanceType{}
|
||||
t.HostType = hostType
|
||||
t.HostScaleType = hostScaleType
|
||||
t.CPU = cpu
|
||||
t.Memory = memory
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
|
||||
type imageInfo struct {
|
||||
ImageId string
|
||||
ProjectId string
|
||||
Region string
|
||||
}
|
||||
|
||||
func (i *imageInfo) Id() string {
|
||||
return fmt.Sprintf("%s:%s", i.ProjectId, i.Region)
|
||||
}
|
||||
|
||||
type imageInfoSet struct {
|
||||
m map[string]imageInfo
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
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) Set(img imageInfo) {
|
||||
i.once.Do(i.init)
|
||||
|
||||
i.m[img.Id()] = img
|
||||
}
|
||||
|
||||
func (i *imageInfoSet) Remove(id string) {
|
||||
i.once.Do(i.init)
|
||||
|
||||
delete(i.m, id)
|
||||
}
|
||||
|
||||
func (i *imageInfoSet) Get(projectId, region string) *imageInfo {
|
||||
k := fmt.Sprintf("%s:%s", projectId, region)
|
||||
if v, ok := i.m[k]; ok {
|
||||
return &v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *imageInfoSet) GetAll() []imageInfo {
|
||||
var vL []imageInfo
|
||||
for _, img := range i.m {
|
||||
vL = append(vL, img)
|
||||
}
|
||||
return vL
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_parseInstanceType(t *testing.T) {
|
||||
type args struct {
|
||||
s string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
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},
|
||||
|
||||
{"err_customized", args{"n-customized-1-5"}, nil, true},
|
||||
{"err_type", args{"nx-highcpu-1"}, nil, true},
|
||||
{"err_scale_type", args{"n-invalid-1"}, nil, true},
|
||||
{"err_cpu_too_much", args{"n-highcpu-33"}, nil, true},
|
||||
{"err_cpu_too_less", args{"n-highcpu-0"}, nil, true},
|
||||
{"err_cpu_is_invalid", args{"n-highcpu-x"}, nil, true},
|
||||
{"err_customized_format_len", args{"n-customized-1"}, nil, true},
|
||||
{"err_customized_format_number", args{"n-customized-x"}, nil, true},
|
||||
{"err_customized_should_be_standard", args{"n-customized-1-2"}, nil, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
if got == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !(tt.want.CPU == got.CPU) ||
|
||||
!(tt.want.Memory == got.Memory) ||
|
||||
!(tt.want.HostType == got.HostType) ||
|
||||
!(tt.want.HostScaleType == got.HostScaleType) {
|
||||
t.Errorf("parseInstanceType() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/ucloud/ucloud-sdk-go/services/uhost"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func checkStringIn(val string, availables []string) error {
|
||||
for _, choice := range availables {
|
||||
if val == choice {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("should be one of %q, got %q", strings.Join(availables, ","), val)
|
||||
}
|
||||
|
||||
func checkIntIn(val int, availables []int) error {
|
||||
for _, choice := range availables {
|
||||
if val == choice {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("should be one of %v, got %d", availables, val)
|
||||
}
|
||||
|
||||
func isStringIn(val string, availables []string) bool {
|
||||
for _, choice := range availables {
|
||||
if val == choice {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// SSHHost returns a function that can be given to the SSH communicator
|
||||
func SSHHost(usePrivateIp bool) func(multistep.StateBag) (string, error) {
|
||||
return func(state multistep.StateBag) (string, error) {
|
||||
|
||||
instance := state.Get("instance").(*uhost.UHostInstanceSet)
|
||||
var privateIp, publicIp string
|
||||
|
||||
for _, v := range instance.IPSet {
|
||||
if v.Type == "Private" {
|
||||
privateIp = v.IP
|
||||
} else {
|
||||
publicIp = v.IP
|
||||
}
|
||||
}
|
||||
if usePrivateIp {
|
||||
return privateIp, nil
|
||||
} else {
|
||||
return publicIp, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
if prefix != "" {
|
||||
err = fmt.Errorf("%s: %s", prefix, err)
|
||||
}
|
||||
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
|
@ -46,6 +46,7 @@ import (
|
|||
scalewaybuilder "github.com/hashicorp/packer/builder/scaleway"
|
||||
tencentcloudcvmbuilder "github.com/hashicorp/packer/builder/tencentcloud/cvm"
|
||||
tritonbuilder "github.com/hashicorp/packer/builder/triton"
|
||||
uclouduhostbuilder "github.com/hashicorp/packer/builder/ucloud/uhost"
|
||||
vagrantbuilder "github.com/hashicorp/packer/builder/vagrant"
|
||||
virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso"
|
||||
virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf"
|
||||
|
@ -127,6 +128,7 @@ var Builders = map[string]packer.Builder{
|
|||
"scaleway": new(scalewaybuilder.Builder),
|
||||
"tencentcloud-cvm": new(tencentcloudcvmbuilder.Builder),
|
||||
"triton": new(tritonbuilder.Builder),
|
||||
"ucloud-uhost": new(uclouduhostbuilder.Builder),
|
||||
"vagrant": new(vagrantbuilder.Builder),
|
||||
"virtualbox-iso": new(virtualboxisobuilder.Builder),
|
||||
"virtualbox-ovf": new(virtualboxovfbuilder.Builder),
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// Code generated by pigeon; DO NOT EDIT.
|
||||
|
||||
package bootcommand
|
||||
|
||||
import (
|
||||
|
@ -8,9 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -791,85 +787,18 @@ var (
|
|||
// errNoRule is returned when the grammar to parse has no rule.
|
||||
errNoRule = errors.New("grammar has no rule")
|
||||
|
||||
// errInvalidEntrypoint is returned when the specified entrypoint rule
|
||||
// does not exit.
|
||||
errInvalidEntrypoint = errors.New("invalid entrypoint")
|
||||
|
||||
// errInvalidEncoding is returned when the source is not properly
|
||||
// utf8-encoded.
|
||||
errInvalidEncoding = errors.New("invalid encoding")
|
||||
|
||||
// errMaxExprCnt is used to signal that the maximum number of
|
||||
// expressions have been parsed.
|
||||
errMaxExprCnt = errors.New("max number of expresssions parsed")
|
||||
// errNoMatch is returned if no match could be found.
|
||||
errNoMatch = errors.New("no match found")
|
||||
)
|
||||
|
||||
// Option is a function that can set an option on the parser. It returns
|
||||
// the previous setting as an Option.
|
||||
type Option func(*parser) Option
|
||||
|
||||
// MaxExpressions creates an Option to stop parsing after the provided
|
||||
// number of expressions have been parsed, if the value is 0 then the parser will
|
||||
// parse for as many steps as needed (possibly an infinite number).
|
||||
//
|
||||
// The default for maxExprCnt is 0.
|
||||
func MaxExpressions(maxExprCnt uint64) Option {
|
||||
return func(p *parser) Option {
|
||||
oldMaxExprCnt := p.maxExprCnt
|
||||
p.maxExprCnt = maxExprCnt
|
||||
return MaxExpressions(oldMaxExprCnt)
|
||||
}
|
||||
}
|
||||
|
||||
// Entrypoint creates an Option to set the rule name to use as entrypoint.
|
||||
// The rule name must have been specified in the -alternate-entrypoints
|
||||
// if generating the parser with the -optimize-grammar flag, otherwise
|
||||
// it may have been optimized out. Passing an empty string sets the
|
||||
// entrypoint to the first rule in the grammar.
|
||||
//
|
||||
// The default is to start parsing at the first rule in the grammar.
|
||||
func Entrypoint(ruleName string) Option {
|
||||
return func(p *parser) Option {
|
||||
oldEntrypoint := p.entrypoint
|
||||
p.entrypoint = ruleName
|
||||
if ruleName == "" {
|
||||
p.entrypoint = g.rules[0].name
|
||||
}
|
||||
return Entrypoint(oldEntrypoint)
|
||||
}
|
||||
}
|
||||
|
||||
// Statistics adds a user provided Stats struct to the parser to allow
|
||||
// the user to process the results after the parsing has finished.
|
||||
// Also the key for the "no match" counter is set.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// input := "input"
|
||||
// stats := Stats{}
|
||||
// _, err := Parse("input-file", []byte(input), Statistics(&stats, "no match"))
|
||||
// if err != nil {
|
||||
// log.Panicln(err)
|
||||
// }
|
||||
// b, err := json.MarshalIndent(stats.ChoiceAltCnt, "", " ")
|
||||
// if err != nil {
|
||||
// log.Panicln(err)
|
||||
// }
|
||||
// fmt.Println(string(b))
|
||||
//
|
||||
func Statistics(stats *Stats, choiceNoMatch string) Option {
|
||||
return func(p *parser) Option {
|
||||
oldStats := p.Stats
|
||||
p.Stats = stats
|
||||
oldChoiceNoMatch := p.choiceNoMatch
|
||||
p.choiceNoMatch = choiceNoMatch
|
||||
if p.Stats.ChoiceAltCnt == nil {
|
||||
p.Stats.ChoiceAltCnt = make(map[string]map[string]int)
|
||||
}
|
||||
return Statistics(oldStats, oldChoiceNoMatch)
|
||||
}
|
||||
}
|
||||
|
||||
// Debug creates an Option to set the debug flag to b. When set to true,
|
||||
// debugging information is printed to stdout while parsing.
|
||||
//
|
||||
|
@ -896,20 +825,6 @@ func Memoize(b bool) Option {
|
|||
}
|
||||
}
|
||||
|
||||
// AllowInvalidUTF8 creates an Option to allow invalid UTF-8 bytes.
|
||||
// Every invalid UTF-8 byte is treated as a utf8.RuneError (U+FFFD)
|
||||
// by character class matchers and is matched by the any matcher.
|
||||
// The returned matched value, c.text and c.offset are NOT affected.
|
||||
//
|
||||
// The default is false.
|
||||
func AllowInvalidUTF8(b bool) Option {
|
||||
return func(p *parser) Option {
|
||||
old := p.allowInvalidUTF8
|
||||
p.allowInvalidUTF8 = b
|
||||
return AllowInvalidUTF8(old)
|
||||
}
|
||||
}
|
||||
|
||||
// Recover creates an Option to set the recover flag to b. When set to
|
||||
// true, this causes the parser to recover from panics and convert it
|
||||
// to an error. Setting it to false can be useful while debugging to
|
||||
|
@ -924,37 +839,13 @@ func Recover(b bool) Option {
|
|||
}
|
||||
}
|
||||
|
||||
// GlobalStore creates an Option to set a key to a certain value in
|
||||
// the globalStore.
|
||||
func GlobalStore(key string, value interface{}) Option {
|
||||
return func(p *parser) Option {
|
||||
old := p.cur.globalStore[key]
|
||||
p.cur.globalStore[key] = value
|
||||
return GlobalStore(key, old)
|
||||
}
|
||||
}
|
||||
|
||||
// InitState creates an Option to set a key to a certain value in
|
||||
// the global "state" store.
|
||||
func InitState(key string, value interface{}) Option {
|
||||
return func(p *parser) Option {
|
||||
old := p.cur.state[key]
|
||||
p.cur.state[key] = value
|
||||
return InitState(key, old)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseFile parses the file identified by filename.
|
||||
func ParseFile(filename string, opts ...Option) (i interface{}, err error) {
|
||||
func ParseFile(filename string, opts ...Option) (interface{}, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := f.Close(); closeErr != nil {
|
||||
err = closeErr
|
||||
}
|
||||
}()
|
||||
defer f.Close()
|
||||
return ParseReader(filename, f, opts...)
|
||||
}
|
||||
|
||||
|
@ -995,22 +886,8 @@ type savepoint struct {
|
|||
type current struct {
|
||||
pos position // start position of the match
|
||||
text []byte // raw text of the match
|
||||
|
||||
// state is a store for arbitrary key,value pairs that the user wants to be
|
||||
// tied to the backtracking of the parser.
|
||||
// This is always rolled back if a parsing rule fails.
|
||||
state storeDict
|
||||
|
||||
// globalStore is a general store for the user to store arbitrary key-value
|
||||
// pairs that they need to manage and that they do not want tied to the
|
||||
// backtracking of the parser. This is only modified by the user and never
|
||||
// rolled back by the parser. It is always up to the user to keep this in a
|
||||
// consistent state.
|
||||
globalStore storeDict
|
||||
}
|
||||
|
||||
type storeDict map[string]interface{}
|
||||
|
||||
// the AST types...
|
||||
|
||||
type grammar struct {
|
||||
|
@ -1036,23 +913,11 @@ type actionExpr struct {
|
|||
run func(*parser) (interface{}, error)
|
||||
}
|
||||
|
||||
type recoveryExpr struct {
|
||||
pos position
|
||||
expr interface{}
|
||||
recoverExpr interface{}
|
||||
failureLabel []string
|
||||
}
|
||||
|
||||
type seqExpr struct {
|
||||
pos position
|
||||
exprs []interface{}
|
||||
}
|
||||
|
||||
type throwExpr struct {
|
||||
pos position
|
||||
label string
|
||||
}
|
||||
|
||||
type labeledExpr struct {
|
||||
pos position
|
||||
label string
|
||||
|
@ -1075,11 +940,6 @@ type ruleRefExpr struct {
|
|||
name string
|
||||
}
|
||||
|
||||
type stateCodeExpr struct {
|
||||
pos position
|
||||
run func(*parser) error
|
||||
}
|
||||
|
||||
type andCodeExpr struct {
|
||||
pos position
|
||||
run func(*parser) (bool, error)
|
||||
|
@ -1097,14 +957,13 @@ type litMatcher struct {
|
|||
}
|
||||
|
||||
type charClassMatcher struct {
|
||||
pos position
|
||||
val string
|
||||
basicLatinChars [128]bool
|
||||
chars []rune
|
||||
ranges []rune
|
||||
classes []*unicode.RangeTable
|
||||
ignoreCase bool
|
||||
inverted bool
|
||||
pos position
|
||||
val string
|
||||
chars []rune
|
||||
ranges []rune
|
||||
classes []*unicode.RangeTable
|
||||
ignoreCase bool
|
||||
inverted bool
|
||||
}
|
||||
|
||||
type anyMatcher position
|
||||
|
@ -1158,10 +1017,9 @@ func (e errList) Error() string {
|
|||
// parserError wraps an error with a prefix indicating the rule in which
|
||||
// the error occurred. The original error is stored in the Inner field.
|
||||
type parserError struct {
|
||||
Inner error
|
||||
pos position
|
||||
prefix string
|
||||
expected []string
|
||||
Inner error
|
||||
pos position
|
||||
prefix string
|
||||
}
|
||||
|
||||
// Error returns the error message.
|
||||
|
@ -1171,32 +1029,14 @@ func (p *parserError) Error() string {
|
|||
|
||||
// newParser creates a parser with the specified input source and options.
|
||||
func newParser(filename string, b []byte, opts ...Option) *parser {
|
||||
stats := Stats{
|
||||
ChoiceAltCnt: make(map[string]map[string]int),
|
||||
}
|
||||
|
||||
p := &parser{
|
||||
filename: filename,
|
||||
errs: new(errList),
|
||||
data: b,
|
||||
pt: savepoint{position: position{line: 1}},
|
||||
recover: true,
|
||||
cur: current{
|
||||
state: make(storeDict),
|
||||
globalStore: make(storeDict),
|
||||
},
|
||||
maxFailPos: position{col: 1, line: 1},
|
||||
maxFailExpected: make([]string, 0, 20),
|
||||
Stats: &stats,
|
||||
// start rule is rule [0] unless an alternate entrypoint is specified
|
||||
entrypoint: g.rules[0].name,
|
||||
}
|
||||
p.setOptions(opts)
|
||||
|
||||
if p.maxExprCnt == 0 {
|
||||
p.maxExprCnt = math.MaxUint64
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
|
@ -1213,30 +1053,6 @@ type resultTuple struct {
|
|||
end savepoint
|
||||
}
|
||||
|
||||
const choiceNoMatch = -1
|
||||
|
||||
// Stats stores some statistics, gathered during parsing
|
||||
type Stats struct {
|
||||
// ExprCnt counts the number of expressions processed during parsing
|
||||
// This value is compared to the maximum number of expressions allowed
|
||||
// (set by the MaxExpressions option).
|
||||
ExprCnt uint64
|
||||
|
||||
// ChoiceAltCnt is used to count for each ordered choice expression,
|
||||
// which alternative is used how may times.
|
||||
// These numbers allow to optimize the order of the ordered choice expression
|
||||
// to increase the performance of the parser
|
||||
//
|
||||
// The outer key of ChoiceAltCnt is composed of the name of the rule as well
|
||||
// as the line and the column of the ordered choice.
|
||||
// The inner key of ChoiceAltCnt is the number (one-based) of the matching alternative.
|
||||
// For each alternative the number of matches are counted. If an ordered choice does not
|
||||
// match, a special counter is incremented. The name of this counter is set with
|
||||
// the parser option Statistics.
|
||||
// For an alternative to be included in ChoiceAltCnt, it has to match at least once.
|
||||
ChoiceAltCnt map[string]map[string]int
|
||||
}
|
||||
|
||||
type parser struct {
|
||||
filename string
|
||||
pt savepoint
|
||||
|
@ -1245,9 +1061,9 @@ type parser struct {
|
|||
data []byte
|
||||
errs *errList
|
||||
|
||||
depth int
|
||||
recover bool
|
||||
debug bool
|
||||
depth int
|
||||
|
||||
memoize bool
|
||||
// memoization table for the packrat algorithm:
|
||||
|
@ -1261,23 +1077,8 @@ type parser struct {
|
|||
// rule stack, allows identification of the current rule in errors
|
||||
rstack []*rule
|
||||
|
||||
// parse fail
|
||||
maxFailPos position
|
||||
maxFailExpected []string
|
||||
maxFailInvertExpected bool
|
||||
|
||||
// max number of expressions to be parsed
|
||||
maxExprCnt uint64
|
||||
// entrypoint for the parser
|
||||
entrypoint string
|
||||
|
||||
allowInvalidUTF8 bool
|
||||
|
||||
*Stats
|
||||
|
||||
choiceNoMatch string
|
||||
// recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse
|
||||
recoveryStack []map[string]interface{}
|
||||
// stats
|
||||
exprCnt int
|
||||
}
|
||||
|
||||
// push a variable set on the vstack.
|
||||
|
@ -1312,31 +1113,6 @@ func (p *parser) popV() {
|
|||
p.vstack = p.vstack[:len(p.vstack)-1]
|
||||
}
|
||||
|
||||
// push a recovery expression with its labels to the recoveryStack
|
||||
func (p *parser) pushRecovery(labels []string, expr interface{}) {
|
||||
if cap(p.recoveryStack) == len(p.recoveryStack) {
|
||||
// create new empty slot in the stack
|
||||
p.recoveryStack = append(p.recoveryStack, nil)
|
||||
} else {
|
||||
// slice to 1 more
|
||||
p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)+1]
|
||||
}
|
||||
|
||||
m := make(map[string]interface{}, len(labels))
|
||||
for _, fl := range labels {
|
||||
m[fl] = expr
|
||||
}
|
||||
p.recoveryStack[len(p.recoveryStack)-1] = m
|
||||
}
|
||||
|
||||
// pop a recovery expression from the recoveryStack
|
||||
func (p *parser) popRecovery() {
|
||||
// GC that map
|
||||
p.recoveryStack[len(p.recoveryStack)-1] = nil
|
||||
|
||||
p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)-1]
|
||||
}
|
||||
|
||||
func (p *parser) print(prefix, s string) string {
|
||||
if !p.debug {
|
||||
return s
|
||||
|
@ -1358,10 +1134,10 @@ func (p *parser) out(s string) string {
|
|||
}
|
||||
|
||||
func (p *parser) addErr(err error) {
|
||||
p.addErrAt(err, p.pt.position, []string{})
|
||||
p.addErrAt(err, p.pt.position)
|
||||
}
|
||||
|
||||
func (p *parser) addErrAt(err error, pos position, expected []string) {
|
||||
func (p *parser) addErrAt(err error, pos position) {
|
||||
var buf bytes.Buffer
|
||||
if p.filename != "" {
|
||||
buf.WriteString(p.filename)
|
||||
|
@ -1381,29 +1157,10 @@ func (p *parser) addErrAt(err error, pos position, expected []string) {
|
|||
buf.WriteString("rule " + rule.name)
|
||||
}
|
||||
}
|
||||
pe := &parserError{Inner: err, pos: pos, prefix: buf.String(), expected: expected}
|
||||
pe := &parserError{Inner: err, pos: pos, prefix: buf.String()}
|
||||
p.errs.add(pe)
|
||||
}
|
||||
|
||||
func (p *parser) failAt(fail bool, pos position, want string) {
|
||||
// process fail if parsing fails and not inverted or parsing succeeds and invert is set
|
||||
if fail == p.maxFailInvertExpected {
|
||||
if pos.offset < p.maxFailPos.offset {
|
||||
return
|
||||
}
|
||||
|
||||
if pos.offset > p.maxFailPos.offset {
|
||||
p.maxFailPos = pos
|
||||
p.maxFailExpected = p.maxFailExpected[:0]
|
||||
}
|
||||
|
||||
if p.maxFailInvertExpected {
|
||||
want = "!" + want
|
||||
}
|
||||
p.maxFailExpected = append(p.maxFailExpected, want)
|
||||
}
|
||||
}
|
||||
|
||||
// read advances the parser to the next rune.
|
||||
func (p *parser) read() {
|
||||
p.pt.offset += p.pt.w
|
||||
|
@ -1416,8 +1173,8 @@ func (p *parser) read() {
|
|||
p.pt.col = 0
|
||||
}
|
||||
|
||||
if rn == utf8.RuneError && n == 1 { // see utf8.DecodeRune
|
||||
if !p.allowInvalidUTF8 {
|
||||
if rn == utf8.RuneError {
|
||||
if n == 1 {
|
||||
p.addErr(errInvalidEncoding)
|
||||
}
|
||||
}
|
||||
|
@ -1434,43 +1191,6 @@ func (p *parser) restore(pt savepoint) {
|
|||
p.pt = pt
|
||||
}
|
||||
|
||||
// Cloner is implemented by any value that has a Clone method, which returns a
|
||||
// copy of the value. This is mainly used for types which are not passed by
|
||||
// value (e.g map, slice, chan) or structs that contain such types.
|
||||
//
|
||||
// This is used in conjunction with the global state feature to create proper
|
||||
// copies of the state to allow the parser to properly restore the state in
|
||||
// the case of backtracking.
|
||||
type Cloner interface {
|
||||
Clone() interface{}
|
||||
}
|
||||
|
||||
// clone and return parser current state.
|
||||
func (p *parser) cloneState() storeDict {
|
||||
if p.debug {
|
||||
defer p.out(p.in("cloneState"))
|
||||
}
|
||||
|
||||
state := make(storeDict, len(p.cur.state))
|
||||
for k, v := range p.cur.state {
|
||||
if c, ok := v.(Cloner); ok {
|
||||
state[k] = c.Clone()
|
||||
} else {
|
||||
state[k] = v
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
// restore parser current state to the state storeDict.
|
||||
// every restoreState should applied only one time for every cloned state
|
||||
func (p *parser) restoreState(state storeDict) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("restoreState"))
|
||||
}
|
||||
p.cur.state = state
|
||||
}
|
||||
|
||||
// get the slice of bytes from the savepoint start to the current position.
|
||||
func (p *parser) sliceFrom(start savepoint) []byte {
|
||||
return p.data[start.position.offset:p.pt.position.offset]
|
||||
|
@ -1536,54 +1256,19 @@ func (p *parser) parse(g *grammar) (val interface{}, err error) {
|
|||
}()
|
||||
}
|
||||
|
||||
startRule, ok := p.rules[p.entrypoint]
|
||||
if !ok {
|
||||
p.addErr(errInvalidEntrypoint)
|
||||
return nil, p.errs.err()
|
||||
}
|
||||
|
||||
// start rule is rule [0]
|
||||
p.read() // advance to first rune
|
||||
val, ok = p.parseRule(startRule)
|
||||
val, ok := p.parseRule(g.rules[0])
|
||||
if !ok {
|
||||
if len(*p.errs) == 0 {
|
||||
// If parsing fails, but no errors have been recorded, the expected values
|
||||
// for the farthest parser position are returned as error.
|
||||
maxFailExpectedMap := make(map[string]struct{}, len(p.maxFailExpected))
|
||||
for _, v := range p.maxFailExpected {
|
||||
maxFailExpectedMap[v] = struct{}{}
|
||||
}
|
||||
expected := make([]string, 0, len(maxFailExpectedMap))
|
||||
eof := false
|
||||
if _, ok := maxFailExpectedMap["!."]; ok {
|
||||
delete(maxFailExpectedMap, "!.")
|
||||
eof = true
|
||||
}
|
||||
for k := range maxFailExpectedMap {
|
||||
expected = append(expected, k)
|
||||
}
|
||||
sort.Strings(expected)
|
||||
if eof {
|
||||
expected = append(expected, "EOF")
|
||||
}
|
||||
p.addErrAt(errors.New("no match found, expected: "+listJoin(expected, ", ", "or")), p.maxFailPos, expected)
|
||||
// make sure this doesn't go out silently
|
||||
p.addErr(errNoMatch)
|
||||
}
|
||||
|
||||
return nil, p.errs.err()
|
||||
}
|
||||
return val, p.errs.err()
|
||||
}
|
||||
|
||||
func listJoin(list []string, sep string, lastSep string) string {
|
||||
switch len(list) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
return list[0]
|
||||
default:
|
||||
return fmt.Sprintf("%s %s %s", strings.Join(list[:len(list)-1], sep), lastSep, list[len(list)-1])
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseRule(rule *rule) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseRule " + rule.name))
|
||||
|
@ -1615,6 +1300,7 @@ func (p *parser) parseRule(rule *rule) (interface{}, bool) {
|
|||
|
||||
func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
|
||||
var pt savepoint
|
||||
var ok bool
|
||||
|
||||
if p.memoize {
|
||||
res, ok := p.getMemoized(expr)
|
||||
|
@ -1625,13 +1311,8 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
|
|||
pt = p.pt
|
||||
}
|
||||
|
||||
p.ExprCnt++
|
||||
if p.ExprCnt > p.maxExprCnt {
|
||||
panic(errMaxExprCnt)
|
||||
}
|
||||
|
||||
p.exprCnt++
|
||||
var val interface{}
|
||||
var ok bool
|
||||
switch expr := expr.(type) {
|
||||
case *actionExpr:
|
||||
val, ok = p.parseActionExpr(expr)
|
||||
|
@ -1655,16 +1336,10 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
|
|||
val, ok = p.parseNotExpr(expr)
|
||||
case *oneOrMoreExpr:
|
||||
val, ok = p.parseOneOrMoreExpr(expr)
|
||||
case *recoveryExpr:
|
||||
val, ok = p.parseRecoveryExpr(expr)
|
||||
case *ruleRefExpr:
|
||||
val, ok = p.parseRuleRefExpr(expr)
|
||||
case *seqExpr:
|
||||
val, ok = p.parseSeqExpr(expr)
|
||||
case *stateCodeExpr:
|
||||
val, ok = p.parseStateCodeExpr(expr)
|
||||
case *throwExpr:
|
||||
val, ok = p.parseThrowExpr(expr)
|
||||
case *zeroOrMoreExpr:
|
||||
val, ok = p.parseZeroOrMoreExpr(expr)
|
||||
case *zeroOrOneExpr:
|
||||
|
@ -1688,13 +1363,10 @@ func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) {
|
|||
if ok {
|
||||
p.cur.pos = start.position
|
||||
p.cur.text = p.sliceFrom(start)
|
||||
state := p.cloneState()
|
||||
actVal, err := act.run(p)
|
||||
if err != nil {
|
||||
p.addErrAt(err, start.position, []string{})
|
||||
p.addErrAt(err, start.position)
|
||||
}
|
||||
p.restoreState(state)
|
||||
|
||||
val = actVal
|
||||
}
|
||||
if ok && p.debug {
|
||||
|
@ -1708,14 +1380,10 @@ func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) {
|
|||
defer p.out(p.in("parseAndCodeExpr"))
|
||||
}
|
||||
|
||||
state := p.cloneState()
|
||||
|
||||
ok, err := and.run(p)
|
||||
if err != nil {
|
||||
p.addErr(err)
|
||||
}
|
||||
p.restoreState(state)
|
||||
|
||||
return nil, ok
|
||||
}
|
||||
|
||||
|
@ -1725,13 +1393,10 @@ func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) {
|
|||
}
|
||||
|
||||
pt := p.pt
|
||||
state := p.cloneState()
|
||||
p.pushV()
|
||||
_, ok := p.parseExpr(and.expr)
|
||||
p.popV()
|
||||
p.restoreState(state)
|
||||
p.restore(pt)
|
||||
|
||||
return nil, ok
|
||||
}
|
||||
|
||||
|
@ -1740,15 +1405,12 @@ func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) {
|
|||
defer p.out(p.in("parseAnyMatcher"))
|
||||
}
|
||||
|
||||
if p.pt.rn == utf8.RuneError && p.pt.w == 0 {
|
||||
// EOF - see utf8.DecodeRune
|
||||
p.failAt(false, p.pt.position, ".")
|
||||
return nil, false
|
||||
if p.pt.rn != utf8.RuneError {
|
||||
start := p.pt
|
||||
p.read()
|
||||
return p.sliceFrom(start), true
|
||||
}
|
||||
start := p.pt
|
||||
p.read()
|
||||
p.failAt(true, start.position, ".")
|
||||
return p.sliceFrom(start), true
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) {
|
||||
|
@ -1757,14 +1419,11 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool
|
|||
}
|
||||
|
||||
cur := p.pt.rn
|
||||
start := p.pt
|
||||
|
||||
// can't match EOF
|
||||
if cur == utf8.RuneError && p.pt.w == 0 { // see utf8.DecodeRune
|
||||
p.failAt(false, start.position, chr.val)
|
||||
if cur == utf8.RuneError {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
start := p.pt
|
||||
if chr.ignoreCase {
|
||||
cur = unicode.ToLower(cur)
|
||||
}
|
||||
|
@ -1773,11 +1432,9 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool
|
|||
for _, rn := range chr.chars {
|
||||
if rn == cur {
|
||||
if chr.inverted {
|
||||
p.failAt(false, start.position, chr.val)
|
||||
return nil, false
|
||||
}
|
||||
p.read()
|
||||
p.failAt(true, start.position, chr.val)
|
||||
return p.sliceFrom(start), true
|
||||
}
|
||||
}
|
||||
|
@ -1786,11 +1443,9 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool
|
|||
for i := 0; i < len(chr.ranges); i += 2 {
|
||||
if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] {
|
||||
if chr.inverted {
|
||||
p.failAt(false, start.position, chr.val)
|
||||
return nil, false
|
||||
}
|
||||
p.read()
|
||||
p.failAt(true, start.position, chr.val)
|
||||
return p.sliceFrom(start), true
|
||||
}
|
||||
}
|
||||
|
@ -1799,60 +1454,33 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool
|
|||
for _, cl := range chr.classes {
|
||||
if unicode.Is(cl, cur) {
|
||||
if chr.inverted {
|
||||
p.failAt(false, start.position, chr.val)
|
||||
return nil, false
|
||||
}
|
||||
p.read()
|
||||
p.failAt(true, start.position, chr.val)
|
||||
return p.sliceFrom(start), true
|
||||
}
|
||||
}
|
||||
|
||||
if chr.inverted {
|
||||
p.read()
|
||||
p.failAt(true, start.position, chr.val)
|
||||
return p.sliceFrom(start), true
|
||||
}
|
||||
p.failAt(false, start.position, chr.val)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (p *parser) incChoiceAltCnt(ch *choiceExpr, altI int) {
|
||||
choiceIdent := fmt.Sprintf("%s %d:%d", p.rstack[len(p.rstack)-1].name, ch.pos.line, ch.pos.col)
|
||||
m := p.ChoiceAltCnt[choiceIdent]
|
||||
if m == nil {
|
||||
m = make(map[string]int)
|
||||
p.ChoiceAltCnt[choiceIdent] = m
|
||||
}
|
||||
// We increment altI by 1, so the keys do not start at 0
|
||||
alt := strconv.Itoa(altI + 1)
|
||||
if altI == choiceNoMatch {
|
||||
alt = p.choiceNoMatch
|
||||
}
|
||||
m[alt]++
|
||||
}
|
||||
|
||||
func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseChoiceExpr"))
|
||||
}
|
||||
|
||||
for altI, alt := range ch.alternatives {
|
||||
// dummy assignment to prevent compile error if optimized
|
||||
_ = altI
|
||||
|
||||
state := p.cloneState()
|
||||
|
||||
for _, alt := range ch.alternatives {
|
||||
p.pushV()
|
||||
val, ok := p.parseExpr(alt)
|
||||
p.popV()
|
||||
if ok {
|
||||
p.incChoiceAltCnt(ch, altI)
|
||||
return val, ok
|
||||
}
|
||||
p.restoreState(state)
|
||||
}
|
||||
p.incChoiceAltCnt(ch, choiceNoMatch)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
|
@ -1876,11 +1504,6 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) {
|
|||
defer p.out(p.in("parseLitMatcher"))
|
||||
}
|
||||
|
||||
ignoreCase := ""
|
||||
if lit.ignoreCase {
|
||||
ignoreCase = "i"
|
||||
}
|
||||
val := fmt.Sprintf("%q%s", lit.val, ignoreCase)
|
||||
start := p.pt
|
||||
for _, want := range lit.val {
|
||||
cur := p.pt.rn
|
||||
|
@ -1888,13 +1511,11 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) {
|
|||
cur = unicode.ToLower(cur)
|
||||
}
|
||||
if cur != want {
|
||||
p.failAt(false, start.position, val)
|
||||
p.restore(start)
|
||||
return nil, false
|
||||
}
|
||||
p.read()
|
||||
}
|
||||
p.failAt(true, start.position, val)
|
||||
return p.sliceFrom(start), true
|
||||
}
|
||||
|
||||
|
@ -1903,14 +1524,10 @@ func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) {
|
|||
defer p.out(p.in("parseNotCodeExpr"))
|
||||
}
|
||||
|
||||
state := p.cloneState()
|
||||
|
||||
ok, err := not.run(p)
|
||||
if err != nil {
|
||||
p.addErr(err)
|
||||
}
|
||||
p.restoreState(state)
|
||||
|
||||
return nil, !ok
|
||||
}
|
||||
|
||||
|
@ -1920,15 +1537,10 @@ func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) {
|
|||
}
|
||||
|
||||
pt := p.pt
|
||||
state := p.cloneState()
|
||||
p.pushV()
|
||||
p.maxFailInvertExpected = !p.maxFailInvertExpected
|
||||
_, ok := p.parseExpr(not.expr)
|
||||
p.maxFailInvertExpected = !p.maxFailInvertExpected
|
||||
p.popV()
|
||||
p.restoreState(state)
|
||||
p.restore(pt)
|
||||
|
||||
return nil, !ok
|
||||
}
|
||||
|
||||
|
@ -1954,18 +1566,6 @@ func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseRecoveryExpr(recover *recoveryExpr) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseRecoveryExpr (" + strings.Join(recover.failureLabel, ",") + ")"))
|
||||
}
|
||||
|
||||
p.pushRecovery(recover.failureLabel, recover.recoverExpr)
|
||||
val, ok := p.parseExpr(recover.expr)
|
||||
p.popRecovery()
|
||||
|
||||
return val, ok
|
||||
}
|
||||
|
||||
func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseRuleRefExpr " + ref.name))
|
||||
|
@ -1988,14 +1588,12 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) {
|
|||
defer p.out(p.in("parseSeqExpr"))
|
||||
}
|
||||
|
||||
vals := make([]interface{}, 0, len(seq.exprs))
|
||||
var vals []interface{}
|
||||
|
||||
pt := p.pt
|
||||
state := p.cloneState()
|
||||
for _, expr := range seq.exprs {
|
||||
val, ok := p.parseExpr(expr)
|
||||
if !ok {
|
||||
p.restoreState(state)
|
||||
p.restore(pt)
|
||||
return nil, false
|
||||
}
|
||||
|
@ -2004,34 +1602,6 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) {
|
|||
return vals, true
|
||||
}
|
||||
|
||||
func (p *parser) parseStateCodeExpr(state *stateCodeExpr) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseStateCodeExpr"))
|
||||
}
|
||||
|
||||
err := state.run(p)
|
||||
if err != nil {
|
||||
p.addErr(err)
|
||||
}
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func (p *parser) parseThrowExpr(expr *throwExpr) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseThrowExpr"))
|
||||
}
|
||||
|
||||
for i := len(p.recoveryStack) - 1; i >= 0; i-- {
|
||||
if recoverExpr, ok := p.recoveryStack[i][expr.label]; ok {
|
||||
if val, ok := p.parseExpr(recoverExpr); ok {
|
||||
return val, ok
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) {
|
||||
if p.debug {
|
||||
defer p.out(p.in("parseZeroOrMoreExpr"))
|
||||
|
@ -2061,3 +1631,18 @@ func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) {
|
|||
// whether it matched or not, consider it a match
|
||||
return val, true
|
||||
}
|
||||
|
||||
func rangeTable(class string) *unicode.RangeTable {
|
||||
if rt, ok := unicode.Categories[class]; ok {
|
||||
return rt
|
||||
}
|
||||
if rt, ok := unicode.Properties[class]; ok {
|
||||
return rt
|
||||
}
|
||||
if rt, ok := unicode.Scripts[class]; ok {
|
||||
return rt
|
||||
}
|
||||
|
||||
// cannot happen
|
||||
panic(fmt.Sprintf("invalid Unicode class: %s", class))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"variables": {
|
||||
"ucloud_public_key": "{{env `UCLOUD_PUBLIC_KEY`}}",
|
||||
"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-regionCopy-bj",
|
||||
"image_copy_to_mappings": [{
|
||||
"project_id": "org-fthbzm",
|
||||
"region": "cn-sh2",
|
||||
"description": "test"
|
||||
}]
|
||||
}],
|
||||
"provisioners": [{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"yum install mysql -y"
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
3
go.mod
3
go.mod
|
@ -80,6 +80,7 @@ require (
|
|||
github.com/mitchellh/panicwrap v0.0.0-20170106182340-fce601fe5557
|
||||
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784
|
||||
github.com/mitchellh/reflectwalk v1.0.0
|
||||
github.com/mna/pigeon v1.0.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/moul/anonuuid v0.0.0-20160222162117-609b752a95ef // indirect
|
||||
|
@ -103,6 +104,7 @@ require (
|
|||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181220135002-f1744d40d346
|
||||
github.com/ucloud/ucloud-sdk-go v0.8.6
|
||||
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
|
||||
|
@ -115,6 +117,7 @@ require (
|
|||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
golang.org/x/sys v0.0.0-20190425145619-16072639606e
|
||||
golang.org/x/text v0.3.1 // indirect
|
||||
golang.org/x/tools v0.0.0-20190612232758-d4e310b4a8a5 // indirect
|
||||
google.golang.org/api v0.3.1
|
||||
google.golang.org/grpc v1.19.1
|
||||
gopkg.in/h2non/gock.v1 v1.0.12 // indirect
|
||||
|
|
12
go.sum
12
go.sum
|
@ -291,6 +291,8 @@ github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784 h1:+DAetXqxv/
|
|||
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mna/pigeon v1.0.0 h1:n46IoStjdzjaXuyBH53j9HZ8CVqGWpC7P5/v8dP4qEY=
|
||||
github.com/mna/pigeon v1.0.0/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
|
@ -384,6 +386,8 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED
|
|||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w=
|
||||
|
@ -400,6 +404,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181220135002-f1744d40d346 h1:a014AaXz7AISMePv8xKRffUZZkr5z2XmSDf41gRV3+A=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181220135002-f1744d40d346/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/ucloud/ucloud-sdk-go v0.8.6 h1:TBdjokuRMjrFXWEXXXOFXd5B6XStunQJmXxPNvMBaCQ=
|
||||
github.com/ucloud/ucloud-sdk-go v0.8.6/go.mod h1:lM6fpI8y6iwACtlbHUav823/uKPdXsNBlnBpRF2fj3c=
|
||||
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=
|
||||
|
@ -499,6 +505,12 @@ golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7 h1:WxK+jPGx5s7BushiqEK+KKKSELWPhIEaIDJKU052UKU=
|
||||
golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b h1:/mJ+GKieZA6hFDQGdWZrjj4AXPl5ylY+5HusG80roy0=
|
||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190612232758-d4e310b4a8a5 h1:WfRBLVK37R+k1gUOKuZX8JtangyEXmuopHz5tazlZRo=
|
||||
golang.org/x/tools v0.0.0-20190612232758-d4e310b4a8a5/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI=
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
language: go
|
||||
go_import_path: github.com/sirupsen/logrus
|
||||
env:
|
||||
- GOMAXPROCS=4 GORACE=halt_on_error=1
|
||||
matrix:
|
||||
|
|
|
@ -361,6 +361,7 @@ The built-in logging formatters are:
|
|||
Third party logging formatters:
|
||||
|
||||
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
|
||||
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
|
||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||
|
|
|
@ -108,23 +108,34 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
|||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
var field_err string
|
||||
fieldErr := entry.err
|
||||
for k, v := range fields {
|
||||
if t := reflect.TypeOf(v); t != nil && t.Kind() == reflect.Func {
|
||||
field_err = fmt.Sprintf("can not add field %q", k)
|
||||
if entry.err != "" {
|
||||
field_err = entry.err + ", " + field_err
|
||||
isErrField := false
|
||||
if t := reflect.TypeOf(v); t != nil {
|
||||
switch t.Kind() {
|
||||
case reflect.Func:
|
||||
isErrField = true
|
||||
case reflect.Ptr:
|
||||
isErrField = t.Elem().Kind() == reflect.Func
|
||||
}
|
||||
}
|
||||
if isErrField {
|
||||
tmp := fmt.Sprintf("can not add field %q", k)
|
||||
if fieldErr != "" {
|
||||
fieldErr = entry.err + ", " + tmp
|
||||
} else {
|
||||
fieldErr = tmp
|
||||
}
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: field_err}
|
||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr}
|
||||
}
|
||||
|
||||
// Overrides the time of the Entry.
|
||||
func (entry *Entry) WithTime(t time.Time) *Entry {
|
||||
return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t}
|
||||
return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err}
|
||||
}
|
||||
|
||||
// getPackageName reduces a fully qualified function name to the package name
|
||||
|
@ -240,16 +251,18 @@ func (entry *Entry) write() {
|
|||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Trace(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(TraceLevel) {
|
||||
entry.log(TraceLevel, fmt.Sprint(args...))
|
||||
func (entry *Entry) Log(level Level, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.log(level, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Trace(args ...interface{}) {
|
||||
entry.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(DebugLevel) {
|
||||
entry.log(DebugLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Print(args ...interface{}) {
|
||||
|
@ -257,15 +270,11 @@ func (entry *Entry) Print(args ...interface{}) {
|
|||
}
|
||||
|
||||
func (entry *Entry) Info(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(InfoLevel) {
|
||||
entry.log(InfoLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warn(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(WarnLevel) {
|
||||
entry.log(WarnLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warning(args ...interface{}) {
|
||||
|
@ -273,43 +282,35 @@ func (entry *Entry) Warning(args ...interface{}) {
|
|||
}
|
||||
|
||||
func (entry *Entry) Error(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(ErrorLevel) {
|
||||
entry.log(ErrorLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatal(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(FatalLevel) {
|
||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(FatalLevel, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(PanicLevel) {
|
||||
entry.log(PanicLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(PanicLevel, args...)
|
||||
panic(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// Entry Printf family functions
|
||||
|
||||
func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
|
||||
entry.Log(level, fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func (entry *Entry) Tracef(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(TraceLevel) {
|
||||
entry.Trace(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(TraceLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(DebugLevel) {
|
||||
entry.Debug(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(InfoLevel) {
|
||||
entry.Info(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
||||
|
@ -317,9 +318,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(WarnLevel) {
|
||||
entry.Warn(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
||||
|
@ -327,42 +326,36 @@ func (entry *Entry) Warningf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(ErrorLevel) {
|
||||
entry.Error(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(FatalLevel) {
|
||||
entry.Fatal(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(FatalLevel, format, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(PanicLevel) {
|
||||
entry.Panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(PanicLevel, format, args...)
|
||||
}
|
||||
|
||||
// Entry Println family functions
|
||||
|
||||
func (entry *Entry) Traceln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(TraceLevel) {
|
||||
entry.Trace(entry.sprintlnn(args...))
|
||||
func (entry *Entry) Logln(level Level, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.Log(level, entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Traceln(args ...interface{}) {
|
||||
entry.Logln(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debugln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(DebugLevel) {
|
||||
entry.Debug(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Infoln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(InfoLevel) {
|
||||
entry.Info(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Println(args ...interface{}) {
|
||||
|
@ -370,9 +363,7 @@ func (entry *Entry) Println(args ...interface{}) {
|
|||
}
|
||||
|
||||
func (entry *Entry) Warnln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(WarnLevel) {
|
||||
entry.Warn(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningln(args ...interface{}) {
|
||||
|
@ -380,22 +371,16 @@ func (entry *Entry) Warningln(args ...interface{}) {
|
|||
}
|
||||
|
||||
func (entry *Entry) Errorln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(ErrorLevel) {
|
||||
entry.Error(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(FatalLevel) {
|
||||
entry.Fatal(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(FatalLevel, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(PanicLevel) {
|
||||
entry.Panic(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(PanicLevel, args...)
|
||||
}
|
||||
|
||||
// Sprintlnn => Sprint no newline. This is to get the behavior of how
|
||||
|
|
|
@ -131,28 +131,24 @@ func (logger *Logger) WithTime(t time.Time) *Entry {
|
|||
return entry.WithTime(t)
|
||||
}
|
||||
|
||||
func (logger *Logger) Tracef(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(TraceLevel) {
|
||||
func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Tracef(format, args...)
|
||||
entry.Logf(level, format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Tracef(format string, args ...interface{}) {
|
||||
logger.Logf(TraceLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(DebugLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Debugf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(InfoLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Infof(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
|
@ -162,68 +158,44 @@ func (logger *Logger) Printf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(WarnLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(WarnLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Warnf(format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(ErrorLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Errorf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(FatalLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(FatalLevel, format, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(PanicLevel) {
|
||||
logger.Logf(PanicLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Log(level Level, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Panicf(format, args...)
|
||||
entry.Log(level, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Trace(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(TraceLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Trace(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(DebugLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Debug(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(InfoLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
|
@ -233,68 +205,44 @@ func (logger *Logger) Print(args ...interface{}) {
|
|||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(WarnLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(WarnLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Warn(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(ErrorLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Error(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(FatalLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatal(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(PanicLevel) {
|
||||
logger.Log(PanicLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Logln(level Level, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Panic(args...)
|
||||
entry.Logln(level, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Traceln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(TraceLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Traceln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(DebugLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Debugln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(InfoLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Infoln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
|
@ -304,44 +252,24 @@ func (logger *Logger) Println(args ...interface{}) {
|
|||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(WarnLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(WarnLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Warn(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(ErrorLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Errorln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(FatalLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
if logger.IsLevelEnabled(PanicLevel) {
|
||||
entry := logger.newEntry()
|
||||
entry.Panicln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(PanicLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Exit(code int) {
|
||||
|
|
|
@ -14,24 +14,11 @@ type Level uint32
|
|||
|
||||
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
|
||||
func (level Level) String() string {
|
||||
switch level {
|
||||
case TraceLevel:
|
||||
return "trace"
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarnLevel:
|
||||
return "warning"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case FatalLevel:
|
||||
return "fatal"
|
||||
case PanicLevel:
|
||||
return "panic"
|
||||
if b, err := level.MarshalText(); err == nil {
|
||||
return string(b)
|
||||
} else {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||
|
@ -69,6 +56,27 @@ func (level *Level) UnmarshalText(text []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (level Level) MarshalText() ([]byte, error) {
|
||||
switch level {
|
||||
case TraceLevel:
|
||||
return []byte("trace"), nil
|
||||
case DebugLevel:
|
||||
return []byte("debug"), nil
|
||||
case InfoLevel:
|
||||
return []byte("info"), nil
|
||||
case WarnLevel:
|
||||
return []byte("warning"), nil
|
||||
case ErrorLevel:
|
||||
return []byte("error"), nil
|
||||
case FatalLevel:
|
||||
return []byte("fatal"), nil
|
||||
case PanicLevel:
|
||||
return []byte("panic"), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not a valid lorus level %q", level)
|
||||
}
|
||||
|
||||
// A constant exposing all logging levels
|
||||
var AllLevels = []Level{
|
||||
PanicLevel,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// +build !appengine,!js,!windows,aix
|
||||
|
||||
package logrus
|
||||
|
||||
import "io"
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
return false
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !appengine,!js,!windows
|
||||
// +build !appengine,!js,!windows,!aix
|
||||
|
||||
package logrus
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -90,7 +91,7 @@ func (f *TextFormatter) init(entry *Entry) {
|
|||
}
|
||||
|
||||
func (f *TextFormatter) isColored() bool {
|
||||
isColored := f.ForceColors || f.isTerminal
|
||||
isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
|
||||
|
||||
if f.EnvironmentOverrideColors {
|
||||
if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" {
|
||||
|
@ -107,14 +108,17 @@ func (f *TextFormatter) isColored() bool {
|
|||
|
||||
// Format renders a single log entry
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
prefixFieldClashes(entry.Data, f.FieldMap, entry.HasCaller())
|
||||
|
||||
keys := make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
data := make(Fields)
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
||||
keys := make([]string, 0, len(data))
|
||||
for k := range data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
fixedKeys := make([]string, 0, 4+len(entry.Data))
|
||||
fixedKeys := make([]string, 0, 4+len(data))
|
||||
if !f.DisableTimestamp {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
|
||||
}
|
||||
|
@ -160,7 +164,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||
timestampFormat = defaultTimestampFormat
|
||||
}
|
||||
if f.isColored() {
|
||||
f.printColored(b, entry, keys, timestampFormat)
|
||||
f.printColored(b, entry, keys, data, timestampFormat)
|
||||
} else {
|
||||
for _, key := range fixedKeys {
|
||||
var value interface{}
|
||||
|
@ -178,7 +182,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||
case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
|
||||
value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
default:
|
||||
value = entry.Data[key]
|
||||
value = data[key]
|
||||
}
|
||||
f.appendKeyValue(b, key, value)
|
||||
}
|
||||
|
@ -188,7 +192,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel, TraceLevel:
|
||||
|
@ -225,7 +229,7 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
|||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
v := data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||
f.appendValue(b, v)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
80
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/client.go
generated
vendored
Normal file
80
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/client.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Package http is an implementation of http protocol
|
||||
*/
|
||||
package http
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Client is the interface of http client
|
||||
type Client interface {
|
||||
Send(*HttpRequest) (*HttpResponse, error)
|
||||
}
|
||||
|
||||
// HttpClient used to send a real request via http to server
|
||||
type HttpClient struct {
|
||||
}
|
||||
|
||||
// NewHttpClient will create a new HttpClient instance
|
||||
func NewHttpClient() HttpClient {
|
||||
return HttpClient{}
|
||||
}
|
||||
|
||||
// Send will send a real http request to remote server
|
||||
func (c *HttpClient) Send(req *HttpRequest) (*HttpResponse, error) {
|
||||
// build http.Client with timeout settings
|
||||
httpClient, err := c.buildHTTPClient(req.GetTimeout())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// convert sdk http request to origin http.Request
|
||||
httpReq, err := req.buildHTTPRequest()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: enable tracer via `httptrace` package
|
||||
resp, err := c.doHTTPRequest(httpClient, httpReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *HttpClient) buildHTTPClient(timeout time.Duration) (*http.Client, error) {
|
||||
httpClient := http.Client{}
|
||||
if timeout != 0 {
|
||||
httpClient = http.Client{Timeout: timeout}
|
||||
}
|
||||
return &httpClient, nil
|
||||
}
|
||||
|
||||
func (c *HttpClient) doHTTPRequest(client *http.Client, req *http.Request) (*HttpResponse, error) {
|
||||
// send request
|
||||
httpResp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer httpResp.Body.Close()
|
||||
|
||||
// raise status error
|
||||
if httpResp.StatusCode >= 400 {
|
||||
return nil, NewStatusError(httpResp.StatusCode, httpResp.Status)
|
||||
}
|
||||
|
||||
// read content
|
||||
body, err := ioutil.ReadAll(httpResp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// build response wrapper
|
||||
resp := NewHttpResponse()
|
||||
resp.setHttpResponse(httpResp)
|
||||
resp.SetBody(body)
|
||||
return resp, nil
|
||||
}
|
21
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/defaults.go
generated
vendored
Normal file
21
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/defaults.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type mimeType string
|
||||
|
||||
const (
|
||||
mimeFormURLEncoded mimeType = "application/x-www-form-urlencoded"
|
||||
mimeJSON mimeType = "application/json"
|
||||
)
|
||||
|
||||
// DefaultHeaders defined default http headers
|
||||
var DefaultHeaders = map[string]string{
|
||||
"Content-Type": string(mimeFormURLEncoded),
|
||||
// "X-SDK-VERSION": VERSION,
|
||||
}
|
||||
|
||||
// DefaultTimeout is the default timeout of each request
|
||||
var DefaultTimeout = 30 * time.Second
|
23
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/error.go
generated
vendored
Normal file
23
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/error.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// StatusError is the error for http status code >= 400
|
||||
type StatusError struct {
|
||||
StatusCode int
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e StatusError) Error() string {
|
||||
return fmt.Sprintf("http status %v error", e.StatusCode)
|
||||
}
|
||||
|
||||
// NewStatusError will create a new status error
|
||||
func NewStatusError(code int, message string) StatusError {
|
||||
return StatusError{
|
||||
StatusCode: code,
|
||||
Message: message,
|
||||
}
|
||||
}
|
223
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/request.go
generated
vendored
Normal file
223
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/request.go
generated
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/ucloud/ucloud-sdk-go/private/utils"
|
||||
)
|
||||
|
||||
var availableHTTPMethods = []string{"GET", "POST", "PUT", "DELETE", "OPTION", "HEAD", "PATCH"}
|
||||
|
||||
// HttpRequest is the internal http request of sdk, don't use it at your code
|
||||
type HttpRequest struct {
|
||||
url string
|
||||
method string
|
||||
queryMap map[string]string
|
||||
queryString string
|
||||
headers map[string]string
|
||||
requestBody []byte
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// NewHttpRequest will create a http request
|
||||
func NewHttpRequest() *HttpRequest {
|
||||
r := &HttpRequest{
|
||||
queryMap: make(map[string]string),
|
||||
headers: make(map[string]string),
|
||||
timeout: DefaultTimeout,
|
||||
}
|
||||
|
||||
for k, v := range DefaultHeaders {
|
||||
r.headers[k] = v
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetURL will set url into request
|
||||
func (h *HttpRequest) SetURL(val string) error {
|
||||
// check url is valid
|
||||
uri, err := url.ParseRequestURI(val)
|
||||
if err != nil {
|
||||
return errors.Errorf("url is invalid, got %s", val)
|
||||
}
|
||||
|
||||
err = h.SetQueryString(uri.RawQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.url = fmt.Sprintf("%s://%s%s", uri.Scheme, uri.Host, uri.Path)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetURL will get request url value
|
||||
func (h *HttpRequest) GetURL() string {
|
||||
return h.url
|
||||
}
|
||||
|
||||
// SetMethod will set method of current request
|
||||
func (h *HttpRequest) SetMethod(val string) error {
|
||||
err := utils.CheckStringIn(val, availableHTTPMethods)
|
||||
if err != nil {
|
||||
return errors.Errorf("method is invalid, %s", err)
|
||||
}
|
||||
|
||||
h.method = strings.ToUpper(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMethod will get request url value
|
||||
func (h *HttpRequest) GetMethod() string {
|
||||
return h.method
|
||||
}
|
||||
|
||||
// SetQueryString will set query map by query string,
|
||||
// it also save as query string attribute to keep query ordered.
|
||||
func (h *HttpRequest) SetQueryString(val string) error {
|
||||
// check url query is valid
|
||||
values, err := url.ParseQuery(val)
|
||||
if err != nil {
|
||||
return errors.Errorf("url query is invalid, got %s", val)
|
||||
}
|
||||
|
||||
// copy url query into request query map, it will overwrite current query
|
||||
for k, v := range values {
|
||||
if len(v) > 0 {
|
||||
h.SetQuery(k, v[0])
|
||||
}
|
||||
}
|
||||
|
||||
h.queryString = val
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildQueryString will return the query string of this request,
|
||||
// it will also append key-value of query map after existed query string
|
||||
func (h *HttpRequest) BuildQueryString() (string, error) {
|
||||
values := url.Values{}
|
||||
for k, v := range h.queryMap {
|
||||
values.Add(k, v)
|
||||
}
|
||||
|
||||
// if query string is not set by user,
|
||||
// otherwise needn't keep them ordered, encode immediately.
|
||||
if h.queryString == "" {
|
||||
return values.Encode(), nil
|
||||
}
|
||||
|
||||
// exclude query that existed in query string pass by user,
|
||||
// to keep ordered from user definition
|
||||
existsValues, _ := url.ParseQuery(h.queryString)
|
||||
for k := range existsValues {
|
||||
values.Del(k)
|
||||
}
|
||||
|
||||
// append query map after existed query string
|
||||
qs := h.queryString
|
||||
if len(values) > 0 {
|
||||
qs += "&" + values.Encode()
|
||||
}
|
||||
|
||||
return qs, nil
|
||||
}
|
||||
|
||||
// SetQuery will store key-value data into query map
|
||||
func (h *HttpRequest) SetQuery(k, v string) error {
|
||||
if h.queryMap == nil {
|
||||
h.queryMap = make(map[string]string)
|
||||
}
|
||||
h.queryMap[k] = v
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetQuery will get value by key from map
|
||||
func (h *HttpRequest) GetQuery(k string) string {
|
||||
if v, ok := h.queryMap[k]; ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetQueryMap will get all of query as a map
|
||||
func (h *HttpRequest) GetQueryMap() map[string]string {
|
||||
return h.queryMap
|
||||
}
|
||||
|
||||
// SetTimeout will set timeout of current request
|
||||
func (h *HttpRequest) SetTimeout(val time.Duration) error {
|
||||
h.timeout = val
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTimeout will get timeout of current request
|
||||
func (h *HttpRequest) GetTimeout() time.Duration {
|
||||
return h.timeout
|
||||
}
|
||||
|
||||
// SetHeader will set http header of current request
|
||||
func (h *HttpRequest) SetHeader(k, v string) error {
|
||||
if h.headers == nil {
|
||||
h.headers = make(map[string]string)
|
||||
}
|
||||
h.headers[k] = v
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetHeaderMap wiil get all of header as a map
|
||||
func (h *HttpRequest) GetHeaderMap() map[string]string {
|
||||
return h.headers
|
||||
}
|
||||
|
||||
// SetRequestBody will set http body of current request
|
||||
func (h *HttpRequest) SetRequestBody(val []byte) error {
|
||||
h.requestBody = val
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRequestBody will get origin http request ("net/http")
|
||||
func (h *HttpRequest) GetRequestBody() []byte {
|
||||
return h.requestBody
|
||||
}
|
||||
|
||||
func (h *HttpRequest) String() string {
|
||||
if qs, err := h.BuildQueryString(); err == nil {
|
||||
return fmt.Sprintf("%s?%s", h.GetURL(), qs)
|
||||
}
|
||||
return h.GetURL()
|
||||
}
|
||||
|
||||
func (h *HttpRequest) getContentType() string {
|
||||
if v, ok := h.headers["Content-Type"]; ok {
|
||||
return v
|
||||
}
|
||||
return string(mimeFormURLEncoded)
|
||||
}
|
||||
|
||||
func (h *HttpRequest) buildHTTPRequest() (*http.Request, error) {
|
||||
qs, err := h.BuildQueryString()
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot build query string, %s", err)
|
||||
}
|
||||
|
||||
var httpReq *http.Request
|
||||
if h.getContentType() == string(mimeFormURLEncoded) && len(h.GetRequestBody()) == 0 {
|
||||
httpReq, err = http.NewRequest(h.GetMethod(), h.GetURL(), strings.NewReader(qs))
|
||||
} else {
|
||||
httpReq, err = http.NewRequest(h.GetMethod(), h.String(), bytes.NewReader(h.GetRequestBody()))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot build request, %s", err)
|
||||
}
|
||||
|
||||
for k, v := range utils.MergeMap(DefaultHeaders, h.GetHeaderMap()) {
|
||||
httpReq.Header.Set(k, v)
|
||||
}
|
||||
return httpReq, nil
|
||||
}
|
52
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/response.go
generated
vendored
Normal file
52
vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/response.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// HttpResponse is a simple wrapper of "net/http" response
|
||||
type HttpResponse struct {
|
||||
body []byte
|
||||
statusCode int
|
||||
originHttpResponse *http.Response // origin "net/http" response
|
||||
}
|
||||
|
||||
// NewHttpResponse will create a new response of http request
|
||||
func NewHttpResponse() *HttpResponse {
|
||||
return &HttpResponse{}
|
||||
}
|
||||
|
||||
// GetBody will get body from from sdk http request
|
||||
func (h *HttpResponse) GetBody() []byte {
|
||||
return h.body
|
||||
}
|
||||
|
||||
func (h *HttpResponse) GetHeaders() http.Header {
|
||||
if h.originHttpResponse == nil {
|
||||
return http.Header{}
|
||||
}
|
||||
return h.originHttpResponse.Header
|
||||
}
|
||||
|
||||
// SetBody will set body into http response
|
||||
// it usually used for restore the body already read from an stream
|
||||
// it will also cause extra memory usage
|
||||
func (h *HttpResponse) SetBody(body []byte) error {
|
||||
h.body = body
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetStatusCode will return status code of origin http response
|
||||
func (h *HttpResponse) GetStatusCode() int {
|
||||
return h.statusCode
|
||||
}
|
||||
|
||||
// SetStatusCode will return status code of origin http response
|
||||
func (h *HttpResponse) SetStatusCode(code int) {
|
||||
h.statusCode = code
|
||||
}
|
||||
|
||||
func (h *HttpResponse) setHttpResponse(resp *http.Response) {
|
||||
h.statusCode = resp.StatusCode
|
||||
h.originHttpResponse = resp
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ValueAtPath will get struct attribute value by recursive
|
||||
func ValueAtPath(v interface{}, path string) (interface{}, error) {
|
||||
components := strings.Split(path, ".")
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
for rv.Kind() == reflect.Ptr {
|
||||
if rv.IsNil() {
|
||||
return nil, errors.Errorf("object %#v is nil", v)
|
||||
}
|
||||
rv = rv.Elem()
|
||||
}
|
||||
|
||||
if rv.Kind() == reflect.Slice || rv.Kind() == reflect.Array {
|
||||
i, err := strconv.Atoi(components[0])
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("path %s is invalid at index of array", path)
|
||||
}
|
||||
|
||||
length := rv.Len()
|
||||
if i >= length {
|
||||
return nil, errors.Errorf("path %s is invalid, array has length %v, but got %v", path, length, i)
|
||||
}
|
||||
|
||||
itemV := rv.Index(i)
|
||||
if !itemV.IsValid() {
|
||||
return nil, errors.Errorf("path %s is invalid for map", path)
|
||||
}
|
||||
|
||||
if len(components) > 1 {
|
||||
return ValueAtPath(itemV.Interface(), strings.Join(components[1:], "."))
|
||||
}
|
||||
|
||||
return itemV.Interface(), nil
|
||||
}
|
||||
|
||||
if rv.Kind() == reflect.Map && !rv.IsNil() {
|
||||
itemV := rv.MapIndex(reflect.ValueOf(components[0]))
|
||||
if !itemV.IsValid() {
|
||||
return nil, errors.Errorf("path %s is invalid for map", path)
|
||||
}
|
||||
|
||||
if len(components) > 1 {
|
||||
return ValueAtPath(itemV.Interface(), strings.Join(components[1:], "."))
|
||||
}
|
||||
|
||||
return itemV.Interface(), nil
|
||||
}
|
||||
|
||||
if rv.Kind() == reflect.Struct {
|
||||
itemV := rv.FieldByName(components[0])
|
||||
if !itemV.IsValid() {
|
||||
return nil, errors.Errorf("path %s is invalid for struct", path)
|
||||
}
|
||||
|
||||
if len(components) > 1 {
|
||||
return ValueAtPath(itemV.Interface(), strings.Join(components[1:], "."))
|
||||
}
|
||||
|
||||
return itemV.Interface(), nil
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("object %#v is invalid, need map or struct", v)
|
||||
}
|
43
vendor/github.com/ucloud/ucloud-sdk-go/private/utils/collection.go
generated
vendored
Normal file
43
vendor/github.com/ucloud/ucloud-sdk-go/private/utils/collection.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MergeMap will merge two map and return a new map
|
||||
func MergeMap(args ...map[string]string) map[string]string {
|
||||
m := map[string]string{}
|
||||
for _, kv := range args {
|
||||
for k, v := range kv {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// SetMapIfNotExists will set a key-value of the map if the key is not exists
|
||||
func SetMapIfNotExists(m map[string]string, k string, v string) {
|
||||
if _, ok := m[k]; !ok && v != "" {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// IsStringIn will return if the value is contains by an array
|
||||
func IsStringIn(val string, availables []string) bool {
|
||||
for _, choice := range availables {
|
||||
if val == choice {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// CheckStringIn will check if the value is contains by an array
|
||||
func CheckStringIn(val string, availables []string) error {
|
||||
if IsStringIn(val, availables) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("got %s, should be one of %s", val, strings.Join(availables, ","))
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/*
|
||||
Package utils is the utilities to process internal data of sdk
|
||||
*/
|
||||
package utils
|
|
@ -0,0 +1,44 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Patch is the patch object to provider a converter function
|
||||
type Patch interface {
|
||||
Patch([]byte) []byte
|
||||
}
|
||||
|
||||
// RegexpPatcher a patch object to provider a converter function from regular expression
|
||||
type RegexpPatcher struct {
|
||||
pattern *regexp.Regexp
|
||||
replacement string
|
||||
}
|
||||
|
||||
// NewRegexpPatcher will return a patch object to provider a converter function from regular expression
|
||||
func NewRegexpPatcher(regex string, repl string) *RegexpPatcher {
|
||||
return &RegexpPatcher{
|
||||
pattern: regexp.MustCompile(regex),
|
||||
replacement: repl,
|
||||
}
|
||||
}
|
||||
|
||||
// Patch will convert a bytes to another bytes with patch rules
|
||||
func (p *RegexpPatcher) Patch(body []byte) []byte {
|
||||
// TODO: ensure why the pattern will be disabled when there are multiple goroutines for bytes replacement
|
||||
return []byte(p.PatchString(string(body)))
|
||||
}
|
||||
|
||||
// PatchString will convert a string to another string with patch rules
|
||||
func (p *RegexpPatcher) PatchString(body string) string {
|
||||
return p.pattern.ReplaceAllString(body, p.replacement)
|
||||
}
|
||||
|
||||
// RetCodePatcher will convert `RetCode` as integer
|
||||
var RetCodePatcher = NewRegexpPatcher(`"RetCode":\s?"(\d+)"`, `"RetCode": $1`)
|
||||
|
||||
// PortPatcher will convert `Port` as integer
|
||||
var PortPatcher = NewRegexpPatcher(`"Port":\s?"(\d+)"`, `"Port": $1`)
|
||||
|
||||
// FrequencePatcher will convert `Frequence` as float64
|
||||
var FrequencePatcher = NewRegexpPatcher(`"Frequence":\s?"([\d.]+)"`, `"Frequence": $1`)
|
|
@ -0,0 +1,53 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/log"
|
||||
)
|
||||
|
||||
// Waiter to wait sth until it completed.
|
||||
type Waiter interface {
|
||||
WaitForCompletion() error
|
||||
Cancel() error
|
||||
}
|
||||
|
||||
// FuncWaiter used for waiting any condition function.
|
||||
type FuncWaiter struct {
|
||||
Interval time.Duration
|
||||
MaxAttempts int
|
||||
Checker func() (bool, error)
|
||||
IgnoreError bool
|
||||
|
||||
cancel chan struct{}
|
||||
}
|
||||
|
||||
// WaitForCompletion will wait until the state of consdition is available.
|
||||
// It will call the condition function to ensure state with interval.
|
||||
func (w *FuncWaiter) WaitForCompletion() error {
|
||||
for i := 0; ; i++ {
|
||||
log.Infof("Waiting for completion ... attempted %v times, %v total", i, w.MaxAttempts)
|
||||
|
||||
if i >= w.MaxAttempts {
|
||||
return errors.New("maximum attempts are reached")
|
||||
}
|
||||
|
||||
if ok, err := w.Checker(); ok || (!w.IgnoreError && err != nil) {
|
||||
return err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(w.Interval):
|
||||
continue
|
||||
case <-w.cancel:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel will stop all of WaitForCompletion function call.
|
||||
func (w *FuncWaiter) Cancel() error {
|
||||
w.cancel <- struct{}{}
|
||||
return nil
|
||||
}
|
19
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/client.go
generated
vendored
Normal file
19
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/client.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
|
||||
)
|
||||
|
||||
// UAccountClient is the client of UAccount
|
||||
type UAccountClient struct {
|
||||
*ucloud.Client
|
||||
}
|
||||
|
||||
// NewClient will return a instance of UAccountClient
|
||||
func NewClient(config *ucloud.Config, credential *auth.Credential) *UAccountClient {
|
||||
client := ucloud.NewClient(config, credential)
|
||||
return &UAccountClient{
|
||||
client,
|
||||
}
|
||||
}
|
53
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/create_project.go
generated
vendored
Normal file
53
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/create_project.go
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
|
||||
//go:generate ucloud-gen-go-api UAccount CreateProject
|
||||
|
||||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// CreateProjectRequest is request schema for CreateProject action
|
||||
type CreateProjectRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// 项目名称
|
||||
ProjectName *string `required:"true"`
|
||||
|
||||
// 项目父节点Id, 不填写创建顶层项目
|
||||
ParentId *string `required:"false"`
|
||||
}
|
||||
|
||||
// CreateProjectResponse is response schema for CreateProject action
|
||||
type CreateProjectResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 所创建项目的Id
|
||||
ProjectId string
|
||||
}
|
||||
|
||||
// NewCreateProjectRequest will create request of CreateProject action.
|
||||
func (c *UAccountClient) NewCreateProjectRequest() *CreateProjectRequest {
|
||||
req := &CreateProjectRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// CreateProject - 创建项目
|
||||
func (c *UAccountClient) CreateProject(req *CreateProjectRequest) (*CreateProjectResponse, error) {
|
||||
var err error
|
||||
var res CreateProjectResponse
|
||||
|
||||
err = c.Client.InvokeAction("CreateProject", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Package uaccount include resources of ucloud uaccount product
|
||||
|
||||
See also
|
||||
|
||||
- API: https://docs.ucloud.cn/api/uaccount-api/index
|
||||
- Product: https://www.ucloud.cn/site/product/uaccount.html
|
||||
|
||||
for detail.
|
||||
*/
|
||||
package uaccount
|
53
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/get_project_list.go
generated
vendored
Normal file
53
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/get_project_list.go
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
|
||||
//go:generate ucloud-gen-go-api UAccount GetProjectList
|
||||
|
||||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// GetProjectListRequest is request schema for GetProjectList action
|
||||
type GetProjectListRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// 是否是财务账号(Yes: 是, No: 否)
|
||||
IsFinance *string `required:"false"`
|
||||
}
|
||||
|
||||
// GetProjectListResponse is response schema for GetProjectList action
|
||||
type GetProjectListResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 项目总数
|
||||
ProjectCount int
|
||||
|
||||
// JSON格式的项目列表实例
|
||||
ProjectSet []ProjectListInfo
|
||||
}
|
||||
|
||||
// NewGetProjectListRequest will create request of GetProjectList action.
|
||||
func (c *UAccountClient) NewGetProjectListRequest() *GetProjectListRequest {
|
||||
req := &GetProjectListRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetProjectList - 获取项目列表
|
||||
func (c *UAccountClient) GetProjectList(req *GetProjectListRequest) (*GetProjectListResponse, error) {
|
||||
var err error
|
||||
var res GetProjectListResponse
|
||||
|
||||
err = c.Client.InvokeAction("GetProjectList", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
47
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/get_region.go
generated
vendored
Normal file
47
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/get_region.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
|
||||
//go:generate ucloud-gen-go-api UAccount GetRegion
|
||||
|
||||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// GetRegionRequest is request schema for GetRegion action
|
||||
type GetRegionRequest struct {
|
||||
request.CommonBase
|
||||
}
|
||||
|
||||
// GetRegionResponse is response schema for GetRegion action
|
||||
type GetRegionResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 各数据中心信息
|
||||
Regions []RegionInfo
|
||||
}
|
||||
|
||||
// NewGetRegionRequest will create request of GetRegion action.
|
||||
func (c *UAccountClient) NewGetRegionRequest() *GetRegionRequest {
|
||||
req := &GetRegionRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetRegion - 获取用户在各数据中心的权限等信息
|
||||
func (c *UAccountClient) GetRegion(req *GetRegionRequest) (*GetRegionResponse, error) {
|
||||
var err error
|
||||
var res GetRegionResponse
|
||||
|
||||
err = c.Client.InvokeAction("GetRegion", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
47
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/get_user_info.go
generated
vendored
Normal file
47
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/get_user_info.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
|
||||
//go:generate ucloud-gen-go-api UAccount GetUserInfo
|
||||
|
||||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// GetUserInfoRequest is request schema for GetUserInfo action
|
||||
type GetUserInfoRequest struct {
|
||||
request.CommonBase
|
||||
}
|
||||
|
||||
// GetUserInfoResponse is response schema for GetUserInfo action
|
||||
type GetUserInfoResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 用户信息返回数组
|
||||
DataSet []UserInfo
|
||||
}
|
||||
|
||||
// NewGetUserInfoRequest will create request of GetUserInfo action.
|
||||
func (c *UAccountClient) NewGetUserInfoRequest() *GetUserInfoRequest {
|
||||
req := &GetUserInfoRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetUserInfo - 获取用户信息
|
||||
func (c *UAccountClient) GetUserInfo(req *GetUserInfoRequest) (*GetUserInfoResponse, error) {
|
||||
var err error
|
||||
var res GetUserInfoResponse
|
||||
|
||||
err = c.Client.InvokeAction("GetUserInfo", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
50
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/modify_project.go
generated
vendored
Normal file
50
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/modify_project.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
|
||||
//go:generate ucloud-gen-go-api UAccount ModifyProject
|
||||
|
||||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ModifyProjectRequest is request schema for ModifyProject action
|
||||
type ModifyProjectRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
|
||||
// ProjectId *string `required:"true"`
|
||||
|
||||
// 新的项目名称
|
||||
ProjectName *string `required:"true"`
|
||||
}
|
||||
|
||||
// ModifyProjectResponse is response schema for ModifyProject action
|
||||
type ModifyProjectResponse struct {
|
||||
response.CommonBase
|
||||
}
|
||||
|
||||
// NewModifyProjectRequest will create request of ModifyProject action.
|
||||
func (c *UAccountClient) NewModifyProjectRequest() *ModifyProjectRequest {
|
||||
req := &ModifyProjectRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ModifyProject - 修改项目
|
||||
func (c *UAccountClient) ModifyProject(req *ModifyProjectRequest) (*ModifyProjectResponse, error) {
|
||||
var err error
|
||||
var res ModifyProjectResponse
|
||||
|
||||
err = c.Client.InvokeAction("ModifyProject", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
48
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/terminate_project.go
generated
vendored
Normal file
48
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/terminate_project.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
//Code is generated by ucloud code generator, don't modify it by hand, it will cause undefined behaviors.
|
||||
//go:generate ucloud-gen-go-api UAccount TerminateProject
|
||||
|
||||
package uaccount
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// TerminateProjectRequest is request schema for TerminateProject action
|
||||
type TerminateProjectRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
|
||||
// ProjectId *string `required:"false"`
|
||||
|
||||
}
|
||||
|
||||
// TerminateProjectResponse is response schema for TerminateProject action
|
||||
type TerminateProjectResponse struct {
|
||||
response.CommonBase
|
||||
}
|
||||
|
||||
// NewTerminateProjectRequest will create request of TerminateProject action.
|
||||
func (c *UAccountClient) NewTerminateProjectRequest() *TerminateProjectRequest {
|
||||
req := &TerminateProjectRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// TerminateProject - 删除项目
|
||||
func (c *UAccountClient) TerminateProject(req *TerminateProjectRequest) (*TerminateProjectResponse, error) {
|
||||
var err error
|
||||
var res TerminateProjectResponse
|
||||
|
||||
err = c.Client.InvokeAction("TerminateProject", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
34
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/types_project_list_info.go
generated
vendored
Normal file
34
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/types_project_list_info.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package uaccount
|
||||
|
||||
/*
|
||||
ProjectListInfo - 项目信息
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type ProjectListInfo struct {
|
||||
|
||||
// 项目ID
|
||||
ProjectId string
|
||||
|
||||
// 项目名称
|
||||
ProjectName string
|
||||
|
||||
// 父项目ID
|
||||
ParentId string
|
||||
|
||||
// 父项目名称
|
||||
ParentName string
|
||||
|
||||
// 创建时间(Unix时间戳)
|
||||
CreateTime int
|
||||
|
||||
// 是否为默认项目
|
||||
IsDefault bool
|
||||
|
||||
// 项目下资源数量
|
||||
ResourceCount int
|
||||
|
||||
// 项目下成员数量
|
||||
MemberCount int
|
||||
}
|
28
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/types_region_info.go
generated
vendored
Normal file
28
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/types_region_info.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
package uaccount
|
||||
|
||||
/*
|
||||
RegionInfo - 数据中心信息
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type RegionInfo struct {
|
||||
|
||||
// 数据中心ID
|
||||
RegionId int
|
||||
|
||||
// 数据中心名称
|
||||
RegionName string
|
||||
|
||||
// 是否用户当前默认数据中心
|
||||
IsDefault bool
|
||||
|
||||
// 用户在此数据中心的权限位
|
||||
BitMaps string
|
||||
|
||||
// 地域名字,如cn-bj
|
||||
Region string
|
||||
|
||||
// 可用区名字,如cn-bj-01
|
||||
Zone string
|
||||
}
|
58
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/types_user_info.go
generated
vendored
Normal file
58
vendor/github.com/ucloud/ucloud-sdk-go/services/uaccount/types_user_info.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
package uaccount
|
||||
|
||||
/*
|
||||
UserInfo - 用户信息
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UserInfo struct {
|
||||
|
||||
// 用户Id
|
||||
UserId int
|
||||
|
||||
// 用户邮箱
|
||||
UserEmail string
|
||||
|
||||
// 用户手机
|
||||
UserPhone string
|
||||
|
||||
// 国际号码前缀
|
||||
PhonePrefix string
|
||||
|
||||
// 会员类型
|
||||
UserType int
|
||||
|
||||
// 称呼
|
||||
UserName string
|
||||
|
||||
// 公司名称
|
||||
CompanyName string
|
||||
|
||||
// 所属行业
|
||||
IndustryType int
|
||||
|
||||
// 省份
|
||||
Province string
|
||||
|
||||
// 城市
|
||||
City string
|
||||
|
||||
// 公司地址
|
||||
UserAddress string
|
||||
|
||||
// 是否超级管理员 0:否 1:是
|
||||
Admin int
|
||||
|
||||
// 是否子帐户(大于100为子帐户)
|
||||
UserVersion int
|
||||
|
||||
// 是否有财务权限 0:否 1:是
|
||||
Finance int
|
||||
|
||||
// 管理员
|
||||
Administrator string
|
||||
|
||||
// 实名认证状态
|
||||
AuthState string
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
|
||||
)
|
||||
|
||||
// UHostClient is the client of UHost
|
||||
type UHostClient struct {
|
||||
*ucloud.Client
|
||||
}
|
||||
|
||||
// NewClient will return a instance of UHostClient
|
||||
func NewClient(config *ucloud.Config, credential *auth.Credential) *UHostClient {
|
||||
client := ucloud.NewClient(config, credential)
|
||||
return &UHostClient{
|
||||
client,
|
||||
}
|
||||
}
|
71
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/copy_custom_image.go
generated
vendored
Normal file
71
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/copy_custom_image.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
//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 CopyCustomImage
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// CopyCustomImageRequest is request schema for CopyCustomImage action
|
||||
type CopyCustomImageRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// 源镜像Id, 参见 DescribeImage
|
||||
SourceImageId *string `required:"true"`
|
||||
|
||||
// 目标项目Id, 参见 GetProjectList
|
||||
TargetProjectId *string `required:"true"`
|
||||
|
||||
// 目标地域,不跨地域不用填
|
||||
TargetRegion *string `required:"false"`
|
||||
|
||||
// 目标镜像名称
|
||||
TargetImageName *string `required:"false"`
|
||||
|
||||
// 目标镜像描述
|
||||
TargetImageDescription *string `required:"false"`
|
||||
}
|
||||
|
||||
// CopyCustomImageResponse is response schema for CopyCustomImage action
|
||||
type CopyCustomImageResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 目标镜像Id
|
||||
TargetImageId string
|
||||
}
|
||||
|
||||
// NewCopyCustomImageRequest will create request of CopyCustomImage action.
|
||||
func (c *UHostClient) NewCopyCustomImageRequest() *CopyCustomImageRequest {
|
||||
req := &CopyCustomImageRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// CopyCustomImage - 复制自制镜像
|
||||
func (c *UHostClient) CopyCustomImage(req *CopyCustomImageRequest) (*CopyCustomImageResponse, error) {
|
||||
var err error
|
||||
var res CopyCustomImageResponse
|
||||
|
||||
err = c.Client.InvokeAction("CopyCustomImage", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
65
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/create_custom_image.go
generated
vendored
Normal file
65
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/create_custom_image.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
//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 CreateCustomImage
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// CreateCustomImageRequest is request schema for CreateCustomImage action
|
||||
type CreateCustomImageRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 镜像名称
|
||||
ImageName *string `required:"true"`
|
||||
|
||||
// 镜像描述
|
||||
ImageDescription *string `required:"false"`
|
||||
}
|
||||
|
||||
// CreateCustomImageResponse is response schema for CreateCustomImage action
|
||||
type CreateCustomImageResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 镜像Id
|
||||
ImageId string
|
||||
}
|
||||
|
||||
// NewCreateCustomImageRequest will create request of CreateCustomImage action.
|
||||
func (c *UHostClient) NewCreateCustomImageRequest() *CreateCustomImageRequest {
|
||||
req := &CreateCustomImageRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// CreateCustomImage - 从指定UHost实例,生成自定义镜像。
|
||||
func (c *UHostClient) CreateCustomImage(req *CreateCustomImageRequest) (*CreateCustomImageResponse, error) {
|
||||
var err error
|
||||
var res CreateCustomImageResponse
|
||||
|
||||
err = c.Client.InvokeAction("CreateCustomImage", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
202
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/create_uhost_instance.go
generated
vendored
Normal file
202
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/create_uhost_instance.go
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// CreateUHostInstanceRequest is request schema for CreateUHostInstance action
|
||||
type CreateUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// 可用区。参见 [可用区列表](../summary/regionlist.html)
|
||||
// Zone *string `required:"true"`
|
||||
|
||||
// 镜像ID。 请通过 [DescribeImage](describe_image.html)获取
|
||||
ImageId *string `required:"true"`
|
||||
|
||||
// UHost密码,LoginMode为Password时此项必须(密码需使用base64进行编码)
|
||||
Password *string `required:"true"`
|
||||
|
||||
// 磁盘列表
|
||||
Disks []UHostDisk `required:"true"`
|
||||
|
||||
// UHost实例名称。默认:UHost。请遵照[[api:uhost-api:specification|字段规范]]设定实例名称。
|
||||
Name *string `required:"false"`
|
||||
|
||||
// 业务组。默认:Default(Default即为未分组)
|
||||
Tag *string `required:"false"`
|
||||
|
||||
// 计费模式。枚举值为: Year,按年付费; Month,按月付费; Dynamic,按小时付费(需开启权限)。默认为月付
|
||||
ChargeType *string `required:"false"`
|
||||
|
||||
// 购买时长。默认: 1。按小时购买(Dynamic)时无需此参数。 月付时,此参数传0,代表了购买至月末。
|
||||
Quantity *int `required:"false"`
|
||||
|
||||
// 云主机机型。枚举值:N1:系列1标准型;N2:系列2标准型;I1: 系列1高IO型;I2,系列2高IO型; D1: 系列1大数据机型;G1: 系列1GPU型,型号为K80;G2:系列2GPU型,型号为P40;G3:系列2GPU型,型号为V100;北京A、北京C、上海二A、香港A可用区默认N1,其他机房默认N2。参考[[api:uhost-api:uhost_type|云主机机型说明]]。
|
||||
UHostType *string `required:"false"`
|
||||
|
||||
// 虚拟CPU核数。可选参数:1-32(可选范围与UHostType相关)。默认值: 4
|
||||
CPU *int `required:"false"`
|
||||
|
||||
// 内存大小。单位:MB。范围 :[1024, 262144],取值为1024的倍数(可选范围与UHostType相关)。默认值:8192
|
||||
Memory *int `required:"false"`
|
||||
|
||||
// GPU卡核心数。仅GPU机型支持此字段;系列1可选1,2;系列2可选1,2,3,4。GPU可选数量与CPU有关联,详情请参考控制台。
|
||||
GPU *int `required:"false"`
|
||||
|
||||
// 主机登陆模式。密码(默认选项): Password,key: KeyPair(此项暂不支持)
|
||||
LoginMode *string `required:"false"`
|
||||
|
||||
// 【暂不支持】Keypair公钥,LoginMode为KeyPair时此项必须
|
||||
KeyPair *string `required:"false"`
|
||||
|
||||
// 【待废弃,不建议调用】磁盘类型,同时设定系统盘和数据盘的磁盘类型。枚举值为:LocalDisk,本地磁盘; UDisk,云硬盘;默认为LocalDisk。仅部分可用区支持云硬盘方式的主机存储方式,具体请查询控制台。
|
||||
StorageType *string `required:"false"`
|
||||
|
||||
// 【待废弃,不建议调用】系统盘大小。 单位:GB, 范围[20,100], 步长:10
|
||||
BootDiskSpace *int `required:"false"`
|
||||
|
||||
// 【待废弃,不建议调用】数据盘大小。 单位:GB, 范围[0,8000], 步长:10, 默认值:20,云盘支持0-8000;本地普通盘支持0-2000;本地SSD盘(包括所有GPU机型)支持100-1000
|
||||
DiskSpace *int `required:"false"`
|
||||
|
||||
// 网络增强。目前仅Normal(不开启) 和Super(开启)可用。默认Normal。 不同机房的网络增强支持情况不同。详情请参考控制台。
|
||||
NetCapability *string `required:"false"`
|
||||
|
||||
// 是否开启方舟特性。Yes为开启方舟,No为关闭方舟。目前仅选择普通本地盘+普通本地盘 或 SSD云盘+普通云盘的组合支持开启方舟。
|
||||
TimemachineFeature *string `required:"false"`
|
||||
|
||||
// 是否开启热升级特性。True为开启,False为未开启,默认False。仅系列1云主机需要使用此字段,系列2云主机根据镜像是否支持云主机。
|
||||
HotplugFeature *bool `required:"false"`
|
||||
|
||||
// 网络ID(VPC2.0情况下无需填写)。VPC1.0情况下,若不填写,代表选择基础网络; 若填写,代表选择子网。参见DescribeSubnet。
|
||||
NetworkId *string `required:"false"`
|
||||
|
||||
// VPC ID。VPC2.0下需要填写此字段。
|
||||
VPCId *string `required:"false"`
|
||||
|
||||
// 子网ID。VPC2.0下需要填写此字段。
|
||||
SubnetId *string `required:"false"`
|
||||
|
||||
// 【数组】创建云主机时指定内网IP。当前只支持一个内网IP。调用方式举例:PrivateIp.0=x.x.x.x。
|
||||
PrivateIp []string `required:"false"`
|
||||
|
||||
// 创建云主机时指定Mac。调用方式举例:PrivateMac="xx:xx:xx:xx:xx:xx"。
|
||||
PrivateMac *string `required:"false"`
|
||||
|
||||
// 防火墙Id,默认:Web推荐防火墙。如何查询SecurityGroupId请参见 [DescribeSecurityGroup](../unet-api/describe_security_group.html)
|
||||
SecurityGroupId *string `required:"false"`
|
||||
|
||||
// 【暂不支持】cloudinit方式下,用户初始化脚本
|
||||
UserDataScript *string `required:"false"`
|
||||
|
||||
// 【已废弃】宿主机类型,N2,N1
|
||||
HostType *string `required:"false"`
|
||||
|
||||
// 【暂不支持】是否安装UGA。'yes': 安装;其他或者不填:不安装。
|
||||
InstallAgent *string `required:"false"`
|
||||
|
||||
// 【内部参数】资源类型
|
||||
ResourceType *int `required:"false"`
|
||||
|
||||
// 代金券ID。请通过DescribeCoupon接口查询,或登录用户中心查看
|
||||
CouponId *string `required:"false"`
|
||||
|
||||
// 云主机类型,枚举值["N", "C", "G", "O"]
|
||||
MachineType *string `required:"false"`
|
||||
|
||||
// 最低cpu平台,枚举值["Intel/Auto", "Intel/LvyBridge", "Intel/Haswell", "Intel/Broadwell", "Intel/Skylake", "Intel/Cascadelake"(只有O型云主机可选)]
|
||||
MinimalCpuPlatform *string `required:"false"`
|
||||
|
||||
// NetworkInterface
|
||||
NetworkInterface []CreateUHostInstanceParamNetworkInterface
|
||||
}
|
||||
|
||||
/*
|
||||
CreateUHostInstanceParamNetworkInterface is request schema for complex param
|
||||
*/
|
||||
type CreateUHostInstanceParamNetworkInterface struct {
|
||||
|
||||
// EIP
|
||||
EIP *CreateUHostInstanceParamNetworkInterfaceEIP
|
||||
}
|
||||
|
||||
/*
|
||||
CreateUHostInstanceParamNetworkInterfaceEIP is request schema for complex param
|
||||
*/
|
||||
type CreateUHostInstanceParamNetworkInterfaceEIP struct {
|
||||
|
||||
// 弹性IP的计费模式. 枚举值: "Traffic", 流量计费; "Bandwidth", 带宽计费; "ShareBandwidth",共享带宽模式. "Free":免费带宽模式.默认为 "Bandwidth".
|
||||
PayMode *string
|
||||
|
||||
// 当前EIP代金券id。请通过DescribeCoupon接口查询,或登录用户中心查看
|
||||
CouponId *string
|
||||
|
||||
// 【如果绑定EIP这个参数必填】弹性IP的外网带宽, 单位为Mbps. 共享带宽模式必须指定0M带宽, 非共享带宽模式必须指定非0Mbps带宽. 各地域非共享带宽的带宽范围如下: 流量计费[1-300],带宽计费[1-800]
|
||||
Bandwidth *int
|
||||
|
||||
// 绑定的共享带宽Id,仅当PayMode为ShareBandwidth时有效
|
||||
ShareBandwidthId *string
|
||||
|
||||
// GlobalSSH
|
||||
GlobalSSH *CreateUHostInstanceParamNetworkInterfaceEIPGlobalSSH
|
||||
|
||||
// 【如果绑定EIP这个参数必填】弹性IP的线路如下: 国际: International BGP: Bgp 各地域允许的线路参数如下: cn-sh1: Bgp cn-sh2: Bgp cn-gd: Bgp cn-bj1: Bgp cn-bj2: Bgp hk: International us-ca: International th-bkk: International kr-seoul:International us-ws:International ge-fra:International sg:International tw-kh:International.其他海外线路均为 International
|
||||
OperatorName *string
|
||||
}
|
||||
|
||||
/*
|
||||
CreateUHostInstanceParamNetworkInterfaceEIPGlobalSSH is request schema for complex param
|
||||
*/
|
||||
type CreateUHostInstanceParamNetworkInterfaceEIPGlobalSSH struct {
|
||||
|
||||
// 填写支持SSH访问IP的地区名称,如“洛杉矶”,“新加坡”,“香港”,“东京”,“华盛顿”,“法兰克福”。Area和AreaCode两者必填一个
|
||||
Area *string
|
||||
|
||||
// AreaCode, 区域航空港国际通用代码。Area和AreaCode两者必填一个
|
||||
AreaCode *string
|
||||
|
||||
// SSH端口,1-65535且不能使用80,443端口
|
||||
Port *int
|
||||
}
|
||||
|
||||
// CreateUHostInstanceResponse is response schema for CreateUHostInstance action
|
||||
type CreateUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例Id集合
|
||||
UHostIds []string
|
||||
|
||||
// IP信息
|
||||
IPs []string
|
||||
}
|
||||
|
||||
// NewCreateUHostInstanceRequest will create request of CreateUHostInstance action.
|
||||
func (c *UHostClient) NewCreateUHostInstanceRequest() *CreateUHostInstanceRequest {
|
||||
req := &CreateUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// CreateUHostInstance - 指定数据中心,根据资源使用量创建指定数量的UHost实例。
|
||||
func (c *UHostClient) CreateUHostInstance(req *CreateUHostInstanceRequest) (*CreateUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res CreateUHostInstanceResponse
|
||||
var reqImmutable = *req
|
||||
reqImmutable.Password = ucloud.String(base64.StdEncoding.EncodeToString([]byte(ucloud.StringValue(req.Password))))
|
||||
|
||||
err = c.Client.InvokeAction("CreateUHostInstance", &reqImmutable, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
77
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/describe_image.go
generated
vendored
Normal file
77
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/describe_image.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
//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 DescribeImage
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// DescribeImageRequest is request schema for DescribeImage action
|
||||
type DescribeImageRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// 镜像类型。标准镜像:Base,镜像市场:Business, 自定义镜像:Custom,默认返回所有类型
|
||||
ImageType *string `required:"false"`
|
||||
|
||||
// 操作系统类型:Linux, Windows 默认返回所有类型
|
||||
OsType *string `required:"false"`
|
||||
|
||||
// 镜像Id
|
||||
ImageId *string `required:"false"`
|
||||
|
||||
// 列表起始位置偏移量,默认为0
|
||||
Offset *int `required:"false"`
|
||||
|
||||
// 返回数据长度,默认为20
|
||||
Limit *int `required:"false"`
|
||||
|
||||
// 是否返回价格:1返回,0不返回;默认不返回
|
||||
PriceSet *int `required:"false"`
|
||||
}
|
||||
|
||||
// DescribeImageResponse is response schema for DescribeImage action
|
||||
type DescribeImageResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 满足条件的镜像总数
|
||||
TotalCount int
|
||||
|
||||
// 镜像列表详见 UHostImageSet
|
||||
ImageSet []UHostImageSet
|
||||
}
|
||||
|
||||
// NewDescribeImageRequest will create request of DescribeImage action.
|
||||
func (c *UHostClient) NewDescribeImageRequest() *DescribeImageRequest {
|
||||
req := &DescribeImageRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// DescribeImage - 获取指定数据中心镜像列表,用户可通过指定操作系统类型,镜像Id进行过滤。
|
||||
func (c *UHostClient) DescribeImage(req *DescribeImageRequest) (*DescribeImageResponse, error) {
|
||||
var err error
|
||||
var res DescribeImageResponse
|
||||
|
||||
err = c.Client.InvokeAction("DescribeImage", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
83
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/describe_uhost_instance.go
generated
vendored
Normal file
83
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/describe_uhost_instance.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
//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 DescribeUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// DescribeUHostInstanceRequest is request schema for DescribeUHostInstance action
|
||||
type DescribeUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// 【数组】UHost主机的资源ID,例如UHostIds.0代表希望获取信息 的主机1,UHostIds.1代表主机2。 如果不传入,则返回当前Region 所有符合条件的UHost实例。
|
||||
UHostIds []string `required:"false"`
|
||||
|
||||
// 要查询的业务组名称
|
||||
Tag *string `required:"false"`
|
||||
|
||||
// 1:普通云主机;2:抢占型云主机;如不传此参数,默认全部获取
|
||||
LifeCycle *int `required:"false"`
|
||||
|
||||
// 列表起始位置偏移量,默认为0
|
||||
Offset *int `required:"false"`
|
||||
|
||||
// 返回数据长度,默认为20,最大100
|
||||
Limit *int `required:"false"`
|
||||
|
||||
// 硬件隔离组id
|
||||
IsolationGroup *string `required:"false"`
|
||||
|
||||
// 云主机ip对应的vpc id
|
||||
VPCId *string `required:"false"`
|
||||
|
||||
// 云主机ip对应的子网id
|
||||
SubnetId *string `required:"false"`
|
||||
}
|
||||
|
||||
// DescribeUHostInstanceResponse is response schema for DescribeUHostInstance action
|
||||
type DescribeUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHostInstance总数
|
||||
TotalCount int
|
||||
|
||||
// 云主机实例列表,每项参数可见下面 UHostInstanceSet
|
||||
UHostSet []UHostInstanceSet
|
||||
}
|
||||
|
||||
// NewDescribeUHostInstanceRequest will create request of DescribeUHostInstance action.
|
||||
func (c *UHostClient) NewDescribeUHostInstanceRequest() *DescribeUHostInstanceRequest {
|
||||
req := &DescribeUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// DescribeUHostInstance - 获取主机或主机列表信息,并可根据数据中心,主机ID等参数进行过滤。
|
||||
func (c *UHostClient) DescribeUHostInstance(req *DescribeUHostInstanceRequest) (*DescribeUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res DescribeUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("DescribeUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
60
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/describe_uhost_tags.go
generated
vendored
Normal file
60
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/describe_uhost_tags.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
//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 DescribeUHostTags
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// DescribeUHostTagsRequest is request schema for DescribeUHostTags action
|
||||
type DescribeUHostTagsRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
}
|
||||
|
||||
// DescribeUHostTagsResponse is response schema for DescribeUHostTags action
|
||||
type DescribeUHostTagsResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 已有主机的业务组总个数
|
||||
TotalCount int
|
||||
|
||||
// 业务组集合见 UHostTagSet
|
||||
TagSet []UHostTagSet
|
||||
}
|
||||
|
||||
// NewDescribeUHostTagsRequest will create request of DescribeUHostTags action.
|
||||
func (c *UHostClient) NewDescribeUHostTagsRequest() *DescribeUHostTagsRequest {
|
||||
req := &DescribeUHostTagsRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// DescribeUHostTags - 获取指定数据中心的业务组列表。
|
||||
func (c *UHostClient) DescribeUHostTags(req *DescribeUHostTagsRequest) (*DescribeUHostTagsResponse, error) {
|
||||
var err error
|
||||
var res DescribeUHostTagsResponse
|
||||
|
||||
err = c.Client.InvokeAction("DescribeUHostTags", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Package uhost include resources of ucloud host product
|
||||
|
||||
See also
|
||||
|
||||
- API: https://docs.ucloud.cn/api/uhost-api/index
|
||||
- Product: https://www.ucloud.cn/site/product/uhost.html
|
||||
|
||||
for detail.
|
||||
*/
|
||||
package uhost
|
|
@ -0,0 +1,20 @@
|
|||
package uhost
|
||||
|
||||
// State is the state of UHost instance
|
||||
type State string
|
||||
|
||||
// Enum values for State
|
||||
const (
|
||||
StateInitializing State = "Initializing"
|
||||
StateStarting State = "Starting"
|
||||
StateRunning State = "Running"
|
||||
StateStopping State = "Stopping"
|
||||
StateStopped State = "Stopped"
|
||||
StateInstallFail State = "InstallFail"
|
||||
StateRebooting State = "Rebooting"
|
||||
)
|
||||
|
||||
// MarshalValue will marshal state value to string
|
||||
func (enum State) MarshalValue() (string, error) {
|
||||
return string(enum), nil
|
||||
}
|
94
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/get_uhost_instance_price.go
generated
vendored
Normal file
94
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/get_uhost_instance_price.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// GetUHostInstancePriceRequest is request schema for GetUHostInstancePrice action
|
||||
type GetUHostInstancePriceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// 镜像Id,可通过 [DescribeImage](describe_image.html) 获取镜像ID
|
||||
ImageId *string `required:"true"`
|
||||
|
||||
// 虚拟CPU核数。可选参数:1-32(可选范围与UHostType相关)。默认值: 4
|
||||
CPU *int `required:"true"`
|
||||
|
||||
// 内存大小。单位:MB。范围 :[1024, 262144],取值为1024的倍数(可选范围与UHostType相关)。默认值:8192
|
||||
Memory *int `required:"true"`
|
||||
|
||||
// 【未启用】购买台数,范围[1,5]
|
||||
Count *int `required:"false"`
|
||||
|
||||
// 磁盘列表
|
||||
Disks []UHostDisk
|
||||
|
||||
// GPU卡核心数。仅GPU机型支持此字段(可选范围与UHostType相关)。
|
||||
GPU *int `required:"false"`
|
||||
|
||||
// 计费模式。枚举值为: \\ > Year,按年付费; \\ > Month,按月付费;\\ > Dynamic,按小时付费 \\ 默认为月付。
|
||||
ChargeType *string `required:"false"`
|
||||
|
||||
// 【待废弃】磁盘类型,同时设定系统盘和数据盘, 枚举值为:LocalDisk,本地磁盘; UDisk,云硬盘; 默认为LocalDisk 仅部分可用区支持云硬盘方式的主机存储方式,具体请查询控制台。
|
||||
StorageType *string `required:"false"`
|
||||
|
||||
// 【待废弃】数据盘大小,单位: GB,范围[0,1000],步长: 10,默认值: 0
|
||||
DiskSpace *int `required:"false"`
|
||||
|
||||
// 网络增强。枚举值:\\ > Normal,不开启 \\ > Super,开启 \\ 默认值未为Normal。
|
||||
NetCapability *string `required:"false"`
|
||||
|
||||
// 【待废弃】方舟机型。No,Yes。默认是No。
|
||||
TimemachineFeature *string `required:"false"`
|
||||
|
||||
// 主机类型 Normal: 标准机型 SSD:SSD机型 BigData:大数据 GPU:GPU型G1(原GPU型) GPU_G2:GPU型G2 GPU_G3:GPU型G3 不同机房的主机类型支持情况不同。详情请参考控制台。
|
||||
UHostType *string `required:"false"`
|
||||
// 【未支持】1:普通云主机;2:抢占性云主机;默认普通
|
||||
LifeCycle *int `required:"false"`
|
||||
|
||||
// 购买时长。默认: 1。按小时购买(Dynamic)时无需此参数。 月付时,此参数传0,代表了购买至月末。
|
||||
Quantity *int `required:"false"`
|
||||
}
|
||||
|
||||
// GetUHostInstancePriceResponse is response schema for GetUHostInstancePrice action
|
||||
type GetUHostInstancePriceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 价格列表 UHostPriceSet
|
||||
PriceSet []UHostPriceSet
|
||||
}
|
||||
|
||||
// NewGetUHostInstancePriceRequest will create request of GetUHostInstancePrice action.
|
||||
func (c *UHostClient) NewGetUHostInstancePriceRequest() *GetUHostInstancePriceRequest {
|
||||
req := &GetUHostInstancePriceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetUHostInstancePrice - 根据UHost实例配置,获取UHost实例的价格。
|
||||
func (c *UHostClient) GetUHostInstancePrice(req *GetUHostInstancePriceRequest) (*GetUHostInstancePriceResponse, error) {
|
||||
var err error
|
||||
var res GetUHostInstancePriceResponse
|
||||
|
||||
err = c.Client.InvokeAction("GetUHostInstancePrice", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
68
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/get_uhost_instance_vnc_info.go
generated
vendored
Normal file
68
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/get_uhost_instance_vnc_info.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
//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 GetUHostInstanceVncInfo
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// GetUHostInstanceVncInfoRequest is request schema for GetUHostInstanceVncInfo action
|
||||
type GetUHostInstanceVncInfoRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](./describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
}
|
||||
|
||||
// GetUHostInstanceVncInfoResponse is response schema for GetUHostInstanceVncInfo action
|
||||
type GetUHostInstanceVncInfoResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
|
||||
// Vnc登录IP
|
||||
VncIP string
|
||||
|
||||
// Vnc登录端口
|
||||
VncPort int
|
||||
|
||||
// Vnc 登录密码
|
||||
VncPassword string
|
||||
}
|
||||
|
||||
// NewGetUHostInstanceVncInfoRequest will create request of GetUHostInstanceVncInfo action.
|
||||
func (c *UHostClient) NewGetUHostInstanceVncInfoRequest() *GetUHostInstanceVncInfoRequest {
|
||||
req := &GetUHostInstanceVncInfoRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetUHostInstanceVncInfo - 获取指定UHost实例的管理VNC配置详细信息。
|
||||
func (c *UHostClient) GetUHostInstanceVncInfo(req *GetUHostInstanceVncInfoRequest) (*GetUHostInstanceVncInfoResponse, error) {
|
||||
var err error
|
||||
var res GetUHostInstanceVncInfoResponse
|
||||
|
||||
err = c.Client.InvokeAction("GetUHostInstanceVncInfo", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
80
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/get_uhost_upgrade_price.go
generated
vendored
Normal file
80
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/get_uhost_upgrade_price.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
//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 GetUHostUpgradePrice
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// GetUHostUpgradePriceRequest is request schema for GetUHostUpgradePrice action
|
||||
type GetUHostUpgradePriceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID。 参见 [DescribeUHostInstance](describe_uhost_instance.html)。
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 虚拟CPU核数。可选参数:1-32(可选范围与UHostType相关)。默认值为当前实例的CPU核数。
|
||||
CPU *int `required:"false"`
|
||||
|
||||
// 内存大小。单位:MB。范围 :[1024, 262144],取值为1024的倍数(可选范围与UHostType相关)。默认值为当前实例的内存大小。
|
||||
Memory *int `required:"false"`
|
||||
|
||||
// 【待废弃】数据盘大小,单位: GB,范围[0,1000],步长: 10, 默认值是该主机当前数据盘大小。
|
||||
DiskSpace *int `required:"false"`
|
||||
|
||||
// 【待废弃】系统大小,单位: GB,范围[20,100],步长: 10。
|
||||
BootDiskSpace *int `required:"false"`
|
||||
|
||||
// 方舟机型。No,Yes。默认是No。
|
||||
TimemachineFeature *string `required:"false"`
|
||||
|
||||
// 网卡升降级(1,表示升级,2表示降级,0表示不变)
|
||||
NetCapValue *int `required:"false"`
|
||||
|
||||
// 【待废弃】主机系列,目前支持N1,N2
|
||||
HostType *string `required:"false"`
|
||||
}
|
||||
|
||||
// GetUHostUpgradePriceResponse is response schema for GetUHostUpgradePrice action
|
||||
type GetUHostUpgradePriceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 规格调整差价。精确到小数点后2位。
|
||||
Price float64
|
||||
}
|
||||
|
||||
// NewGetUHostUpgradePriceRequest will create request of GetUHostUpgradePrice action.
|
||||
func (c *UHostClient) NewGetUHostUpgradePriceRequest() *GetUHostUpgradePriceRequest {
|
||||
req := &GetUHostUpgradePriceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetUHostUpgradePrice - 获取UHost实例升级配置的价格。可选配置范围请参考[[api:uhost-api:uhost_type|云主机机型说明]]。
|
||||
func (c *UHostClient) GetUHostUpgradePrice(req *GetUHostUpgradePriceRequest) (*GetUHostUpgradePriceResponse, error) {
|
||||
var err error
|
||||
var res GetUHostUpgradePriceResponse
|
||||
|
||||
err = c.Client.InvokeAction("GetUHostUpgradePrice", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
74
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/import_custom_image.go
generated
vendored
Normal file
74
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/import_custom_image.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
//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 ImportCustomImage
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ImportCustomImageRequest is request schema for ImportCustomImage action
|
||||
type ImportCustomImageRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
|
||||
// Region *string `required:"true"`
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
|
||||
// ProjectId *string `required:"false"`
|
||||
|
||||
// 镜像名称
|
||||
ImageName *string `required:"true"`
|
||||
|
||||
// UFile私有空间地址
|
||||
UFileUrl *string `required:"true"`
|
||||
|
||||
// 操作系统平台,比如CentOS、Ubuntu、Windows、RedHat等,请参考控制台的镜像版本;若导入控制台上没有的操作系统,参数为Other
|
||||
OsType *string `required:"true"`
|
||||
|
||||
// 操作系统详细版本,请参考控制台的镜像版本;OsType为Other时,输入参数为Other
|
||||
OsName *string `required:"true"`
|
||||
|
||||
// 镜像格式,可选RAW、VHD、VMDK、qcow2
|
||||
Format *string `required:"true"`
|
||||
|
||||
// 是否授权。必须填true
|
||||
Auth *bool `required:"true"`
|
||||
|
||||
// 镜像描述
|
||||
ImageDescription *string `required:"false"`
|
||||
}
|
||||
|
||||
// ImportCustomImageResponse is response schema for ImportCustomImage action
|
||||
type ImportCustomImageResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 镜像Id
|
||||
ImageId string
|
||||
}
|
||||
|
||||
// NewImportCustomImageRequest will create request of ImportCustomImage action.
|
||||
func (c *UHostClient) NewImportCustomImageRequest() *ImportCustomImageRequest {
|
||||
req := &ImportCustomImageRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ImportCustomImage - 把UFile的镜像文件导入到UHost,生成自定义镜像
|
||||
func (c *UHostClient) ImportCustomImage(req *ImportCustomImageRequest) (*ImportCustomImageResponse, error) {
|
||||
var err error
|
||||
var res ImportCustomImageResponse
|
||||
|
||||
err = c.Client.InvokeAction("ImportCustomImage", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/modify_uhost_instance_name.go
generated
vendored
Normal file
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/modify_uhost_instance_name.go
generated
vendored
Normal 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 ModifyUHostInstanceName
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ModifyUHostInstanceNameRequest is request schema for ModifyUHostInstanceName action
|
||||
type ModifyUHostInstanceNameRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// UHost实例名称
|
||||
Name *string `required:"false"`
|
||||
}
|
||||
|
||||
// ModifyUHostInstanceNameResponse is response schema for ModifyUHostInstanceName action
|
||||
type ModifyUHostInstanceNameResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewModifyUHostInstanceNameRequest will create request of ModifyUHostInstanceName action.
|
||||
func (c *UHostClient) NewModifyUHostInstanceNameRequest() *ModifyUHostInstanceNameRequest {
|
||||
req := &ModifyUHostInstanceNameRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ModifyUHostInstanceName - 修改指定UHost实例名称,需要给出数据中心,UHostId,及新的实例名称。
|
||||
func (c *UHostClient) ModifyUHostInstanceName(req *ModifyUHostInstanceNameRequest) (*ModifyUHostInstanceNameResponse, error) {
|
||||
var err error
|
||||
var res ModifyUHostInstanceNameResponse
|
||||
|
||||
err = c.Client.InvokeAction("ModifyUHostInstanceName", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/modify_uhost_instance_remark.go
generated
vendored
Normal file
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/modify_uhost_instance_remark.go
generated
vendored
Normal 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 ModifyUHostInstanceRemark
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ModifyUHostInstanceRemarkRequest is request schema for ModifyUHostInstanceRemark action
|
||||
type ModifyUHostInstanceRemarkRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 备注
|
||||
Remark *string `required:"false"`
|
||||
}
|
||||
|
||||
// ModifyUHostInstanceRemarkResponse is response schema for ModifyUHostInstanceRemark action
|
||||
type ModifyUHostInstanceRemarkResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewModifyUHostInstanceRemarkRequest will create request of ModifyUHostInstanceRemark action.
|
||||
func (c *UHostClient) NewModifyUHostInstanceRemarkRequest() *ModifyUHostInstanceRemarkRequest {
|
||||
req := &ModifyUHostInstanceRemarkRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ModifyUHostInstanceRemark - 修改指定UHost实例备注信息。
|
||||
func (c *UHostClient) ModifyUHostInstanceRemark(req *ModifyUHostInstanceRemarkRequest) (*ModifyUHostInstanceRemarkResponse, error) {
|
||||
var err error
|
||||
var res ModifyUHostInstanceRemarkResponse
|
||||
|
||||
err = c.Client.InvokeAction("ModifyUHostInstanceRemark", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/modify_uhost_instance_tag.go
generated
vendored
Normal file
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/modify_uhost_instance_tag.go
generated
vendored
Normal 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 ModifyUHostInstanceTag
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ModifyUHostInstanceTagRequest is request schema for ModifyUHostInstanceTag action
|
||||
type ModifyUHostInstanceTagRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 业务组名称
|
||||
Tag *string `required:"false"`
|
||||
}
|
||||
|
||||
// ModifyUHostInstanceTagResponse is response schema for ModifyUHostInstanceTag action
|
||||
type ModifyUHostInstanceTagResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewModifyUHostInstanceTagRequest will create request of ModifyUHostInstanceTag action.
|
||||
func (c *UHostClient) NewModifyUHostInstanceTagRequest() *ModifyUHostInstanceTagRequest {
|
||||
req := &ModifyUHostInstanceTagRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ModifyUHostInstanceTag - 修改指定UHost实例业务组标识。
|
||||
func (c *UHostClient) ModifyUHostInstanceTag(req *ModifyUHostInstanceTagRequest) (*ModifyUHostInstanceTagResponse, error) {
|
||||
var err error
|
||||
var res ModifyUHostInstanceTagResponse
|
||||
|
||||
err = c.Client.InvokeAction("ModifyUHostInstanceTag", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
59
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/poweroff_uhost_instance.go
generated
vendored
Normal file
59
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/poweroff_uhost_instance.go
generated
vendored
Normal 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 PoweroffUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// PoweroffUHostInstanceRequest is request schema for PoweroffUHostInstance action
|
||||
type PoweroffUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](./describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
}
|
||||
|
||||
// PoweroffUHostInstanceResponse is response schema for PoweroffUHostInstance action
|
||||
type PoweroffUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewPoweroffUHostInstanceRequest will create request of PoweroffUHostInstance action.
|
||||
func (c *UHostClient) NewPoweroffUHostInstanceRequest() *PoweroffUHostInstanceRequest {
|
||||
req := &PoweroffUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// PoweroffUHostInstance - 直接关闭UHost实例电源,无需等待实例正常关闭。
|
||||
func (c *UHostClient) PoweroffUHostInstance(req *PoweroffUHostInstanceRequest) (*PoweroffUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res PoweroffUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("PoweroffUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/reboot_uhost_instance.go
generated
vendored
Normal file
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/reboot_uhost_instance.go
generated
vendored
Normal 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 RebootUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// RebootUHostInstanceRequest is request schema for RebootUHostInstance action
|
||||
type RebootUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 加密盘密码
|
||||
DiskPassword *string `required:"false"`
|
||||
}
|
||||
|
||||
// RebootUHostInstanceResponse is response schema for RebootUHostInstance action
|
||||
type RebootUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewRebootUHostInstanceRequest will create request of RebootUHostInstance action.
|
||||
func (c *UHostClient) NewRebootUHostInstanceRequest() *RebootUHostInstanceRequest {
|
||||
req := &RebootUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// RebootUHostInstance - 重新启动UHost实例,需要指定数据中心及UHostID两个参数的值。
|
||||
func (c *UHostClient) RebootUHostInstance(req *RebootUHostInstanceRequest) (*RebootUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res RebootUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("RebootUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
76
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/reinstall_uhost_instance.go
generated
vendored
Normal file
76
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/reinstall_uhost_instance.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
//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 ReinstallUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ReinstallUHostInstanceRequest is request schema for ReinstallUHostInstance action
|
||||
type ReinstallUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// 可用区。参见 [可用区列表](../summary/regionlist.html)
|
||||
// Zone *string `required:"false"`
|
||||
|
||||
// UHost实例资源ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 如果创建UHost实例时LoginMode为Password,则必须填写,如果LoginMode为KeyPair,不需要填写 (密码格式使用BASE64编码;LoginMode不可变更)
|
||||
Password *string `required:"false"`
|
||||
|
||||
// 镜像Id,默认使用原镜像 参见 [DescribeImage](describe_image.html)
|
||||
ImageId *string `required:"false"`
|
||||
|
||||
// 系统盘大小。 单位:GB, 范围[20,100], 步长:10
|
||||
BootDiskSpace *int `required:"false"`
|
||||
|
||||
// 是否保留数据盘,保留:Yes,不报留:No, 默认:Yes;如果是从Windows重装为Linux或反之,则无法保留数据盘
|
||||
ReserveDisk *string `required:"false"`
|
||||
|
||||
// 云灾备指明191
|
||||
ResourceType *int `required:"false"`
|
||||
|
||||
// 针对非私有子网主机,可自定义DNS。n可为0-2
|
||||
DNSServers []string `required:"false"`
|
||||
}
|
||||
|
||||
// ReinstallUHostInstanceResponse is response schema for ReinstallUHostInstance action
|
||||
type ReinstallUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例资源ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewReinstallUHostInstanceRequest will create request of ReinstallUHostInstance action.
|
||||
func (c *UHostClient) NewReinstallUHostInstanceRequest() *ReinstallUHostInstanceRequest {
|
||||
req := &ReinstallUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ReinstallUHostInstance - 重新安装指定UHost实例的操作系统
|
||||
func (c *UHostClient) ReinstallUHostInstance(req *ReinstallUHostInstanceRequest) (*ReinstallUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res ReinstallUHostInstanceResponse
|
||||
var reqImmutable = *req
|
||||
reqImmutable.Password = ucloud.String(base64.StdEncoding.EncodeToString([]byte(ucloud.StringValue(req.Password))))
|
||||
|
||||
err = c.Client.InvokeAction("ReinstallUHostInstance", &reqImmutable, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
67
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/reset_uhost_instance_password.go
generated
vendored
Normal file
67
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/reset_uhost_instance_password.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
//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 ResetUHostInstancePassword
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ResetUHostInstancePasswordRequest is request schema for ResetUHostInstancePassword action
|
||||
type ResetUHostInstancePasswordRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// UHost新密码(密码格式使用BASE64编码)
|
||||
Password *string `required:"true"`
|
||||
}
|
||||
|
||||
// ResetUHostInstancePasswordResponse is response schema for ResetUHostInstancePassword action
|
||||
type ResetUHostInstancePasswordResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewResetUHostInstancePasswordRequest will create request of ResetUHostInstancePassword action.
|
||||
func (c *UHostClient) NewResetUHostInstancePasswordRequest() *ResetUHostInstancePasswordRequest {
|
||||
req := &ResetUHostInstancePasswordRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ResetUHostInstancePassword - 重置UHost实例的管理员密码。
|
||||
func (c *UHostClient) ResetUHostInstancePassword(req *ResetUHostInstancePasswordRequest) (*ResetUHostInstancePasswordResponse, error) {
|
||||
var err error
|
||||
var res ResetUHostInstancePasswordResponse
|
||||
var reqImmutable = *req
|
||||
reqImmutable.Password = ucloud.String(base64.StdEncoding.EncodeToString([]byte(ucloud.StringValue(req.Password))))
|
||||
|
||||
err = c.Client.InvokeAction("ResetUHostInstancePassword", &reqImmutable, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
65
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/resize_attached_disk.go
generated
vendored
Normal file
65
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/resize_attached_disk.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
//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 ResizeAttachedDisk
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ResizeAttachedDiskRequest is request schema for ResizeAttachedDisk action
|
||||
type ResizeAttachedDiskRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID。 参见 [DescribeUHostInstance](describe_uhost_instance.html)。
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 磁盘大小,单位GB,步长为10。取值范围需大于当前磁盘大小,最大值请参考[[api:uhost-api:disk_type|磁盘类型]]。
|
||||
DiskSpace *int `required:"true"`
|
||||
|
||||
// 磁盘ID。参见 [DescribeUHostInstance](describe_uhost_instance.html)返回值中的DiskSet。
|
||||
DiskId *string `required:"true"`
|
||||
}
|
||||
|
||||
// ResizeAttachedDiskResponse is response schema for ResizeAttachedDisk action
|
||||
type ResizeAttachedDiskResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 改配成功的磁盘id
|
||||
DiskId string
|
||||
}
|
||||
|
||||
// NewResizeAttachedDiskRequest will create request of ResizeAttachedDisk action.
|
||||
func (c *UHostClient) NewResizeAttachedDiskRequest() *ResizeAttachedDiskRequest {
|
||||
req := &ResizeAttachedDiskRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ResizeAttachedDisk - 修改挂载的磁盘大小,包含系统盘和数据盘
|
||||
func (c *UHostClient) ResizeAttachedDisk(req *ResizeAttachedDiskRequest) (*ResizeAttachedDiskResponse, error) {
|
||||
var err error
|
||||
var res ResizeAttachedDiskResponse
|
||||
|
||||
err = c.Client.InvokeAction("ResizeAttachedDisk", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
74
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/resize_uhost_instance.go
generated
vendored
Normal file
74
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/resize_uhost_instance.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
//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 ResizeUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// ResizeUHostInstanceRequest is request schema for ResizeUHostInstance action
|
||||
type ResizeUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 虚拟CPU核数。可选参数:1-32(可选范围与UHostType相关)。默认值为当前实例的CPU核数
|
||||
CPU *int `required:"false"`
|
||||
|
||||
// 内存大小。单位:MB。范围 :[1024, 262144],取值为1024的倍数(可选范围与UHostType相关)。默认值为当前实例的内存大小。
|
||||
Memory *int `required:"false"`
|
||||
|
||||
// 【待废弃】数据盘大小,单位:GB,范围[10,1000]; SSD机型,单位:GB,范围[100,500];步长:10,默认值为当前实例的数据盘大小,数据盘不支持缩容,因此不允许输入比当前实例数据盘大小的值
|
||||
DiskSpace *int `required:"false"`
|
||||
|
||||
// 【待废弃】系统盘大小,单位:GB,范围[20,100],步长:10,系统盘不支持缩容,因此不允许输入比当前实例系统盘小的值
|
||||
BootDiskSpace *int `required:"false"`
|
||||
|
||||
// 网卡升降级(1,表示升级,2表示降级,0表示不变)
|
||||
NetCapValue *int `required:"false"`
|
||||
}
|
||||
|
||||
// ResizeUHostInstanceResponse is response schema for ResizeUHostInstance action
|
||||
type ResizeUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewResizeUHostInstanceRequest will create request of ResizeUHostInstance action.
|
||||
func (c *UHostClient) NewResizeUHostInstanceRequest() *ResizeUHostInstanceRequest {
|
||||
req := &ResizeUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ResizeUHostInstance - 修改指定UHost实例的资源配置,如CPU核心数,内存容量大小,网络增强等。可选配置范围请参考[[api:uhost-api:uhost_type|云主机机型说明]]。
|
||||
func (c *UHostClient) ResizeUHostInstance(req *ResizeUHostInstanceRequest) (*ResizeUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res ResizeUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("ResizeUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/start_uhost_instance.go
generated
vendored
Normal file
62
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/start_uhost_instance.go
generated
vendored
Normal 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 StartUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// StartUHostInstanceRequest is request schema for StartUHostInstance action
|
||||
type StartUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 加密盘密码
|
||||
DiskPassword *string `required:"false"`
|
||||
}
|
||||
|
||||
// StartUHostInstanceResponse is response schema for StartUHostInstance action
|
||||
type StartUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewStartUHostInstanceRequest will create request of StartUHostInstance action.
|
||||
func (c *UHostClient) NewStartUHostInstanceRequest() *StartUHostInstanceRequest {
|
||||
req := &StartUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// StartUHostInstance - 启动处于关闭状态的UHost实例,需要指定数据中心及UHostID两个参数的值。
|
||||
func (c *UHostClient) StartUHostInstance(req *StartUHostInstanceRequest) (*StartUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res StartUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("StartUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
59
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/stop_uhost_instance.go
generated
vendored
Normal file
59
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/stop_uhost_instance.go
generated
vendored
Normal 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 StopUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// StopUHostInstanceRequest is request schema for StopUHostInstance action
|
||||
type StopUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost实例ID 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
}
|
||||
|
||||
// StopUHostInstanceResponse is response schema for StopUHostInstance action
|
||||
type StopUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost实例ID
|
||||
UhostId string
|
||||
}
|
||||
|
||||
// NewStopUHostInstanceRequest will create request of StopUHostInstance action.
|
||||
func (c *UHostClient) NewStopUHostInstanceRequest() *StopUHostInstanceRequest {
|
||||
req := &StopUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// StopUHostInstance - 指停止处于运行状态的UHost实例,需指定数据中心及UhostID。
|
||||
func (c *UHostClient) StopUHostInstance(req *StopUHostInstanceRequest) (*StopUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res StopUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("StopUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
56
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/terminate_custom_image.go
generated
vendored
Normal file
56
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/terminate_custom_image.go
generated
vendored
Normal 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 TerminateCustomImage
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// TerminateCustomImageRequest is request schema for TerminateCustomImage action
|
||||
type TerminateCustomImageRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
|
||||
// Region *string `required:"true"`
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
|
||||
// ProjectId *string `required:"false"`
|
||||
|
||||
// 自制镜像ID 参见 [DescribeImage](describe_image.html)
|
||||
ImageId *string `required:"true"`
|
||||
}
|
||||
|
||||
// TerminateCustomImageResponse is response schema for TerminateCustomImage action
|
||||
type TerminateCustomImageResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 自制镜像Id
|
||||
ImageId string
|
||||
}
|
||||
|
||||
// NewTerminateCustomImageRequest will create request of TerminateCustomImage action.
|
||||
func (c *UHostClient) NewTerminateCustomImageRequest() *TerminateCustomImageRequest {
|
||||
req := &TerminateCustomImageRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// TerminateCustomImage - 删除用户自定义镜像
|
||||
func (c *UHostClient) TerminateCustomImage(req *TerminateCustomImageRequest) (*TerminateCustomImageResponse, error) {
|
||||
var err error
|
||||
var res TerminateCustomImageResponse
|
||||
|
||||
err = c.Client.InvokeAction("TerminateCustomImage", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
71
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/terminate_uhost_instance.go
generated
vendored
Normal file
71
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/terminate_uhost_instance.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
//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 TerminateUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// TerminateUHostInstanceRequest is request schema for TerminateUHostInstance action
|
||||
type TerminateUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../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"`
|
||||
|
||||
// UHost资源Id 参见 [DescribeUHostInstance](describe_uhost_instance.html)
|
||||
UHostId *string `required:"true"`
|
||||
|
||||
// 是否直接删除,0表示按照原来的逻辑(有回收站权限,则进入回收站),1表示直接删除
|
||||
Destroy *int `required:"false"`
|
||||
|
||||
// 是否释放绑定的EIP。true: 解绑EIP后,并释放;其他值或不填:解绑EIP。
|
||||
ReleaseEIP *bool `required:"false"`
|
||||
|
||||
// 是否删除挂载的数据盘。true删除,其他不删除。
|
||||
ReleaseUDisk *bool `required:"false"`
|
||||
}
|
||||
|
||||
// TerminateUHostInstanceResponse is response schema for TerminateUHostInstance action
|
||||
type TerminateUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 放入回收站:"Yes", 彻底删除:“No”
|
||||
InRecycle string
|
||||
|
||||
// UHost 实例 Id
|
||||
UHostId string
|
||||
}
|
||||
|
||||
// NewTerminateUHostInstanceRequest will create request of TerminateUHostInstance action.
|
||||
func (c *UHostClient) NewTerminateUHostInstanceRequest() *TerminateUHostInstanceRequest {
|
||||
req := &TerminateUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// TerminateUHostInstance - 删除指定数据中心的UHost实例。
|
||||
func (c *UHostClient) TerminateUHostInstance(req *TerminateUHostInstanceRequest) (*TerminateUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res TerminateUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("TerminateUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
18
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_disk_query.go
generated
vendored
Normal file
18
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_disk_query.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostDisk - the request query for disk of uhost
|
||||
*/
|
||||
type UHostDisk struct {
|
||||
// 磁盘大小,单位GB。请参考[[api:uhost-api:disk_type|磁盘类型]]。
|
||||
Size *int `required:"true"`
|
||||
|
||||
// 磁盘类型。枚举值:LOCAL_NORMAL 普通本地盘 | CLOUD_NORMAL 普通云盘 |LOCAL_SSD SSD本地盘 | CLOUD_SSD SSD云盘,默认为LOCAL_NORMAL。请参考[[api:uhost-api:disk_type|磁盘类型]]。
|
||||
Type *string `required:"true"`
|
||||
|
||||
// 是否是系统盘。枚举值:\\ > True,是系统盘 \\ > False,是数据盘(默认)。Disks数组中有且只能有一块盘是系统盘。
|
||||
IsBoot *string `required:"true"`
|
||||
|
||||
// 磁盘备份方案。枚举值:\\ > NONE,无备份 \\ > DATAARK,数据方舟 \\ 当前磁盘支持的备份模式参考 [[api:uhost-api:disk_type|磁盘类型]]
|
||||
BackupType *string `required:"false"`
|
||||
}
|
34
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_disk_set.go
generated
vendored
Normal file
34
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_disk_set.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostDiskSet - DescribeUHostInstance
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UHostDiskSet struct {
|
||||
|
||||
// 磁盘类型。请参考[[api:uhost-api:disk_type|磁盘类型]]。
|
||||
DiskType string
|
||||
|
||||
// 是否是系统盘。枚举值:\\ > True,是系统盘 \\ > False,是数据盘(默认)。Disks数组中有且只能有一块盘是系统盘。
|
||||
IsBoot string
|
||||
|
||||
// 【建议不再使用】磁盘类型。系统盘: Boot,数据盘: Data,网络盘:Udisk
|
||||
Type string
|
||||
|
||||
// 磁盘ID
|
||||
DiskId string
|
||||
|
||||
// UDisk名字(仅当磁盘是UDisk时返回)
|
||||
Name string
|
||||
|
||||
// 磁盘盘符
|
||||
Drive string
|
||||
|
||||
// 磁盘大小,单位: GB
|
||||
Size int
|
||||
|
||||
// 备份方案。若开通了数据方舟,则为DataArk
|
||||
BackupType string
|
||||
}
|
58
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_image_set.go
generated
vendored
Normal file
58
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_image_set.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostImageSet - DescribeImage
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UHostImageSet struct {
|
||||
|
||||
// 可用区,参见 [可用区列表](../summary/regionlist.html) |
|
||||
Zone string
|
||||
|
||||
// 镜像ID
|
||||
ImageId string
|
||||
|
||||
// 镜像名称
|
||||
ImageName string
|
||||
|
||||
// 操作系统类型:Liunx,Windows
|
||||
OsType string
|
||||
|
||||
// 操作系统名称
|
||||
OsName string
|
||||
|
||||
// 镜像类型 标准镜像:Base, 行业镜像:Business,自定义镜像:Custom
|
||||
ImageType string
|
||||
|
||||
// 特殊状态标识, 目前包含NetEnhnced(网络增强1.0), NetEnhanced_Ultra](网络增强2.0)
|
||||
Features []string
|
||||
|
||||
// 行业镜像类型(仅行业镜像将返回这个值)
|
||||
FuncType string
|
||||
|
||||
// 集成软件名称(仅行业镜像将返回这个值)
|
||||
IntegratedSoftware string
|
||||
|
||||
// 供应商(仅行业镜像将返回这个值)
|
||||
Vendor string
|
||||
|
||||
// 介绍链接(仅行业镜像将返回这个值)
|
||||
Links string
|
||||
|
||||
// 镜像状态, 可用:Available,制作中:Making, 不可用:Unavailable
|
||||
State string
|
||||
|
||||
// 镜像描述
|
||||
ImageDescription string
|
||||
|
||||
// 创建时间,格式为Unix时间戳
|
||||
CreateTime int
|
||||
|
||||
// 镜像大小
|
||||
ImageSize int
|
||||
|
||||
// 默认值为空'''。当CentOS 7.3/7.4/7.5等镜像会标记为“Broadwell”
|
||||
MinimalCPU string
|
||||
}
|
112
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_instance_set.go
generated
vendored
Normal file
112
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_instance_set.go
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostInstanceSet - DescribeUHostInstance
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UHostInstanceSet struct {
|
||||
|
||||
// 可用区。参见 [可用区列表](../summary/regionlist.html)
|
||||
Zone string
|
||||
|
||||
// UHost实例ID
|
||||
UHostId string
|
||||
|
||||
// 云主机机型。参考[[api:uhost-api:uhost_type|云主机机型说明]]。
|
||||
UHostType string
|
||||
|
||||
// 【建议不再使用】主机磁盘类型。 枚举值为:\\ > LocalDisk,本地磁盘; \\ > UDisk 云盘。\\只要有一块磁盘为本地盘,即返回LocalDisk。
|
||||
StorageType string
|
||||
|
||||
// 【建议不再使用】主机的系统盘ID。
|
||||
ImageId string
|
||||
|
||||
// 基础镜像ID(指当前自定义镜像的来源镜像)
|
||||
BasicImageId string
|
||||
|
||||
// 基础镜像名称(指当前自定义镜像的来源镜像)
|
||||
BasicImageName string
|
||||
|
||||
// 业务组名称
|
||||
Tag string
|
||||
|
||||
// 备注
|
||||
Remark string
|
||||
|
||||
// UHost实例名称
|
||||
Name string
|
||||
|
||||
// 实例状态,枚举值:\\ >初始化: Initializing; \\ >启动中: Starting; \\> 运行中: Running; \\> 关机中: Stopping; \\ >关机: Stopped \\ >安装失败: Install Fail; \\ >重启中: Rebooting
|
||||
State string
|
||||
|
||||
// 创建时间,格式为Unix时间戳
|
||||
CreateTime int
|
||||
|
||||
// 计费模式,枚举值为: Year,按年付费; Month,按月付费; Dynamic,按需付费(需开启权限);
|
||||
ChargeType string
|
||||
|
||||
// 到期时间,格式为Unix时间戳
|
||||
ExpireTime int
|
||||
|
||||
// 虚拟CPU核数,单位: 个
|
||||
CPU int
|
||||
|
||||
// 内存大小,单位: MB
|
||||
Memory int
|
||||
|
||||
// 是否自动续费,自动续费:“Yes”,不自动续费:“No”
|
||||
AutoRenew string
|
||||
|
||||
// 磁盘信息见 UHostDiskSet
|
||||
DiskSet []UHostDiskSet
|
||||
|
||||
// 详细信息见 UHostIPSet
|
||||
IPSet []UHostIPSet
|
||||
|
||||
// 网络增强。Normal: 无;Super: 网络增强1.0; Ultra: 网络增强2.0
|
||||
NetCapability string
|
||||
|
||||
// 【建议不再使用】网络状态。 连接:Connected, 断开:NotConnected
|
||||
NetworkState string
|
||||
|
||||
// 【建议不再使用】数据方舟模式。枚举值:\\ > Yes: 开启方舟; \\ > no,未开启方舟
|
||||
TimemachineFeature string
|
||||
|
||||
// true: 开启热升级; false,未开启热升级
|
||||
HotplugFeature bool
|
||||
|
||||
// 【建议不再使用】仅北京A的云主机会返回此字段。基础网络模式:Default;子网模式:Private
|
||||
SubnetType string
|
||||
|
||||
// 内网的IP地址
|
||||
IPs []string
|
||||
|
||||
// 创建主机的最初来源镜像的操作系统名称(若直接通过基础镜像创建,此处返回和BasicImageName一致)
|
||||
OsName string
|
||||
|
||||
// 操作系统类别。返回"Linux"或者"Windows"
|
||||
OsType string
|
||||
|
||||
// 删除时间,格式为Unix时间戳
|
||||
DeleteTime int
|
||||
|
||||
// 主机系列:N2,表示系列2;N1,表示系列1
|
||||
HostType string
|
||||
|
||||
// 主机的生命周期类型。目前仅支持Normal:普通;
|
||||
LifeCycle string
|
||||
|
||||
// GPU个数
|
||||
GPU int
|
||||
|
||||
// 系统盘状态 Normal表示初始化完成;Initializing表示在初始化。仍在初始化的系统盘无法制作镜像。
|
||||
BootDiskState string
|
||||
|
||||
// 总的数据盘存储空间。
|
||||
TotalDiskSpace int
|
||||
|
||||
// 隔离组id,不在隔离组则返回""
|
||||
IsolationGroup string
|
||||
}
|
37
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_ipset.go
generated
vendored
Normal file
37
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_ipset.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostIPSet - DescribeUHostInstance
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UHostIPSet struct {
|
||||
|
||||
// 【暂未支持】是否为默认网卡。True: 是默认网卡;其他值:不是。
|
||||
Default string
|
||||
|
||||
// 当前网卡的Mac。
|
||||
Mac string
|
||||
|
||||
// 当前EIP的权重。权重最大的为当前的出口IP。
|
||||
Weight int
|
||||
|
||||
// 国际: Internation,BGP: Bgp,内网: Private
|
||||
Type string
|
||||
|
||||
// 外网IP资源ID 。(内网IP无对应的资源ID)
|
||||
IPId string
|
||||
|
||||
// IP地址
|
||||
IP string
|
||||
|
||||
// IP对应的带宽, 单位: Mb (内网IP不显示带宽信息)
|
||||
Bandwidth int
|
||||
|
||||
// IP地址对应的VPC ID。(北京一不支持,字段返回为空)
|
||||
VPCId string
|
||||
|
||||
// IP地址对应的子网 ID。(北京一不支持,字段返回为空)
|
||||
SubnetId string
|
||||
}
|
16
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_price_set.go
generated
vendored
Normal file
16
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_price_set.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostPriceSet - 主机价格
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UHostPriceSet struct {
|
||||
|
||||
// 计费类型。Year,Month,Dynamic
|
||||
ChargeType string
|
||||
|
||||
// 价格,单位: 元,保留小数点后两位有效数字
|
||||
Price float64
|
||||
}
|
19
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_tag_set.go
generated
vendored
Normal file
19
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/types_uhost_tag_set.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
package uhost
|
||||
|
||||
/*
|
||||
UHostTagSet - DescribeUHostTags
|
||||
|
||||
this model is auto created by ucloud code generater for open api,
|
||||
you can also see https://docs.ucloud.cn for detail.
|
||||
*/
|
||||
type UHostTagSet struct {
|
||||
|
||||
// 业务组名称
|
||||
Tag string
|
||||
|
||||
// 该业务组中包含的主机个数
|
||||
TotalCount int
|
||||
|
||||
// 可用区
|
||||
Zone string
|
||||
}
|
59
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/upgrade_to_ark_uhost_instance.go
generated
vendored
Normal file
59
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/upgrade_to_ark_uhost_instance.go
generated
vendored
Normal 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 UpgradeToArkUHostInstance
|
||||
|
||||
package uhost
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// UpgradeToArkUHostInstanceRequest is request schema for UpgradeToArkUHostInstance action
|
||||
type UpgradeToArkUHostInstanceRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
|
||||
// Region *string `required:"true"`
|
||||
|
||||
// [公共参数] 可用区。参见 [可用区列表](../summary/regionlist.html)
|
||||
// Zone *string `required:"true"`
|
||||
|
||||
// UHost主机的资源ID,例如UHostIds.0代表希望升级的主机1,UHostIds.1代表主机2。
|
||||
UHostIds []string `required:"true"`
|
||||
|
||||
// 代金券ID 请参考DescribeCoupon接口
|
||||
CouponId *string `required:"false"`
|
||||
}
|
||||
|
||||
// UpgradeToArkUHostInstanceResponse is response schema for UpgradeToArkUHostInstance action
|
||||
type UpgradeToArkUHostInstanceResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// UHost主机的资源ID数组
|
||||
UHostSet []string
|
||||
}
|
||||
|
||||
// NewUpgradeToArkUHostInstanceRequest will create request of UpgradeToArkUHostInstance action.
|
||||
func (c *UHostClient) NewUpgradeToArkUHostInstanceRequest() *UpgradeToArkUHostInstanceRequest {
|
||||
req := &UpgradeToArkUHostInstanceRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// UpgradeToArkUHostInstance - 普通升级为方舟机型
|
||||
func (c *UHostClient) UpgradeToArkUHostInstance(req *UpgradeToArkUHostInstanceRequest) (*UpgradeToArkUHostInstanceResponse, error) {
|
||||
var err error
|
||||
var res UpgradeToArkUHostInstanceResponse
|
||||
|
||||
err = c.Client.InvokeAction("UpgradeToArkUHostInstance", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
71
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/wait_until_uhost_instance_state.go
generated
vendored
Normal file
71
vendor/github.com/ucloud/ucloud-sdk-go/services/uhost/wait_until_uhost_instance_state.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
package uhost
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ucloud/ucloud-sdk-go/private/utils"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud"
|
||||
uerr "github.com/ucloud/ucloud-sdk-go/ucloud/error"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/log"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
)
|
||||
|
||||
// WaitUntilUHostInstanceStateRequest is the request of uhost instance state waiter
|
||||
type WaitUntilUHostInstanceStateRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
Interval *time.Duration
|
||||
MaxAttempts *int
|
||||
DescribeRequest *DescribeUHostInstanceRequest
|
||||
State State
|
||||
IgnoreError *bool
|
||||
}
|
||||
|
||||
// NewWaitUntilUHostInstanceStateRequest will create request of WaitUntilUHostInstanceState action.
|
||||
func (c *UHostClient) NewWaitUntilUHostInstanceStateRequest() *WaitUntilUHostInstanceStateRequest {
|
||||
cfg := c.Client.GetConfig()
|
||||
|
||||
return &WaitUntilUHostInstanceStateRequest{
|
||||
CommonBase: request.CommonBase{
|
||||
Region: ucloud.String(cfg.Region),
|
||||
ProjectId: ucloud.String(cfg.ProjectId),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// WaitUntilUHostInstanceState will pending current goroutine until the state has changed to expected state.
|
||||
func (c *UHostClient) WaitUntilUHostInstanceState(req *WaitUntilUHostInstanceStateRequest) error {
|
||||
waiter := utils.FuncWaiter{
|
||||
Interval: ucloud.TimeDurationValue(req.Interval),
|
||||
MaxAttempts: ucloud.IntValue(req.MaxAttempts),
|
||||
IgnoreError: ucloud.BoolValue(req.IgnoreError),
|
||||
Checker: func() (bool, error) {
|
||||
resp, err := c.DescribeUHostInstance(req.DescribeRequest)
|
||||
|
||||
if err != nil {
|
||||
skipErrors := []string{uerr.ErrNetwork, uerr.ErrHTTPStatus, uerr.ErrRetCode}
|
||||
if uErr, ok := err.(uerr.Error); ok && utils.IsStringIn(uErr.Name(), skipErrors) {
|
||||
log.Infof("skip error for wait resource state, %s", uErr)
|
||||
return false, nil
|
||||
}
|
||||
log.Infof("wait for resource state is ready, %s", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// TODO: Ensure if it is any data consistency problem?
|
||||
// Such as creating a new uhost, but cannot describe it's correct state immediately ...
|
||||
for _, uhost := range resp.UHostSet {
|
||||
if val, _ := req.State.MarshalValue(); uhost.State != val {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(resp.UHostSet) > 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
},
|
||||
}
|
||||
return waiter.WaitForCompletion()
|
||||
}
|
83
vendor/github.com/ucloud/ucloud-sdk-go/services/unet/allocate_eip.go
generated
vendored
Normal file
83
vendor/github.com/ucloud/ucloud-sdk-go/services/unet/allocate_eip.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
//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 AllocateEIP
|
||||
|
||||
package unet
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// AllocateEIPRequest is request schema for AllocateEIP action
|
||||
type AllocateEIPRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。
|
||||
// Region *string `required:"true"`
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。
|
||||
// ProjectId *string `required:"false"`
|
||||
|
||||
// 弹性IP的线路如下: 国际: International BGP: Bgp 各地域允许的线路参数如下: cn-sh1: Bgp cn-sh2: Bgp cn-gd: Bgp cn-bj1: Bgp cn-bj2: Bgp hk: International us-ca: International th-bkk: International kr-seoul:International us-ws:International ge-fra:International sg:International tw-kh:International.其他海外线路均为 International
|
||||
OperatorName *string `required:"true"`
|
||||
|
||||
// 弹性IP的外网带宽, 单位为Mbps. 共享带宽模式必须指定0M带宽, 非共享带宽模式必须指定非0Mbps带宽. 各地域非共享带宽的带宽范围如下: 流量计费[1-200],带宽计费[1-800]
|
||||
Bandwidth *int `required:"true"`
|
||||
|
||||
// 业务组名称, 默认为 "Default"
|
||||
Tag *string `required:"false"`
|
||||
|
||||
// 付费方式, 枚举值为: Year, 按年付费; Month, 按月付费; Dynamic, 按需付费(需开启权限); Trial, 试用(需开启权限) 默认为按月付费
|
||||
ChargeType *string `required:"false"`
|
||||
|
||||
// 购买时长, 默认: 1
|
||||
Quantity *int `required:"false"`
|
||||
|
||||
// 弹性IP的计费模式. 枚举值: "Traffic", 流量计费; "Bandwidth", 带宽计费; "ShareBandwidth",共享带宽模式. 默认为 "Bandwidth".
|
||||
PayMode *string `required:"false"`
|
||||
|
||||
// 绑定的共享带宽Id,仅当PayMode为ShareBandwidth时有效
|
||||
ShareBandwidthId *string `required:"false"`
|
||||
|
||||
// 弹性IP的名称, 默认为 "EIP"
|
||||
Name *string `required:"false"`
|
||||
|
||||
// 弹性IP的备注, 默认为空
|
||||
Remark *string `required:"false"`
|
||||
|
||||
// 代金券ID, 默认不使用
|
||||
CouponId *string `required:"false"`
|
||||
}
|
||||
|
||||
// AllocateEIPResponse is response schema for AllocateEIP action
|
||||
type AllocateEIPResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 申请到的EIP资源详情 参见 UnetAllocateEIPSet
|
||||
EIPSet []UnetAllocateEIPSet
|
||||
}
|
||||
|
||||
// NewAllocateEIPRequest will create request of AllocateEIP action.
|
||||
func (c *UNetClient) NewAllocateEIPRequest() *AllocateEIPRequest {
|
||||
req := &AllocateEIPRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// AllocateEIP - 根据提供信息, 申请弹性IP
|
||||
func (c *UNetClient) AllocateEIP(req *AllocateEIPRequest) (*AllocateEIPResponse, error) {
|
||||
var err error
|
||||
var res AllocateEIPResponse
|
||||
|
||||
err = c.Client.InvokeAction("AllocateEIP", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
68
vendor/github.com/ucloud/ucloud-sdk-go/services/unet/allocate_share_bandwidth.go
generated
vendored
Normal file
68
vendor/github.com/ucloud/ucloud-sdk-go/services/unet/allocate_share_bandwidth.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
//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 AllocateShareBandwidth
|
||||
|
||||
package unet
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// AllocateShareBandwidthRequest is request schema for AllocateShareBandwidth action
|
||||
type AllocateShareBandwidthRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域。 参见 [地域和可用区列表](../summary/regionlist.html)
|
||||
// Region *string `required:"true"`
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。
|
||||
// ProjectId *string `required:"false"`
|
||||
|
||||
// 共享带宽名字
|
||||
Name *string `required:"true"`
|
||||
|
||||
// 付费方式:Year 按年,Month 按月,Dynamic 按时;
|
||||
ChargeType *string `required:"true"`
|
||||
|
||||
// 共享带宽值
|
||||
ShareBandwidth *int `required:"true"`
|
||||
|
||||
// 购买时长
|
||||
Quantity *int `required:"false"`
|
||||
|
||||
// 共享带宽保底值(后付费)
|
||||
ShareBandwidthGuarantee *int `required:"false"`
|
||||
}
|
||||
|
||||
// AllocateShareBandwidthResponse is response schema for AllocateShareBandwidth action
|
||||
type AllocateShareBandwidthResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 共享带宽资源Id
|
||||
ShareBandwidthId string
|
||||
}
|
||||
|
||||
// NewAllocateShareBandwidthRequest will create request of AllocateShareBandwidth action.
|
||||
func (c *UNetClient) NewAllocateShareBandwidthRequest() *AllocateShareBandwidthRequest {
|
||||
req := &AllocateShareBandwidthRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// AllocateShareBandwidth - 开通共享带宽
|
||||
func (c *UNetClient) AllocateShareBandwidth(req *AllocateShareBandwidthRequest) (*AllocateShareBandwidthResponse, error) {
|
||||
var err error
|
||||
var res AllocateShareBandwidthResponse
|
||||
|
||||
err = c.Client.InvokeAction("AllocateShareBandwidth", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
80
vendor/github.com/ucloud/ucloud-sdk-go/services/unet/allocate_vip.go
generated
vendored
Normal file
80
vendor/github.com/ucloud/ucloud-sdk-go/services/unet/allocate_vip.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
//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 AllocateVIP
|
||||
|
||||
package unet
|
||||
|
||||
import (
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/request"
|
||||
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
|
||||
)
|
||||
|
||||
// AllocateVIPRequest is request schema for AllocateVIP action
|
||||
type AllocateVIPRequest struct {
|
||||
request.CommonBase
|
||||
|
||||
// [公共参数] 地域
|
||||
// Region *string `required:"true"`
|
||||
|
||||
// [公共参数] 可用区
|
||||
// Zone *string `required:"false"`
|
||||
|
||||
// [公共参数] 项目ID。不填写为默认项目,子帐号必须填写。 请参考[GetProjectList接口](../summary/get_project_list.html)
|
||||
// ProjectId *string `required:"false"`
|
||||
|
||||
// 指定vip所属的VPC
|
||||
VPCId *string `required:"true"`
|
||||
|
||||
// 子网id
|
||||
SubnetId *string `required:"true"`
|
||||
|
||||
// 申请数量,默认: 1
|
||||
Count *int `required:"false"`
|
||||
|
||||
// vip名,默认为VIP
|
||||
Name *string `required:"false"`
|
||||
|
||||
// 业务组名称,默认为Default
|
||||
Tag *string `required:"false"`
|
||||
|
||||
// 备注
|
||||
Remark *string `required:"false"`
|
||||
|
||||
// 业务组
|
||||
BusinessId *string `required:"false"`
|
||||
}
|
||||
|
||||
// AllocateVIPResponse is response schema for AllocateVIP action
|
||||
type AllocateVIPResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
// 申请到的VIP资源相关信息
|
||||
VIPSet []VIPSet
|
||||
|
||||
// 申请到的VIP地址
|
||||
DataSet []string
|
||||
}
|
||||
|
||||
// NewAllocateVIPRequest will create request of AllocateVIP action.
|
||||
func (c *UNetClient) NewAllocateVIPRequest() *AllocateVIPRequest {
|
||||
req := &AllocateVIPRequest{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// AllocateVIP - 根据提供信息,申请内网VIP(Virtual IP),多用于高可用程序作为漂移IP。
|
||||
func (c *UNetClient) AllocateVIP(req *AllocateVIPRequest) (*AllocateVIPResponse, error) {
|
||||
var err error
|
||||
var res AllocateVIPResponse
|
||||
|
||||
err = c.Client.InvokeAction("AllocateVIP", req, &res)
|
||||
if err != nil {
|
||||
return &res, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue