Unverified Commit 605e37bd by Shuwei Hao Committed by GitHub

Merge pull request #20 from haoshuwei/velero-plugin-update

update dependencies of velero plugin for alibabacloud
parents 94ce8eb4 341be9d7

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

.go
_output
.idea
velero-*
_output
\ No newline at end of file
module github.com/AliyunContainerService/velero-plugin
go 1.13
require (
github.com/Azure/go-autorest/autorest v0.9.3 // indirect
github.com/Azure/go-autorest/autorest/adal v0.8.1 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.60.302
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible
github.com/hashicorp/go-plugin v1.0.1 // indirect
github.com/heptio/velero v1.2.0
github.com/imdario/mergo v0.3.8 // indirect
github.com/joho/godotenv v1.3.0
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.4.2
github.com/spf13/cobra v0.0.5 // indirect
github.com/stretchr/testify v1.4.0
github.com/vmware-tanzu/velero v1.2.0
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
google.golang.org/grpc v1.26.0 // indirect
k8s.io/api v0.17.0
k8s.io/apimachinery v0.17.0
k8s.io/client-go v11.0.0+incompatible // indirect
k8s.io/utils v0.0.0-20191218082557-f07c713de883 // indirect
)
This diff is collapsed. Click to expand it.
package main
import (
"github.com/joho/godotenv"
"os"
"github.com/pkg/errors"
"io/ioutil"
"net/http"
"fmt"
)
const (
metadataURL = "http://100.100.100.200/latest/meta-data/"
metadataRegionKey = "region"
metadataZoneKey = "zone-id"
regionConfigKey = "region"
)
// load environment vars from $ALIBABA_CLOUD_CREDENTIALS_FILE, if it exists
func loadEnv() error {
envFile := os.Getenv("ALIBABA_CLOUD_CREDENTIALS_FILE")
if envFile == "" {
return nil
}
if err := godotenv.Overload(envFile); err != nil {
return errors.Wrapf(err, "error loading environment from ALIBABA_CLOUD_CREDENTIALS_FILE (%s)", envFile)
}
return nil
}
// get region or available zone information
func getMetaData(resource string) (string, error) {
resp, err := http.Get(metadataURL + resource)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
// getOssEndpoint return oss endpoint in format "oss-%s.aliyuncs.com"
func getOssEndpoint(config map[string]string) string {
if value := config[regionConfigKey]; value == "" {
if value, err := getMetaData(metadataRegionKey); err != nil {
// set default region
return "oss-cn-hangzhou.aliyuncs.com"
} else {
return fmt.Sprintf("oss-%s.aliyuncs.com", value)
}
} else {
return fmt.Sprintf("oss-%s.aliyuncs.com", value)
}
}
// getEcsRegionID return ecs region id
func getEcsRegionID(config map[string]string) string {
if value := config[regionConfigKey]; value == "" {
if value, err := getMetaData(metadataRegionKey); err != nil {
// set default region
return "cn-hangzhou"
} else {
return value
}
} else {
return value
}
}
\ No newline at end of file
......@@ -17,8 +17,7 @@ limitations under the License.
package main
import (
"github.com/AliyunContainerService/velero-plugin/pkg/alibabacloud"
veleroplugin "github.com/heptio/velero/pkg/plugin/framework"
veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework"
"github.com/sirupsen/logrus"
)
......@@ -30,9 +29,9 @@ func main() {
}
func newAlibabaCloudObjectStore(logger logrus.FieldLogger) (interface{}, error) {
return alibabacloud.NewObjectStore(logger), nil
return newObjectStore(logger), nil
}
func newAlibabaCloudVolumeSnapshotter(logger logrus.FieldLogger) (interface{}, error) {
return alibabacloud.NewVolumeSnapshotter(logger), nil
return newVolumeSnapshotter(logger), nil
}
......@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package alibabacloud
package main
import (
"io"
......@@ -19,7 +19,6 @@ import (
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/joho/godotenv"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
......@@ -28,7 +27,7 @@ import (
"bytes"
"compress/gzip"
"fmt"
"github.com/heptio/velero/pkg/cloudprovider"
veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework"
"io/ioutil"
"math/rand"
"path/filepath"
......@@ -37,7 +36,6 @@ import (
)
const (
RegionKey = "region"
OriginStr = "volumeId"
TargetStr = "VolumeId"
Workspace = "/tmp/velero-restore/"
......@@ -48,11 +46,11 @@ type bucketGetter interface {
}
type ossBucket interface {
IsObjectExist(key string) (bool, error)
IsObjectExist(key string, options ...oss.Option) (bool, error)
ListObjects(options ...oss.Option) (oss.ListObjectsResult, error)
PutObject(objectKey string, reader io.Reader, options ...oss.Option) error
GetObject(key string, options ...oss.Option) (io.ReadCloser, error)
DeleteObject(key string) error
DeleteObject(key string, options ...oss.Option) error
SignURL(objectKey string, method oss.HTTPMethod, expiredInSec int64, options ...oss.Option) (string, error)
}
......@@ -73,7 +71,7 @@ type ObjectStore struct {
}
// NewObjectStore init ObjectStore
func NewObjectStore(logger logrus.FieldLogger) *ObjectStore {
func newObjectStore(logger logrus.FieldLogger) *ObjectStore {
return &ObjectStore{log: logger}
}
......@@ -85,23 +83,9 @@ func (o *ObjectStore) getBucket(bucket string) (ossBucket, error) {
return bucketObj, err
}
// load environment vars from $ALIBABA_CLOUD_CREDENTIALS_FILE, if it exists
func loadEnv() error {
envFile := os.Getenv("ALIBABA_CLOUD_CREDENTIALS_FILE")
if envFile == "" {
return nil
}
if err := godotenv.Overload(envFile); err != nil {
return errors.Wrapf(err, "error loading environment from ALIBABA_CLOUD_CREDENTIALS_FILE (%s)", envFile)
}
return nil
}
// Init init oss client with os envs
func (o *ObjectStore) Init(config map[string]string) error {
if err := cloudprovider.ValidateObjectStoreConfigKeys(config); err != nil {
if err := veleroplugin.ValidateObjectStoreConfigKeys(config, regionConfigKey); err != nil {
return err
}
......@@ -114,8 +98,6 @@ func (o *ObjectStore) Init(config map[string]string) error {
stsToken := os.Getenv("ALIBABA_CLOUD_ACCESS_STS_TOKEN")
encryptionKeyID := os.Getenv("ALIBABA_CLOUD_ENCRYPTION_KEY_ID")
endpoint := os.Getenv("ALIBABA_CLOUD_OSS_ENDPOINT")
if len(accessKeyID) == 0 {
return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is not set")
}
......@@ -124,11 +106,7 @@ func (o *ObjectStore) Init(config map[string]string) error {
return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is not set")
}
if len(endpoint) == 0 {
// Set default endpoint
endpoint = "oss-cn-hangzhou.aliyuncs.com"
}
endpoint := getOssEndpoint(config)
var client *oss.Client
var err error
......
......@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package alibabacloud
package main
import (
"io"
......
......@@ -11,12 +11,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package alibabacloud
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"regexp"
"strings"
......@@ -25,16 +23,15 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"github.com/heptio/velero/pkg/cloudprovider"
veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework"
)
const (
ackClusterNameKey = "ACK_CLUSTER_NAME"
metadataURL = "http://100.100.100.200/latest/meta-data/"
)
// VolumeSnapshotter struct
......@@ -44,13 +41,13 @@ type VolumeSnapshotter struct {
}
// NewVolumeSnapshotter init a VolumeSnapshotter
func NewVolumeSnapshotter(logger logrus.FieldLogger) *VolumeSnapshotter {
func newVolumeSnapshotter(logger logrus.FieldLogger) *VolumeSnapshotter {
return &VolumeSnapshotter{log: logger}
}
// Init init ecs client with os env
func (b *VolumeSnapshotter) Init(config map[string]string) error {
if err := cloudprovider.ValidateVolumeSnapshotterConfigKeys(config, RegionKey); err != nil {
if err := veleroplugin.ValidateVolumeSnapshotterConfigKeys(config, regionConfigKey); err != nil {
return err
}
......@@ -58,10 +55,7 @@ func (b *VolumeSnapshotter) Init(config map[string]string) error {
return err
}
region := config[RegionKey]
if region == "" {
return errors.Errorf("missing %s in Alibaba Cloud configuration", RegionKey)
}
regionID := getEcsRegionID(config)
accessKeyID := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
accessKeySecret := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
......@@ -78,9 +72,9 @@ func (b *VolumeSnapshotter) Init(config map[string]string) error {
var err error
if len(stsToken) == 0 {
client, err = ecs.NewClientWithAccessKey(region, accessKeyID, accessKeySecret)
client, err = ecs.NewClientWithAccessKey(regionID, accessKeyID, accessKeySecret)
} else {
client, err = ecs.NewClientWithStsToken(region, accessKeyID, accessKeySecret, stsToken)
client, err = ecs.NewClientWithStsToken(regionID, accessKeyID, accessKeySecret, stsToken)
}
b.ecs = client
return err
......@@ -107,7 +101,7 @@ func (b *VolumeSnapshotter) CreateVolumeFromSnapshot(snapshotID, volumeType, vol
tags := getTagsForCluster(snapRes.Snapshots.Snapshot[0].Tags.Tag)
volumeAZ, err = GetMetaData("zone-id")
volumeAZ, err = getMetaData(metadataZoneKey)
if err != nil {
return "", errors.Errorf("failed to get zone-id, got %v", err)
}
......@@ -372,17 +366,3 @@ func (b *VolumeSnapshotter) SetVolumeID(unstructuredPV runtime.Unstructured, vol
return &unstructured.Unstructured{Object: res}, nil
}
// GetMetaData get the AZ infos
func GetMetaData(resource string) (string, error) {
resp, err := http.Get(metadataURL + resource)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
......@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package alibabacloud
package main
import (
"os"
......
# This is the official list of cloud authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
# Names should be added to this file as:
# Name or Organization <email address>
# The email address is not required for organizations.
Filippo Valsorda <hi@filippo.io>
Google Inc.
Ingo Oeser <nightlyone@googlemail.com>
Palm Stone Games, Inc.
Paweł Knap <pawelknap88@gmail.com>
Péter Szilágyi <peterke@gmail.com>
Tyler Treat <ttreat31@gmail.com>
# People who have agreed to one of the CLAs and can contribute patches.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# https://developers.google.com/open-source/cla/individual
# https://developers.google.com/open-source/cla/corporate
#
# Names should be added to this file as:
# Name <email address>
# Keep the list alphabetically sorted.
Alexis Hunt <lexer@google.com>
Andreas Litt <andreas.litt@gmail.com>
Andrew Gerrand <adg@golang.org>
Brad Fitzpatrick <bradfitz@golang.org>
Burcu Dogan <jbd@google.com>
Dave Day <djd@golang.org>
David Sansome <me@davidsansome.com>
David Symonds <dsymonds@golang.org>
Filippo Valsorda <hi@filippo.io>
Glenn Lewis <gmlewis@google.com>
Ingo Oeser <nightlyone@googlemail.com>
James Hall <james.hall@shopify.com>
Johan Euphrosine <proppy@google.com>
Jonathan Amsterdam <jba@google.com>
Kunpei Sakai <namusyaka@gmail.com>
Luna Duclos <luna.duclos@palmstonegames.com>
Magnus Hiie <magnus.hiie@gmail.com>
Mario Castro <mariocaster@gmail.com>
Michael McGreevy <mcgreevy@golang.org>
Omar Jarjur <ojarjur@google.com>
Paweł Knap <pawelknap88@gmail.com>
Péter Szilágyi <peterke@gmail.com>
Sarah Adams <shadams@google.com>
Thanatat Tamtan <acoshift@gmail.com>
Toby Burress <kurin@google.com>
Tuo Shan <shantuo@google.com>
Tyler Treat <ttreat31@gmail.com>
......@@ -20,7 +20,6 @@
package metadata // import "cloud.google.com/go/compute/metadata"
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
......@@ -32,6 +31,9 @@ import (
"strings"
"sync"
"time"
"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
)
const (
......@@ -137,11 +139,11 @@ func testOnGCE() bool {
resc := make(chan bool, 2)
// Try two strategies in parallel.
// See https://github.com/googleapis/google-cloud-go/issues/194
// See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/194
go func() {
req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
req.Header.Set("User-Agent", userAgent)
res, err := defaultClient.hc.Do(req.WithContext(ctx))
res, err := ctxhttp.Do(ctx, defaultClient.hc, req)
if err != nil {
resc <- false
return
......@@ -300,8 +302,8 @@ func (c *Client) getETag(suffix string) (value, etag string, err error) {
// being stable anyway.
host = metadataIP
}
u := "http://" + host + "/computeMetadata/v1/" + suffix
req, _ := http.NewRequest("GET", u, nil)
url := "http://" + host + "/computeMetadata/v1/" + suffix
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Metadata-Flavor", "Google")
req.Header.Set("User-Agent", userAgent)
res, err := c.hc.Do(req)
......@@ -312,13 +314,13 @@ func (c *Client) getETag(suffix string) (value, etag string, err error) {
if res.StatusCode == http.StatusNotFound {
return "", "", NotDefinedError(suffix)
}
if res.StatusCode != 200 {
return "", "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url)
}
all, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", "", err
}
if res.StatusCode != 200 {
return "", "", &Error{Code: res.StatusCode, Message: string(all)}
}
return string(all), res.Header.Get("Etag"), nil
}
......@@ -499,15 +501,3 @@ func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) erro
}
}
}
// Error contains an error response from the server.
type Error struct {
// Code is the HTTP response status code.
Code int
// Message is the server response message.
Message string
}
func (e *Error) Error() string {
return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message)
}
# Azure Active Directory authentication for Go
This is a standalone package for authenticating with Azure Active
Directory from other Go libraries and applications, in particular the [Azure SDK
for Go](https://github.com/Azure/azure-sdk-for-go).
Note: Despite the package's name it is not related to other "ADAL" libraries
maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues
should be opened in [this repo's](https://github.com/Azure/go-autorest/issues)
or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue
trackers.
## Install
```bash
go get -u github.com/Azure/go-autorest/autorest/adal
```
## Usage
An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
### Register an Azure AD Application with secret
1. Register a new application with a `secret` credential
```
az ad app create \
--display-name example-app \
--homepage https://example-app/home \
--identifier-uris https://example-app/app \
--password secret
```
2. Create a service principal using the `Application ID` from previous step
```
az ad sp create --id "Application ID"
```
* Replace `Application ID` with `appId` from step 1.
### Register an Azure AD Application with certificate
1. Create a private key
```
openssl genrsa -out "example-app.key" 2048
```
2. Create the certificate
```
openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr"
openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000
```
3. Create the PKCS12 version of the certificate containing also the private key
```
openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass:
```
4. Register a new application with the certificate content form `example-app.crt`
```
certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)"
az ad app create \
--display-name example-app \
--homepage https://example-app/home \
--identifier-uris https://example-app/app \
--key-usage Verify --end-date 2018-01-01 \
--key-value "${certificateContents}"
```
5. Create a service principal using the `Application ID` from previous step
```
az ad sp create --id "APPLICATION_ID"
```
* Replace `APPLICATION_ID` with `appId` from step 4.
### Grant the necessary permissions
Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained
level. There is a set of [pre-defined roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles)
which can be assigned to a service principal of an Azure AD application depending of your needs.
```
az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME"
```
* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step.
* Replace the `ROLE_NAME` with a role name of your choice.
It is also possible to define custom role definitions.
```
az role definition create --role-definition role-definition.json
```
* Check [custom roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file.
### Acquire Access Token
The common configuration used by all flows:
```Go
const activeDirectoryEndpoint = "https://login.microsoftonline.com/"
tenantID := "TENANT_ID"
oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID)
applicationID := "APPLICATION_ID"
callback := func(token adal.Token) error {
// This is called after the token is acquired
}
// The resource for which the token is acquired
resource := "https://management.core.windows.net/"
```
* Replace the `TENANT_ID` with your tenant ID.
* Replace the `APPLICATION_ID` with the value from previous section.
#### Client Credentials
```Go
applicationSecret := "APPLICATION_SECRET"
spt, err := adal.NewServicePrincipalToken(
*oauthConfig,
appliationID,
applicationSecret,
resource,
callbacks...)
if err != nil {
return nil, err
}
// Acquire a new access token
err = spt.Refresh()
if (err == nil) {
token := spt.Token
}
```
* Replace the `APPLICATION_SECRET` with the `password` value from previous section.
#### Client Certificate
```Go
certificatePath := "./example-app.pfx"
certData, err := ioutil.ReadFile(certificatePath)
if err != nil {
return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err)
}
// Get the certificate and private key from pfx file
certificate, rsaPrivateKey, err := decodePkcs12(certData, "")
if err != nil {
return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
}
spt, err := adal.NewServicePrincipalTokenFromCertificate(
*oauthConfig,
applicationID,
certificate,
rsaPrivateKey,
resource,
callbacks...)
// Acquire a new access token
err = spt.Refresh()
if (err == nil) {
token := spt.Token
}
```
* Update the certificate path to point to the example-app.pfx file which was created in previous section.
#### Device Code
```Go
oauthClient := &http.Client{}
// Acquire the device code
deviceCode, err := adal.InitiateDeviceAuth(
oauthClient,
*oauthConfig,
applicationID,
resource)
if err != nil {
return nil, fmt.Errorf("Failed to start device auth flow: %s", err)
}
// Display the authentication message
fmt.Println(*deviceCode.Message)
// Wait here until the user is authenticated
token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
if err != nil {
return nil, fmt.Errorf("Failed to finish device auth flow: %s", err)
}
spt, err := adal.NewServicePrincipalTokenFromManualToken(
*oauthConfig,
applicationID,
resource,
*token,
callbacks...)
if (err == nil) {
token := spt.Token
}
```
#### Username password authenticate
```Go
spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
*oauthConfig,
applicationID,
username,
password,
resource,
callbacks...)
if (err == nil) {
token := spt.Token
}
```
#### Authorization code authenticate
``` Go
spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
*oauthConfig,
applicationID,
clientSecret,
authorizationCode,
redirectURI,
resource,
callbacks...)
err = spt.Refresh()
if (err == nil) {
token := spt.Token
}
```
### Command Line Tool
A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
```
adal -h
Usage of ./adal:
-applicationId string
application id
-certificatePath string
path to pk12/PFC application certificate
-mode string
authentication mode (device, secret, cert, refresh) (default "device")
-resource string
resource for which the token is requested
-secret string
application secret
-tenantId string
tenant id
-tokenCachePath string
location of oath token cache (default "/home/cgc/.adal/accessToken.json")
```
Example acquire a token for `https://management.core.windows.net/` using device code flow:
```
adal -mode device \
-applicationId "APPLICATION_ID" \
-tenantId "TENANT_ID" \
-resource https://management.core.windows.net/
```
......@@ -24,6 +24,7 @@ package adal
*/
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
......@@ -101,7 +102,14 @@ type deviceToken struct {
// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
// Deprecated: use InitiateDeviceAuthWithContext() instead.
func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
return InitiateDeviceAuthWithContext(context.Background(), sender, oauthConfig, clientID, resource)
}
// InitiateDeviceAuthWithContext initiates a device auth flow. It returns a DeviceCode
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
func InitiateDeviceAuthWithContext(ctx context.Context, sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
v := url.Values{
"client_id": []string{clientID},
"resource": []string{resource},
......@@ -117,7 +125,7 @@ func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resour
req.ContentLength = int64(len(s))
req.Header.Set(contentType, mimeTypeFormPost)
resp, err := sender.Do(req)
resp, err := sender.Do(req.WithContext(ctx))
if err != nil {
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
}
......@@ -151,7 +159,14 @@ func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resour
// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint
// to see if the device flow has: been completed, timed out, or otherwise failed
// Deprecated: use CheckForUserCompletionWithContext() instead.
func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
return CheckForUserCompletionWithContext(context.Background(), sender, code)
}
// CheckForUserCompletionWithContext takes a DeviceCode and checks with the Azure AD OAuth endpoint
// to see if the device flow has: been completed, timed out, or otherwise failed
func CheckForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) {
v := url.Values{
"client_id": []string{code.ClientID},
"code": []string{*code.DeviceCode},
......@@ -169,7 +184,7 @@ func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
req.ContentLength = int64(len(s))
req.Header.Set(contentType, mimeTypeFormPost)
resp, err := sender.Do(req)
resp, err := sender.Do(req.WithContext(ctx))
if err != nil {
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
}
......@@ -213,12 +228,19 @@ func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs.
// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
// Deprecated: use WaitForUserCompletionWithContext() instead.
func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
return WaitForUserCompletionWithContext(context.Background(), sender, code)
}
// WaitForUserCompletionWithContext calls CheckForUserCompletion repeatedly until a token is granted or an error
// state occurs. This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
func WaitForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) {
intervalDuration := time.Duration(*code.Interval) * time.Second
waitDuration := intervalDuration
for {
token, err := CheckForUserCompletion(sender, code)
token, err := CheckForUserCompletionWithContext(ctx, sender, code)
if err == nil {
return token, nil
......@@ -237,6 +259,11 @@ func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix)
}
time.Sleep(waitDuration)
select {
case <-time.After(waitDuration):
// noop
case <-ctx.Done():
return nil, ctx.Err()
}
}
}
module github.com/Azure/go-autorest/autorest/adal
go 1.12
require (
github.com/Azure/go-autorest/autorest v0.9.0
github.com/Azure/go-autorest/autorest/date v0.2.0
github.com/Azure/go-autorest/autorest/mocks v0.3.0
github.com/Azure/go-autorest/tracing v0.5.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
)
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
// +build modhack
package adal
// Copyright 2017 Microsoft Corporation
//
// 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.
// This file, and the github.com/Azure/go-autorest/autorest import, won't actually become part of
// the resultant binary.
// Necessary for safely adding multi-module repo.
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
import _ "github.com/Azure/go-autorest/autorest"
......@@ -26,9 +26,9 @@ import (
"fmt"
"io/ioutil"
"math"
"net"
"net/http"
"net/url"
"os"
"strings"
"sync"
"time"
......@@ -63,6 +63,12 @@ const (
// the default number of attempts to refresh an MSI authentication token
defaultMaxMSIRefreshAttempts = 5
// asMSIEndpointEnv is the environment variable used to store the endpoint on App Service and Functions
asMSIEndpointEnv = "MSI_ENDPOINT"
// asMSISecretEnv is the environment variable used to store the request secret on App Service and Functions
asMSISecretEnv = "MSI_SECRET"
)
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
......@@ -100,6 +106,9 @@ type RefresherWithContext interface {
// a successful token refresh
type TokenRefreshCallback func(Token) error
// TokenRefresh is a type representing a custom callback to refresh a token
type TokenRefresh func(ctx context.Context, resource string) (*Token, error)
// Token encapsulates the access token used to authorize Azure requests.
// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response
type Token struct {
......@@ -338,10 +347,11 @@ func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, err
// ServicePrincipalToken encapsulates a Token created for a Service Principal.
type ServicePrincipalToken struct {
inner servicePrincipalToken
refreshLock *sync.RWMutex
sender Sender
refreshCallbacks []TokenRefreshCallback
inner servicePrincipalToken
refreshLock *sync.RWMutex
sender Sender
customRefreshFunc TokenRefresh
refreshCallbacks []TokenRefreshCallback
// MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token.
MaxMSIRefreshAttempts int
}
......@@ -356,6 +366,11 @@ func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCa
spt.refreshCallbacks = callbacks
}
// SetCustomRefreshFunc sets a custom refresh function used to refresh the token.
func (spt *ServicePrincipalToken) SetCustomRefreshFunc(customRefreshFunc TokenRefresh) {
spt.customRefreshFunc = customRefreshFunc
}
// MarshalJSON implements the json.Marshaler interface.
func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) {
return json.Marshal(spt.inner)
......@@ -634,6 +649,31 @@ func GetMSIVMEndpoint() (string, error) {
return msiEndpoint, nil
}
func isAppService() bool {
_, asMSIEndpointEnvExists := os.LookupEnv(asMSIEndpointEnv)
_, asMSISecretEnvExists := os.LookupEnv(asMSISecretEnv)
return asMSIEndpointEnvExists && asMSISecretEnvExists
}
// GetMSIAppServiceEndpoint get the MSI endpoint for App Service and Functions
func GetMSIAppServiceEndpoint() (string, error) {
asMSIEndpoint, asMSIEndpointEnvExists := os.LookupEnv(asMSIEndpointEnv)
if asMSIEndpointEnvExists {
return asMSIEndpoint, nil
}
return "", errors.New("MSI endpoint not found")
}
// GetMSIEndpoint get the appropriate MSI endpoint depending on the runtime environment
func GetMSIEndpoint() (string, error) {
if isAppService() {
return GetMSIAppServiceEndpoint()
}
return GetMSIVMEndpoint()
}
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
// It will use the system assigned identity when creating the token.
func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
......@@ -666,7 +706,12 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI
v := url.Values{}
v.Set("resource", resource)
v.Set("api-version", "2018-02-01")
// App Service MSI currently only supports token API version 2017-09-01
if isAppService() {
v.Set("api-version", "2017-09-01")
} else {
v.Set("api-version", "2018-02-01")
}
if userAssignedID != nil {
v.Set("client_id", *userAssignedID)
}
......@@ -750,13 +795,13 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
}
// Refresh obtains a fresh token for the Service Principal.
// This method is not safe for concurrent use and should be syncrhonized.
// This method is safe for concurrent use.
func (spt *ServicePrincipalToken) Refresh() error {
return spt.RefreshWithContext(context.Background())
}
// RefreshWithContext obtains a fresh token for the Service Principal.
// This method is not safe for concurrent use and should be syncrhonized.
// This method is safe for concurrent use.
func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
spt.refreshLock.Lock()
defer spt.refreshLock.Unlock()
......@@ -764,13 +809,13 @@ func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error
}
// RefreshExchange refreshes the token, but for a different resource.
// This method is not safe for concurrent use and should be syncrhonized.
// This method is safe for concurrent use.
func (spt *ServicePrincipalToken) RefreshExchange(resource string) error {
return spt.RefreshExchangeWithContext(context.Background(), resource)
}
// RefreshExchangeWithContext refreshes the token, but for a different resource.
// This method is not safe for concurrent use and should be syncrhonized.
// This method is safe for concurrent use.
func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
spt.refreshLock.Lock()
defer spt.refreshLock.Unlock()
......@@ -793,15 +838,29 @@ func isIMDS(u url.URL) bool {
if err != nil {
return false
}
return u.Host == imds.Host && u.Path == imds.Path
return (u.Host == imds.Host && u.Path == imds.Path) || isAppService()
}
func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error {
if spt.customRefreshFunc != nil {
token, err := spt.customRefreshFunc(ctx, resource)
if err != nil {
return err
}
spt.inner.Token = *token
return spt.InvokeRefreshCallbacks(spt.inner.Token)
}
req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil)
if err != nil {
return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err)
}
req.Header.Add("User-Agent", UserAgent())
// Add header when runtime is on App Service or Functions
if isAppService() {
asMSISecret, _ := os.LookupEnv(asMSISecretEnv)
req.Header.Add("Secret", asMSISecret)
}
req = req.WithContext(ctx)
if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
v := url.Values{}
......@@ -846,7 +905,8 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource
resp, err = spt.sender.Do(req)
}
if err != nil {
return newTokenRefreshError(fmt.Sprintf("adal: Failed to execute the refresh request. Error = '%v'", err), nil)
// don't return a TokenRefreshError here; this will allow retry logic to apply
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
}
defer resp.Body.Close()
......@@ -913,10 +973,8 @@ func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http
for attempt < maxAttempts {
resp, err = sender.Do(req)
// retry on temporary network errors, e.g. transient network failures.
// if we don't receive a response then assume we can't connect to the
// endpoint so we're likely not running on an Azure VM so don't retry.
if (err != nil && !isTemporaryNetworkError(err)) || resp == nil || resp.StatusCode == http.StatusOK || !containsInt(retries, resp.StatusCode) {
// we want to retry if err is not nil or the status code is in the list of retry codes
if err == nil && !responseHasStatusCode(resp, retries...) {
return
}
......@@ -940,20 +998,12 @@ func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http
return
}
// returns true if the specified error is a temporary network error or false if it's not.
// if the error doesn't implement the net.Error interface the return value is true.
func isTemporaryNetworkError(err error) bool {
if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) {
return true
}
return false
}
// returns true if slice ints contains the value n
func containsInt(ints []int, n int) bool {
for _, i := range ints {
if i == n {
return true
func responseHasStatusCode(resp *http.Response, codes ...int) bool {
if resp != nil {
for _, i := range codes {
if i == resp.StatusCode {
return true
}
}
}
return false
......
package autorest
// Copyright 2017 Microsoft Corporation
//
// 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.
import (
"fmt"
"net/http"
"strings"
)
// SASTokenAuthorizer implements an authorization for SAS Token Authentication
// this can be used for interaction with Blob Storage Endpoints
type SASTokenAuthorizer struct {
sasToken string
}
// NewSASTokenAuthorizer creates a SASTokenAuthorizer using the given credentials
func NewSASTokenAuthorizer(sasToken string) (*SASTokenAuthorizer, error) {
if strings.TrimSpace(sasToken) == "" {
return nil, fmt.Errorf("sasToken cannot be empty")
}
token := sasToken
if strings.HasPrefix(sasToken, "?") {
token = strings.TrimPrefix(sasToken, "?")
}
return &SASTokenAuthorizer{
sasToken: token,
}, nil
}
// WithAuthorization returns a PrepareDecorator that adds a shared access signature token to the
// URI's query parameters. This can be used for the Blob, Queue, and File Services.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature
func (sas *SASTokenAuthorizer) WithAuthorization() PrepareDecorator {
return func(p Preparer) Preparer {
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
r, err := p.Prepare(r)
if err != nil {
return r, err
}
if r.URL.RawQuery != "" {
r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, sas.sasToken)
} else {
r.URL.RawQuery = sas.sasToken
}
r.RequestURI = r.URL.String()
return Prepare(r)
})
}
}
package autorest
// Copyright 2017 Microsoft Corporation
//
// 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.
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"net/http"
"net/url"
"sort"
"strings"
"time"
)
// SharedKeyType defines the enumeration for the various shared key types.
// See https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key for details on the shared key types.
type SharedKeyType string
const (
// SharedKey is used to authorize against blobs, files and queues services.
SharedKey SharedKeyType = "sharedKey"
// SharedKeyForTable is used to authorize against the table service.
SharedKeyForTable SharedKeyType = "sharedKeyTable"
// SharedKeyLite is used to authorize against blobs, files and queues services. It's provided for
// backwards compatibility with API versions before 2009-09-19. Prefer SharedKey instead.
SharedKeyLite SharedKeyType = "sharedKeyLite"
// SharedKeyLiteForTable is used to authorize against the table service. It's provided for
// backwards compatibility with older table API versions. Prefer SharedKeyForTable instead.
SharedKeyLiteForTable SharedKeyType = "sharedKeyLiteTable"
)
const (
headerAccept = "Accept"
headerAcceptCharset = "Accept-Charset"
headerContentEncoding = "Content-Encoding"
headerContentLength = "Content-Length"
headerContentMD5 = "Content-MD5"
headerContentLanguage = "Content-Language"
headerIfModifiedSince = "If-Modified-Since"
headerIfMatch = "If-Match"
headerIfNoneMatch = "If-None-Match"
headerIfUnmodifiedSince = "If-Unmodified-Since"
headerDate = "Date"
headerXMSDate = "X-Ms-Date"
headerXMSVersion = "x-ms-version"
headerRange = "Range"
)
const storageEmulatorAccountName = "devstoreaccount1"
// SharedKeyAuthorizer implements an authorization for Shared Key
// this can be used for interaction with Blob, File and Queue Storage Endpoints
type SharedKeyAuthorizer struct {
accountName string
accountKey []byte
keyType SharedKeyType
}
// NewSharedKeyAuthorizer creates a SharedKeyAuthorizer using the provided credentials and shared key type.
func NewSharedKeyAuthorizer(accountName, accountKey string, keyType SharedKeyType) (*SharedKeyAuthorizer, error) {
key, err := base64.StdEncoding.DecodeString(accountKey)
if err != nil {
return nil, fmt.Errorf("malformed storage account key: %v", err)
}
return &SharedKeyAuthorizer{
accountName: accountName,
accountKey: key,
keyType: keyType,
}, nil
}
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
// value is "<SharedKeyType> " followed by the computed key.
// This can be used for the Blob, Queue, and File Services
//
// from: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key
// You may use Shared Key authorization to authorize a request made against the
// 2009-09-19 version and later of the Blob and Queue services,
// and version 2014-02-14 and later of the File services.
func (sk *SharedKeyAuthorizer) WithAuthorization() PrepareDecorator {
return func(p Preparer) Preparer {
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
r, err := p.Prepare(r)
if err != nil {
return r, err
}
sk, err := buildSharedKey(sk.accountName, sk.accountKey, r, sk.keyType)
return Prepare(r, WithHeader(headerAuthorization, sk))
})
}
}
func buildSharedKey(accName string, accKey []byte, req *http.Request, keyType SharedKeyType) (string, error) {
canRes, err := buildCanonicalizedResource(accName, req.URL.String(), keyType)
if err != nil {
return "", err
}
if req.Header == nil {
req.Header = http.Header{}
}
// ensure date is set
if req.Header.Get(headerDate) == "" && req.Header.Get(headerXMSDate) == "" {
date := time.Now().UTC().Format(http.TimeFormat)
req.Header.Set(headerXMSDate, date)
}
canString, err := buildCanonicalizedString(req.Method, req.Header, canRes, keyType)
if err != nil {
return "", err
}
return createAuthorizationHeader(accName, accKey, canString, keyType), nil
}
func buildCanonicalizedResource(accountName, uri string, keyType SharedKeyType) (string, error) {
errMsg := "buildCanonicalizedResource error: %s"
u, err := url.Parse(uri)
if err != nil {
return "", fmt.Errorf(errMsg, err.Error())
}
cr := bytes.NewBufferString("")
if accountName != storageEmulatorAccountName {
cr.WriteString("/")
cr.WriteString(getCanonicalizedAccountName(accountName))
}
if len(u.Path) > 0 {
// Any portion of the CanonicalizedResource string that is derived from
// the resource's URI should be encoded exactly as it is in the URI.
// -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx
cr.WriteString(u.EscapedPath())
}
params, err := url.ParseQuery(u.RawQuery)
if err != nil {
return "", fmt.Errorf(errMsg, err.Error())
}
// See https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/AuthenticationUtility.cs#L277
if keyType == SharedKey {
if len(params) > 0 {
cr.WriteString("\n")
keys := []string{}
for key := range params {
keys = append(keys, key)
}
sort.Strings(keys)
completeParams := []string{}
for _, key := range keys {
if len(params[key]) > 1 {
sort.Strings(params[key])
}
completeParams = append(completeParams, fmt.Sprintf("%s:%s", key, strings.Join(params[key], ",")))
}
cr.WriteString(strings.Join(completeParams, "\n"))
}
} else {
// search for "comp" parameter, if exists then add it to canonicalizedresource
if v, ok := params["comp"]; ok {
cr.WriteString("?comp=" + v[0])
}
}
return string(cr.Bytes()), nil
}
func getCanonicalizedAccountName(accountName string) string {
// since we may be trying to access a secondary storage account, we need to
// remove the -secondary part of the storage name
return strings.TrimSuffix(accountName, "-secondary")
}
func buildCanonicalizedString(verb string, headers http.Header, canonicalizedResource string, keyType SharedKeyType) (string, error) {
contentLength := headers.Get(headerContentLength)
if contentLength == "0" {
contentLength = ""
}
date := headers.Get(headerDate)
if v := headers.Get(headerXMSDate); v != "" {
if keyType == SharedKey || keyType == SharedKeyLite {
date = ""
} else {
date = v
}
}
var canString string
switch keyType {
case SharedKey:
canString = strings.Join([]string{
verb,
headers.Get(headerContentEncoding),
headers.Get(headerContentLanguage),
contentLength,
headers.Get(headerContentMD5),
headers.Get(headerContentType),
date,
headers.Get(headerIfModifiedSince),
headers.Get(headerIfMatch),
headers.Get(headerIfNoneMatch),
headers.Get(headerIfUnmodifiedSince),
headers.Get(headerRange),
buildCanonicalizedHeader(headers),
canonicalizedResource,
}, "\n")
case SharedKeyForTable:
canString = strings.Join([]string{
verb,
headers.Get(headerContentMD5),
headers.Get(headerContentType),
date,
canonicalizedResource,
}, "\n")
case SharedKeyLite:
canString = strings.Join([]string{
verb,
headers.Get(headerContentMD5),
headers.Get(headerContentType),
date,
buildCanonicalizedHeader(headers),
canonicalizedResource,
}, "\n")
case SharedKeyLiteForTable:
canString = strings.Join([]string{
date,
canonicalizedResource,
}, "\n")
default:
return "", fmt.Errorf("key type '%s' is not supported", keyType)
}
return canString, nil
}
func buildCanonicalizedHeader(headers http.Header) string {
cm := make(map[string]string)
for k := range headers {
headerName := strings.TrimSpace(strings.ToLower(k))
if strings.HasPrefix(headerName, "x-ms-") {
cm[headerName] = headers.Get(k)
}
}
if len(cm) == 0 {
return ""
}
keys := []string{}
for key := range cm {
keys = append(keys, key)
}
sort.Strings(keys)
ch := bytes.NewBufferString("")
for _, key := range keys {
ch.WriteString(key)
ch.WriteRune(':')
ch.WriteString(cm[key])
ch.WriteRune('\n')
}
return strings.TrimSuffix(string(ch.Bytes()), "\n")
}
func createAuthorizationHeader(accountName string, accountKey []byte, canonicalizedString string, keyType SharedKeyType) string {
h := hmac.New(sha256.New, accountKey)
h.Write([]byte(canonicalizedString))
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
var key string
switch keyType {
case SharedKey, SharedKeyForTable:
key = "SharedKey"
case SharedKeyLite, SharedKeyLiteForTable:
key = "SharedKeyLite"
}
return fmt.Sprintf("%s %s:%s", key, getCanonicalizedAccountName(accountName), signature)
}
......@@ -17,6 +17,7 @@ package azure
// limitations under the License.
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
......@@ -143,7 +144,7 @@ type RequestError struct {
autorest.DetailedError
// The error returned by the Azure service.
ServiceError *ServiceError `json:"error"`
ServiceError *ServiceError `json:"error" xml:"Error"`
// The request id (from the x-ms-request-id-header) of the request.
RequestID string
......@@ -285,26 +286,34 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
var e RequestError
defer resp.Body.Close()
encodedAs := autorest.EncodedAsJSON
if strings.Contains(resp.Header.Get("Content-Type"), "xml") {
encodedAs = autorest.EncodedAsXML
}
// Copy and replace the Body in case it does not contain an error object.
// This will leave the Body available to the caller.
b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &e)
b, decodeErr := autorest.CopyAndDecode(encodedAs, resp.Body, &e)
resp.Body = ioutil.NopCloser(&b)
if decodeErr != nil {
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
}
if e.ServiceError == nil {
// Check if error is unwrapped ServiceError
if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil {
decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes()))
if err := decoder.Decode(&e.ServiceError); err != nil {
return err
}
}
if e.ServiceError.Message == "" {
// if we're here it means the returned error wasn't OData v4 compliant.
// try to unmarshal the body as raw JSON in hopes of getting something.
// try to unmarshal the body in hopes of getting something.
rawBody := map[string]interface{}{}
if err := json.Unmarshal(b.Bytes(), &rawBody); err != nil {
decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes()))
if err := decoder.Decode(&rawBody); err != nil {
return err
}
e.ServiceError = &ServiceError{
Code: "Unknown",
Message: "Unknown service error",
......
......@@ -47,11 +47,15 @@ func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration {
return resp, err
}
var re RequestError
err = autorest.Respond(
resp,
autorest.ByUnmarshallingJSON(&re),
)
if strings.Contains(r.Header.Get("Content-Type"), "xml") {
// XML errors (e.g. Storage Data Plane) only return the inner object
err = autorest.Respond(resp, autorest.ByUnmarshallingXML(&re.ServiceError))
} else {
err = autorest.Respond(resp, autorest.ByUnmarshallingJSON(&re))
}
if err != nil {
return resp, err
}
......
module github.com/Azure/go-autorest/autorest/date
go 1.12
require github.com/Azure/go-autorest/autorest v0.9.0
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
// +build modhack
package date
// Copyright 2017 Microsoft Corporation
//
// 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.
// This file, and the github.com/Azure/go-autorest/autorest import, won't actually become part of
// the resultant binary.
// Necessary for safely adding multi-module repo.
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
import _ "github.com/Azure/go-autorest/autorest"
module github.com/Azure/go-autorest/autorest
go 1.12
require (
github.com/Azure/go-autorest/autorest/adal v0.8.0
github.com/Azure/go-autorest/autorest/mocks v0.3.0
github.com/Azure/go-autorest/logger v0.1.0
github.com/Azure/go-autorest/tracing v0.5.0
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
)
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.8.0 h1:CxTzQrySOxDnKpLjFJeZAS5Qrv/qFPkgLjx5bOAi//I=
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
......@@ -523,7 +523,7 @@ func parseURL(u *url.URL, path string) (*url.URL, error) {
// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters
// given in the supplied map (i.e., key=value).
func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator {
parameters := ensureValueStrings(queryParameters)
parameters := MapToValues(queryParameters)
return func(p Preparer) Preparer {
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
r, err := p.Prepare(r)
......@@ -531,14 +531,16 @@ func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorato
if r.URL == nil {
return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
}
v := r.URL.Query()
for key, value := range parameters {
d, err := url.QueryUnescape(value)
if err != nil {
return r, err
for i := range value {
d, err := url.QueryUnescape(value[i])
if err != nil {
return r, err
}
value[i] = d
}
v.Add(key, d)
v[key] = value
}
r.URL.RawQuery = v.Encode()
}
......
......@@ -289,10 +289,6 @@ func doRetryForStatusCodesImpl(s Sender, r *http.Request, count429 bool, attempt
return
}
resp, err = s.Do(rr.Request())
// if the error isn't temporary don't bother retrying
if err != nil && !IsTemporaryNetworkError(err) {
return
}
// we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication
// resp and err will both have a value, so in this case we don't want to retry as it will never succeed.
if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) {
......
......@@ -19,7 +19,7 @@ import (
"runtime"
)
const number = "v13.0.0"
const number = "v13.3.0"
var (
userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
......
module github.com/Azure/go-autorest/logger
go 1.12
module github.com/Azure/go-autorest/tracing
go 1.12
......@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2019 Alibaba Cloud
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
......
......@@ -40,7 +40,8 @@ func NewProfileProvider(name ...string) Provider {
func (p *ProfileProvider) Resolve() (auth.Credential, error) {
path, ok := os.LookupEnv(ENVCredentialFile)
if !ok {
path, err := checkDefaultPath()
var err error
path, err = checkDefaultPath()
if err != nil {
return nil, err
}
......
......@@ -77,7 +77,9 @@ func completeROASignParams(request requests.AcsRequest, signer Signer, regionId
if request.GetFormParams() != nil && len(request.GetFormParams()) > 0 {
formString := utils.GetUrlFormedMap(request.GetFormParams())
request.SetContent([]byte(formString))
headerParams["Content-Type"] = requests.Form
if headerParams["Content-Type"] == "" {
headerParams["Content-Type"] = requests.Form
}
}
contentMD5 := utils.GetMD5Base64(request.GetContent())
headerParams["Content-MD5"] = contentMD5
......
......@@ -73,6 +73,7 @@ type Client struct {
EndpointMap map[string]string
EndpointType string
Network string
Domain string
debug bool
isRunning bool
......@@ -337,6 +338,15 @@ func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer
// resolve endpoint
endpoint := request.GetDomain()
if endpoint == "" && client.Domain != "" {
endpoint = client.Domain
}
if endpoint == "" {
endpoint = endpoints.GetEndpointFromMap(regionId, request.GetProduct())
}
if endpoint == "" && client.EndpointType != "" && request.GetProduct() != "Sts" {
if client.EndpointMap != nil && client.Network == "" || client.Network == "public" {
endpoint = client.EndpointMap[regionId]
......@@ -583,6 +593,10 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
return
}
}
if isCertificateError(err) {
return
}
// if status code >= 500 or timeout, will trigger retry
if client.config.AutoRetry && (err != nil || isServerError(httpResponse)) {
client.setTimeout(request)
......@@ -609,6 +623,13 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
return
}
func isCertificateError(err error) bool {
if err != nil && strings.Contains(err.Error(), "x509: certificate signed by unknown authority") {
return true
}
return false
}
func putMsgToMap(fieldMap map[string]string, request *http.Request) {
fieldMap["{host}"] = request.Host
fieldMap["{method}"] = request.Method
......
......@@ -17,32 +17,33 @@ package endpoints
import (
"fmt"
"strings"
"sync"
)
const keyFormatter = "%s::%s"
var endpointMapping = make(map[string]string)
type EndpointMapping struct {
sync.RWMutex
endpoint map[string]string
}
var endpointMapping = EndpointMapping{endpoint: make(map[string]string)}
// AddEndpointMapping Use product id and region id as key to store the endpoint into inner map
// AddEndpointMapping use productId and regionId as key to store the endpoint into inner map
// when using the same productId and regionId as key, the endpoint will be covered.
func AddEndpointMapping(regionId, productId, endpoint string) (err error) {
key := fmt.Sprintf(keyFormatter, strings.ToLower(regionId), strings.ToLower(productId))
endpointMapping[key] = endpoint
endpointMapping.Lock()
endpointMapping.endpoint[key] = endpoint
endpointMapping.Unlock()
return nil
}
// MappingResolver the mapping resolver type
type MappingResolver struct {
}
// GetName get the resolver name: "mapping resolver"
func (resolver *MappingResolver) GetName() (name string) {
name = "mapping resolver"
return
}
// TryResolve use Product and RegionId as key to find endpoint from inner map
func (resolver *MappingResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
key := fmt.Sprintf(keyFormatter, strings.ToLower(param.RegionId), strings.ToLower(param.Product))
endpoint, contains := endpointMapping[key]
return endpoint, contains, nil
// GetEndpointFromMap use Product and RegionId as key to find endpoint from inner map
func GetEndpointFromMap(regionId, productId string) string {
key := fmt.Sprintf(keyFormatter, strings.ToLower(regionId), strings.ToLower(productId))
endpointMapping.RLock()
endpoint := endpointMapping.endpoint[key]
endpointMapping.RUnlock()
return endpoint
}
......@@ -70,8 +70,6 @@ func Resolve(param *ResolveParam) (endpoint string, err error) {
func getAllResolvers() []Resolver {
once.Do(func() {
resolvers = []Resolver{
&SimpleHostResolver{},
&MappingResolver{},
&LocationResolver{},
&LocalRegionalResolver{},
&LocalGlobalResolver{},
......
/*
* 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.
*/
package endpoints
// SimpleHostResolver the simple host resolver type
type SimpleHostResolver struct {
}
// GetName get the resolver name: "simple host resolver"
func (resolver *SimpleHostResolver) GetName() (name string) {
name = "simple host resolver"
return
}
// TryResolve if the Domain exist in param, use it as endpoint
func (resolver *SimpleHostResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
if support = len(param.Domain) > 0; support {
endpoint = param.Domain
}
return
}
......@@ -332,57 +332,86 @@ func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, pre
}
} else if typeTag == "Repeated" {
// repeated param
repeatedFieldValue := dataValue.Field(i)
if repeatedFieldValue.Kind() != reflect.Slice {
// possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition
repeatedFieldValue = repeatedFieldValue.Elem()
err = handleRepeatedParams(request, dataValue, prefix, name, fieldPosition, i)
if err != nil {
return
}
if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
for m := 0; m < repeatedFieldValue.Len(); m++ {
elementValue := repeatedFieldValue.Index(m)
key := prefix + name + "." + strconv.Itoa(m+1)
if elementValue.Type().Kind().String() == "string" {
value := elementValue.String()
err = addParam(request, fieldPosition, key, value)
if err != nil {
return
}
} else {
err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
if err != nil {
return
}
}
} else if typeTag == "Struct" {
err = handleStruct(request, dataValue, prefix, name, fieldPosition, i)
if err != nil {
return
}
}
}
}
return
}
func handleRepeatedParams(request AcsRequest, dataValue reflect.Value, prefix, name, fieldPosition string, index int) (err error) {
repeatedFieldValue := dataValue.Field(index)
if repeatedFieldValue.Kind() != reflect.Slice {
// possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition
repeatedFieldValue = repeatedFieldValue.Elem()
}
if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
for m := 0; m < repeatedFieldValue.Len(); m++ {
elementValue := repeatedFieldValue.Index(m)
key := prefix + name + "." + strconv.Itoa(m+1)
if elementValue.Type().Kind().String() == "string" {
value := elementValue.String()
err = addParam(request, fieldPosition, key, value)
if err != nil {
return
}
} else {
err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
if err != nil {
return
}
}
}
}
return nil
}
func handleStruct(request AcsRequest, dataValue reflect.Value, prefix, name, fieldPosition string, index int) (err error) {
valueField := dataValue.Field(index)
if valueField.IsValid() && valueField.String() != "" {
valueFieldType := valueField.Type()
for m := 0; m < valueFieldType.NumField(); m++ {
fieldName := valueFieldType.Field(m).Name
elementValue := valueField.FieldByName(fieldName)
key := prefix + name + "." + fieldName
if elementValue.Type().String() == "[]string" {
if elementValue.IsNil() {
continue
}
for j := 0; j < elementValue.Len(); j++ {
err = addParam(request, fieldPosition, key+"."+strconv.Itoa(j+1), elementValue.Index(j).String())
if err != nil {
return
}
}
} else if typeTag == "Struct" {
valueField := dataValue.Field(i)
if valueField.Kind() == reflect.Struct {
if valueField.IsValid() && valueField.String() != "" {
valueFieldType := valueField.Type()
for m := 0; m < valueFieldType.NumField(); m++ {
fieldName := valueFieldType.Field(m).Name
elementValue := valueField.FieldByName(fieldName)
key := prefix + name + "." + fieldName
if elementValue.Type().String() == "[]string" {
for j := 0; j < elementValue.Len(); j++ {
err = addParam(request, fieldPosition, key+"."+strconv.Itoa(j+1), elementValue.Index(j).String())
if err != nil {
return
}
}
} else {
// value := elementValue.String()
// err = addParam(request, fieldPosition, key, value)
// if err != nil {
// return
// }
// } else {
// err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
// if err != nil {
// return
// }
// }
} else {
if elementValue.Type().Kind().String() == "string" {
value := elementValue.String()
err = addParam(request, fieldPosition, key, value)
if err != nil {
return
}
} else if elementValue.Type().Kind().String() == "struct" {
err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
if err != nil {
return
}
} else if !elementValue.IsNil() {
repeatedFieldValue := elementValue.Elem()
if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
for m := 0; m < repeatedFieldValue.Len(); m++ {
elementValue := repeatedFieldValue.Index(m)
err = flatRepeatedList(elementValue, request, fieldPosition, key+"."+strconv.Itoa(m+1)+".")
if err != nil {
return
}
}
}
......@@ -390,7 +419,7 @@ func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, pre
}
}
}
return
return nil
}
func addParam(request AcsRequest, position, name, value string) (err error) {
......
......@@ -77,9 +77,9 @@ func (client *Client) AddBandwidthPackageIpsWithCallback(request *AddBandwidthPa
type AddBandwidthPackageIpsRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ClientToken string `position:"Query" name:"ClientToken"`
BandwidthPackageId string `position:"Query" name:"BandwidthPackageId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
IpCount string `position:"Query" name:"IpCount"`
......
......@@ -77,9 +77,9 @@ func (client *Client) AddTagsWithCallback(request *AddTagsRequest, callback func
type AddTagsRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
Tag *[]AddTagsTag `position:"Query" name:"Tag" type:"Repeated"`
ResourceId string `position:"Query" name:"ResourceId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
Tag *[]AddTagsTag `position:"Query" name:"Tag" type:"Repeated"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
ResourceType string `position:"Query" name:"ResourceType"`
}
......
......@@ -76,15 +76,15 @@ func (client *Client) AllocateEipAddressWithCallback(request *AllocateEipAddress
// AllocateEipAddressRequest is the request struct for api AllocateEipAddress
type AllocateEipAddressRequest struct {
*requests.RpcRequest
ActivityId requests.Integer `position:"Query" name:"ActivityId"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
Bandwidth string `position:"Query" name:"Bandwidth"`
ClientToken string `position:"Query" name:"ClientToken"`
InternetChargeType string `position:"Query" name:"InternetChargeType"`
ISP string `position:"Query" name:"ISP"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
Bandwidth string `position:"Query" name:"Bandwidth"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
ActivityId requests.Integer `position:"Query" name:"ActivityId"`
InternetChargeType string `position:"Query" name:"InternetChargeType"`
}
// AllocateEipAddressResponse is the response struct for api AllocateEipAddress
......
......@@ -78,11 +78,11 @@ type AllocatePublicIpAddressRequest struct {
*requests.RpcRequest
IpAddress string `position:"Query" name:"IpAddress"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
VlanId string `position:"Query" name:"VlanId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
}
// AllocatePublicIpAddressResponse is the response struct for api AllocatePublicIpAddress
......
......@@ -77,9 +77,9 @@ func (client *Client) ApplyAutoSnapshotPolicyWithCallback(request *ApplyAutoSnap
type ApplyAutoSnapshotPolicyRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
AutoSnapshotPolicyId string `position:"Query" name:"autoSnapshotPolicyId"`
DiskIds string `position:"Query" name:"diskIds"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -77,12 +77,12 @@ func (client *Client) AssociateEipAddressWithCallback(request *AssociateEipAddre
type AssociateEipAddressRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
AllocationId string `position:"Query" name:"AllocationId"`
InstanceType string `position:"Query" name:"InstanceType"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
InstanceType string `position:"Query" name:"InstanceType"`
AllocationId string `position:"Query" name:"AllocationId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
}
// AssociateEipAddressResponse is the response struct for api AssociateEipAddress
......
......@@ -76,13 +76,13 @@ func (client *Client) AssociateHaVipWithCallback(request *AssociateHaVipRequest,
// AssociateHaVipRequest is the request struct for api AssociateHaVip
type AssociateHaVipRequest struct {
*requests.RpcRequest
HaVipId string `position:"Query" name:"HaVipId"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
HaVipId string `position:"Query" name:"HaVipId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
}
// AssociateHaVipResponse is the response struct for api AssociateHaVip
......
......@@ -77,10 +77,10 @@ func (client *Client) AttachClassicLinkVpcWithCallback(request *AttachClassicLin
type AttachClassicLinkVpcRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
VpcId string `position:"Query" name:"VpcId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
VpcId string `position:"Query" name:"VpcId"`
}
// AttachClassicLinkVpcResponse is the response struct for api AttachClassicLinkVpc
......
......@@ -77,13 +77,16 @@ func (client *Client) AttachDiskWithCallback(request *AttachDiskRequest, callbac
type AttachDiskRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
KeyPairName string `position:"Query" name:"KeyPairName"`
Bootable requests.Boolean `position:"Query" name:"Bootable"`
Password string `position:"Query" name:"Password"`
DiskId string `position:"Query" name:"DiskId"`
DeleteWithInstance requests.Boolean `position:"Query" name:"DeleteWithInstance"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
DiskId string `position:"Query" name:"DiskId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
Device string `position:"Query" name:"Device"`
DeleteWithInstance requests.Boolean `position:"Query" name:"DeleteWithInstance"`
}
// AttachDiskResponse is the response struct for api AttachDisk
......
......@@ -78,9 +78,9 @@ type AttachInstanceRamRoleRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
InstanceIds string `position:"Query" name:"InstanceIds"`
RamRoleName string `position:"Query" name:"RamRoleName"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceIds string `position:"Query" name:"InstanceIds"`
}
// AttachInstanceRamRoleResponse is the response struct for api AttachInstanceRamRole
......
......@@ -77,10 +77,10 @@ func (client *Client) AttachKeyPairWithCallback(request *AttachKeyPairRequest, c
type AttachKeyPairRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
InstanceIds string `position:"Query" name:"InstanceIds"`
KeyPairName string `position:"Query" name:"KeyPairName"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceIds string `position:"Query" name:"InstanceIds"`
}
// AttachKeyPairResponse is the response struct for api AttachKeyPair
......
......@@ -77,8 +77,8 @@ func (client *Client) CancelAutoSnapshotPolicyWithCallback(request *CancelAutoSn
type CancelAutoSnapshotPolicyRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
DiskIds string `position:"Query" name:"diskIds"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -77,12 +77,12 @@ func (client *Client) CancelPhysicalConnectionWithCallback(request *CancelPhysic
type CancelPhysicalConnectionRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
PhysicalConnectionId string `position:"Query" name:"PhysicalConnectionId"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
UserCidr string `position:"Query" name:"UserCidr"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
PhysicalConnectionId string `position:"Query" name:"PhysicalConnectionId"`
}
// CancelPhysicalConnectionResponse is the response struct for api CancelPhysicalConnection
......
......@@ -77,9 +77,9 @@ func (client *Client) CancelTaskWithCallback(request *CancelTaskRequest, callbac
type CancelTaskRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
TaskId string `position:"Query" name:"TaskId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
TaskId string `position:"Query" name:"TaskId"`
}
// CancelTaskResponse is the response struct for api CancelTask
......
......@@ -78,13 +78,13 @@ type CopyImageRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ImageId string `position:"Query" name:"ImageId"`
DestinationRegionId string `position:"Query" name:"DestinationRegionId"`
Tag *[]CopyImageTag `position:"Query" name:"Tag" type:"Repeated"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
DestinationImageName string `position:"Query" name:"DestinationImageName"`
DestinationRegionId string `position:"Query" name:"DestinationRegionId"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
Encrypted requests.Boolean `position:"Query" name:"Encrypted"`
Tag *[]CopyImageTag `position:"Query" name:"Tag" type:"Repeated"`
KMSKeyId string `position:"Query" name:"KMSKeyId"`
DestinationDescription string `position:"Query" name:"DestinationDescription"`
}
......
......@@ -77,12 +77,12 @@ func (client *Client) CreateAutoSnapshotPolicyWithCallback(request *CreateAutoSn
type CreateAutoSnapshotPolicyRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
TimePoints string `position:"Query" name:"timePoints"`
RetentionDays requests.Integer `position:"Query" name:"retentionDays"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
RepeatWeekdays string `position:"Query" name:"repeatWeekdays"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
AutoSnapshotPolicyName string `position:"Query" name:"autoSnapshotPolicyName"`
RetentionDays requests.Integer `position:"Query" name:"retentionDays"`
}
// CreateAutoSnapshotPolicyResponse is the response struct for api CreateAutoSnapshotPolicy
......
......@@ -20,24 +20,24 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
)
// DescribeFleetInstances invokes the ecs.DescribeFleetInstances API synchronously
// api document: https://help.aliyun.com/api/ecs/describefleetinstances.html
func (client *Client) DescribeFleetInstances(request *DescribeFleetInstancesRequest) (response *DescribeFleetInstancesResponse, err error) {
response = CreateDescribeFleetInstancesResponse()
// CreateDemand invokes the ecs.CreateDemand API synchronously
// api document: https://help.aliyun.com/api/ecs/createdemand.html
func (client *Client) CreateDemand(request *CreateDemandRequest) (response *CreateDemandResponse, err error) {
response = CreateCreateDemandResponse()
err = client.DoAction(request, response)
return
}
// DescribeFleetInstancesWithChan invokes the ecs.DescribeFleetInstances API asynchronously
// api document: https://help.aliyun.com/api/ecs/describefleetinstances.html
// CreateDemandWithChan invokes the ecs.CreateDemand API asynchronously
// api document: https://help.aliyun.com/api/ecs/createdemand.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DescribeFleetInstancesWithChan(request *DescribeFleetInstancesRequest) (<-chan *DescribeFleetInstancesResponse, <-chan error) {
responseChan := make(chan *DescribeFleetInstancesResponse, 1)
func (client *Client) CreateDemandWithChan(request *CreateDemandRequest) (<-chan *CreateDemandResponse, <-chan error) {
responseChan := make(chan *CreateDemandResponse, 1)
errChan := make(chan error, 1)
err := client.AddAsyncTask(func() {
defer close(responseChan)
defer close(errChan)
response, err := client.DescribeFleetInstances(request)
response, err := client.CreateDemand(request)
if err != nil {
errChan <- err
} else {
......@@ -52,16 +52,16 @@ func (client *Client) DescribeFleetInstancesWithChan(request *DescribeFleetInsta
return responseChan, errChan
}
// DescribeFleetInstancesWithCallback invokes the ecs.DescribeFleetInstances API asynchronously
// api document: https://help.aliyun.com/api/ecs/describefleetinstances.html
// CreateDemandWithCallback invokes the ecs.CreateDemand API asynchronously
// api document: https://help.aliyun.com/api/ecs/createdemand.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DescribeFleetInstancesWithCallback(request *DescribeFleetInstancesRequest, callback func(response *DescribeFleetInstancesResponse, err error)) <-chan int {
func (client *Client) CreateDemandWithCallback(request *CreateDemandRequest, callback func(response *CreateDemandResponse, err error)) <-chan int {
result := make(chan int, 1)
err := client.AddAsyncTask(func() {
var response *DescribeFleetInstancesResponse
var response *CreateDemandResponse
var err error
defer close(result)
response, err = client.DescribeFleetInstances(request)
response, err = client.CreateDemand(request)
callback(response, err)
result <- 1
})
......@@ -73,40 +73,45 @@ func (client *Client) DescribeFleetInstancesWithCallback(request *DescribeFleetI
return result
}
// DescribeFleetInstancesRequest is the request struct for api DescribeFleetInstances
type DescribeFleetInstancesRequest struct {
// CreateDemandRequest is the request struct for api CreateDemand
type CreateDemandRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
PageNumber requests.Integer `position:"Query" name:"PageNumber"`
PageSize requests.Integer `position:"Query" name:"PageSize"`
ClientToken string `position:"Query" name:"ClientToken"`
StartTime string `position:"Query" name:"StartTime"`
DemandDescription string `position:"Query" name:"DemandDescription"`
InstanceType string `position:"Query" name:"InstanceType"`
InstanceChargeType string `position:"Query" name:"InstanceChargeType"`
DemandName string `position:"Query" name:"DemandName"`
Amount requests.Integer `position:"Query" name:"Amount"`
Period requests.Integer `position:"Query" name:"Period"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
EndTime string `position:"Query" name:"EndTime"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
FleetId string `position:"Query" name:"FleetId"`
PeriodUnit string `position:"Query" name:"PeriodUnit"`
ZoneId string `position:"Query" name:"ZoneId"`
}
// DescribeFleetInstancesResponse is the response struct for api DescribeFleetInstances
type DescribeFleetInstancesResponse struct {
// CreateDemandResponse is the response struct for api CreateDemand
type CreateDemandResponse struct {
*responses.BaseResponse
RequestId string `json:"RequestId" xml:"RequestId"`
TotalCount int `json:"TotalCount" xml:"TotalCount"`
PageNumber int `json:"PageNumber" xml:"PageNumber"`
PageSize int `json:"PageSize" xml:"PageSize"`
Instances InstancesInDescribeFleetInstances `json:"Instances" xml:"Instances"`
RequestId string `json:"RequestId" xml:"RequestId"`
DemandId string `json:"DemandId" xml:"DemandId"`
}
// CreateDescribeFleetInstancesRequest creates a request to invoke DescribeFleetInstances API
func CreateDescribeFleetInstancesRequest() (request *DescribeFleetInstancesRequest) {
request = &DescribeFleetInstancesRequest{
// CreateCreateDemandRequest creates a request to invoke CreateDemand API
func CreateCreateDemandRequest() (request *CreateDemandRequest) {
request = &CreateDemandRequest{
RpcRequest: &requests.RpcRequest{},
}
request.InitWithApiInfo("Ecs", "2014-05-26", "DescribeFleetInstances", "ecs", "openAPI")
request.InitWithApiInfo("Ecs", "2014-05-26", "CreateDemand", "ecs", "openAPI")
return
}
// CreateDescribeFleetInstancesResponse creates a response to parse from DescribeFleetInstances response
func CreateDescribeFleetInstancesResponse() (response *DescribeFleetInstancesResponse) {
response = &DescribeFleetInstancesResponse{
// CreateCreateDemandResponse creates a response to parse from CreateDemand response
func CreateCreateDemandResponse() (response *CreateDemandResponse) {
response = &CreateDemandResponse{
BaseResponse: &responses.BaseResponse{},
}
return
......
......@@ -77,10 +77,10 @@ func (client *Client) CreateDeploymentSetWithCallback(request *CreateDeploymentS
type CreateDeploymentSetRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
DeploymentSetName string `position:"Query" name:"DeploymentSetName"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
OnUnableToRedeployFailedInstance string `position:"Query" name:"OnUnableToRedeployFailedInstance"`
......
......@@ -78,25 +78,25 @@ type CreateDiskRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
SnapshotId string `position:"Query" name:"SnapshotId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
PerformanceLevel string `position:"Query" name:"PerformanceLevel"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
DiskName string `position:"Query" name:"DiskName"`
ResourceGroupId string `position:"Query" name:"ResourceGroupId"`
DiskCategory string `position:"Query" name:"DiskCategory"`
StorageSetPartitionNumber requests.Integer `position:"Query" name:"StorageSetPartitionNumber"`
Tag *[]CreateDiskTag `position:"Query" name:"Tag" type:"Repeated"`
Arn *[]CreateDiskArn `position:"Query" name:"Arn" type:"Repeated"`
AdvancedFeatures string `position:"Query" name:"AdvancedFeatures"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
PerformanceLevel string `position:"Query" name:"PerformanceLevel"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
StorageSetId string `position:"Query" name:"StorageSetId"`
Size requests.Integer `position:"Query" name:"Size"`
Encrypted requests.Boolean `position:"Query" name:"Encrypted"`
DiskCategory string `position:"Query" name:"DiskCategory"`
ZoneId string `position:"Query" name:"ZoneId"`
StorageSetPartitionNumber requests.Integer `position:"Query" name:"StorageSetPartitionNumber"`
Tag *[]CreateDiskTag `position:"Query" name:"Tag" type:"Repeated"`
Arn *[]CreateDiskArn `position:"Query" name:"Arn" type:"Repeated"`
KMSKeyId string `position:"Query" name:"KMSKeyId"`
AdvancedFeatures string `position:"Query" name:"AdvancedFeatures"`
}
// CreateDiskTag is a repeated param struct in CreateDiskRequest
......
package ecs
//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.
//
// Code generated by Alibaba Cloud SDK Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
)
// CreateFleet invokes the ecs.CreateFleet API synchronously
// api document: https://help.aliyun.com/api/ecs/createfleet.html
func (client *Client) CreateFleet(request *CreateFleetRequest) (response *CreateFleetResponse, err error) {
response = CreateCreateFleetResponse()
err = client.DoAction(request, response)
return
}
// CreateFleetWithChan invokes the ecs.CreateFleet API asynchronously
// api document: https://help.aliyun.com/api/ecs/createfleet.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) CreateFleetWithChan(request *CreateFleetRequest) (<-chan *CreateFleetResponse, <-chan error) {
responseChan := make(chan *CreateFleetResponse, 1)
errChan := make(chan error, 1)
err := client.AddAsyncTask(func() {
defer close(responseChan)
defer close(errChan)
response, err := client.CreateFleet(request)
if err != nil {
errChan <- err
} else {
responseChan <- response
}
})
if err != nil {
errChan <- err
close(responseChan)
close(errChan)
}
return responseChan, errChan
}
// CreateFleetWithCallback invokes the ecs.CreateFleet API asynchronously
// api document: https://help.aliyun.com/api/ecs/createfleet.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) CreateFleetWithCallback(request *CreateFleetRequest, callback func(response *CreateFleetResponse, err error)) <-chan int {
result := make(chan int, 1)
err := client.AddAsyncTask(func() {
var response *CreateFleetResponse
var err error
defer close(result)
response, err = client.CreateFleet(request)
callback(response, err)
result <- 1
})
if err != nil {
defer close(result)
callback(nil, err)
result <- 0
}
return result
}
// CreateFleetRequest is the request struct for api CreateFleet
type CreateFleetRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
FleetType string `position:"Query" name:"FleetType"`
Description string `position:"Query" name:"Description"`
TerminateInstancesWithExpiration requests.Boolean `position:"Query" name:"TerminateInstancesWithExpiration"`
OnDemandTargetCapacity string `position:"Query" name:"OnDemandTargetCapacity"`
FleetName string `position:"Query" name:"FleetName"`
SpotAllocationStrategy string `position:"Query" name:"SpotAllocationStrategy"`
TerminateInstances requests.Boolean `position:"Query" name:"TerminateInstances"`
DefaultTargetCapacityType string `position:"Query" name:"DefaultTargetCapacityType"`
ExcessCapacityTerminationPolicy string `position:"Query" name:"ExcessCapacityTerminationPolicy"`
LaunchTemplateConfig *[]CreateFleetLaunchTemplateConfig `position:"Query" name:"LaunchTemplateConfig" type:"Repeated"`
ValidUntil string `position:"Query" name:"ValidUntil"`
FillGapWithOnDemand string `position:"Query" name:"FillGapWithOnDemand"`
SpotInstanceInterruptionBehavior string `position:"Query" name:"SpotInstanceInterruptionBehavior"`
LaunchTemplateId string `position:"Query" name:"LaunchTemplateId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
SpotInstancePoolsToUseCount requests.Integer `position:"Query" name:"SpotInstancePoolsToUseCount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
LaunchTemplateVersion string `position:"Query" name:"LaunchTemplateVersion"`
TotalTargetCapacity string `position:"Query" name:"TotalTargetCapacity"`
OnDemandAllocationStrategy string `position:"Query" name:"OnDemandAllocationStrategy"`
SpotTargetCapacity string `position:"Query" name:"SpotTargetCapacity"`
ValidFrom string `position:"Query" name:"ValidFrom"`
MaxSpotPrice requests.Float `position:"Query" name:"MaxSpotPrice"`
}
// CreateFleetLaunchTemplateConfig is a repeated param struct in CreateFleetRequest
type CreateFleetLaunchTemplateConfig struct {
InstanceType string `name:"InstanceType"`
MaxPrice string `name:"MaxPrice"`
VSwitchId string `name:"VSwitchId"`
WeightedCapacity string `name:"WeightedCapacity"`
Priority string `name:"Priority"`
}
// CreateFleetResponse is the response struct for api CreateFleet
type CreateFleetResponse struct {
*responses.BaseResponse
RequestId string `json:"RequestId" xml:"RequestId"`
FleetId string `json:"FleetId" xml:"FleetId"`
}
// CreateCreateFleetRequest creates a request to invoke CreateFleet API
func CreateCreateFleetRequest() (request *CreateFleetRequest) {
request = &CreateFleetRequest{
RpcRequest: &requests.RpcRequest{},
}
request.InitWithApiInfo("Ecs", "2014-05-26", "CreateFleet", "ecs", "openAPI")
return
}
// CreateCreateFleetResponse creates a response to parse from CreateFleet response
func CreateCreateFleetResponse() (response *CreateFleetResponse) {
response = &CreateFleetResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}
......@@ -77,15 +77,15 @@ func (client *Client) CreateForwardEntryWithCallback(request *CreateForwardEntry
type CreateForwardEntryRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ForwardTableId string `position:"Query" name:"ForwardTableId"`
InternalIp string `position:"Query" name:"InternalIp"`
ExternalIp string `position:"Query" name:"ExternalIp"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
IpProtocol string `position:"Query" name:"IpProtocol"`
InternalPort string `position:"Query" name:"InternalPort"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
ForwardTableId string `position:"Query" name:"ForwardTableId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
ExternalIp string `position:"Query" name:"ExternalIp"`
InternalPort string `position:"Query" name:"InternalPort"`
ExternalPort string `position:"Query" name:"ExternalPort"`
InternalIp string `position:"Query" name:"InternalIp"`
}
// CreateForwardEntryResponse is the response struct for api CreateForwardEntry
......
......@@ -76,14 +76,14 @@ func (client *Client) CreateHaVipWithCallback(request *CreateHaVipRequest, callb
// CreateHaVipRequest is the request struct for api CreateHaVip
type CreateHaVipRequest struct {
*requests.RpcRequest
VSwitchId string `position:"Query" name:"VSwitchId"`
IpAddress string `position:"Query" name:"IpAddress"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
VSwitchId string `position:"Query" name:"VSwitchId"`
}
// CreateHaVipResponse is the response struct for api CreateHaVip
......
......@@ -79,18 +79,18 @@ type CreateImageRequest struct {
DiskDeviceMapping *[]CreateImageDiskDeviceMapping `position:"Query" name:"DiskDeviceMapping" type:"Repeated"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
SnapshotId string `position:"Query" name:"SnapshotId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
Platform string `position:"Query" name:"Platform"`
ResourceGroupId string `position:"Query" name:"ResourceGroupId"`
InstanceId string `position:"Query" name:"InstanceId"`
ImageName string `position:"Query" name:"ImageName"`
ImageVersion string `position:"Query" name:"ImageVersion"`
Tag *[]CreateImageTag `position:"Query" name:"Tag" type:"Repeated"`
Architecture string `position:"Query" name:"Architecture"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
ImageVersion string `position:"Query" name:"ImageVersion"`
}
// CreateImageDiskDeviceMapping is a repeated param struct in CreateImageRequest
......
......@@ -130,6 +130,7 @@ type CreateInstanceRequest struct {
DedicatedHostId string `position:"Query" name:"DedicatedHostId"`
ClusterId string `position:"Query" name:"ClusterId"`
CreditSpecification string `position:"Query" name:"CreditSpecification"`
SpotDuration requests.Integer `position:"Query" name:"SpotDuration"`
DataDisk *[]CreateInstanceDataDisk `position:"Query" name:"DataDisk" type:"Repeated"`
StorageSetId string `position:"Query" name:"StorageSetId"`
SystemDiskSize requests.Integer `position:"Query" name:"SystemDisk.Size"`
......
......@@ -76,11 +76,11 @@ func (client *Client) CreateKeyPairWithCallback(request *CreateKeyPairRequest, c
// CreateKeyPairRequest is the request struct for api CreateKeyPair
type CreateKeyPairRequest struct {
*requests.RpcRequest
ResourceGroupId string `position:"Query" name:"ResourceGroupId"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
KeyPairName string `position:"Query" name:"KeyPairName"`
ResourceGroupId string `position:"Query" name:"ResourceGroupId"`
Tag *[]CreateKeyPairTag `position:"Query" name:"Tag" type:"Repeated"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -20,24 +20,24 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
)
// DescribeInstancePhysicalAttribute invokes the ecs.DescribeInstancePhysicalAttribute API synchronously
// api document: https://help.aliyun.com/api/ecs/describeinstancephysicalattribute.html
func (client *Client) DescribeInstancePhysicalAttribute(request *DescribeInstancePhysicalAttributeRequest) (response *DescribeInstancePhysicalAttributeResponse, err error) {
response = CreateDescribeInstancePhysicalAttributeResponse()
// CreateMaintenanceProperty invokes the ecs.CreateMaintenanceProperty API synchronously
// api document: https://help.aliyun.com/api/ecs/createmaintenanceproperty.html
func (client *Client) CreateMaintenanceProperty(request *CreateMaintenancePropertyRequest) (response *CreateMaintenancePropertyResponse, err error) {
response = CreateCreateMaintenancePropertyResponse()
err = client.DoAction(request, response)
return
}
// DescribeInstancePhysicalAttributeWithChan invokes the ecs.DescribeInstancePhysicalAttribute API asynchronously
// api document: https://help.aliyun.com/api/ecs/describeinstancephysicalattribute.html
// CreateMaintenancePropertyWithChan invokes the ecs.CreateMaintenanceProperty API asynchronously
// api document: https://help.aliyun.com/api/ecs/createmaintenanceproperty.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DescribeInstancePhysicalAttributeWithChan(request *DescribeInstancePhysicalAttributeRequest) (<-chan *DescribeInstancePhysicalAttributeResponse, <-chan error) {
responseChan := make(chan *DescribeInstancePhysicalAttributeResponse, 1)
func (client *Client) CreateMaintenancePropertyWithChan(request *CreateMaintenancePropertyRequest) (<-chan *CreateMaintenancePropertyResponse, <-chan error) {
responseChan := make(chan *CreateMaintenancePropertyResponse, 1)
errChan := make(chan error, 1)
err := client.AddAsyncTask(func() {
defer close(responseChan)
defer close(errChan)
response, err := client.DescribeInstancePhysicalAttribute(request)
response, err := client.CreateMaintenanceProperty(request)
if err != nil {
errChan <- err
} else {
......@@ -52,16 +52,16 @@ func (client *Client) DescribeInstancePhysicalAttributeWithChan(request *Describ
return responseChan, errChan
}
// DescribeInstancePhysicalAttributeWithCallback invokes the ecs.DescribeInstancePhysicalAttribute API asynchronously
// api document: https://help.aliyun.com/api/ecs/describeinstancephysicalattribute.html
// CreateMaintenancePropertyWithCallback invokes the ecs.CreateMaintenanceProperty API asynchronously
// api document: https://help.aliyun.com/api/ecs/createmaintenanceproperty.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DescribeInstancePhysicalAttributeWithCallback(request *DescribeInstancePhysicalAttributeRequest, callback func(response *DescribeInstancePhysicalAttributeResponse, err error)) <-chan int {
func (client *Client) CreateMaintenancePropertyWithCallback(request *CreateMaintenancePropertyRequest, callback func(response *CreateMaintenancePropertyResponse, err error)) <-chan int {
result := make(chan int, 1)
err := client.AddAsyncTask(func() {
var response *DescribeInstancePhysicalAttributeResponse
var response *CreateMaintenancePropertyResponse
var err error
defer close(result)
response, err = client.DescribeInstancePhysicalAttribute(request)
response, err = client.CreateMaintenanceProperty(request)
callback(response, err)
result <- 1
})
......@@ -73,38 +73,37 @@ func (client *Client) DescribeInstancePhysicalAttributeWithCallback(request *Des
return result
}
// DescribeInstancePhysicalAttributeRequest is the request struct for api DescribeInstancePhysicalAttribute
type DescribeInstancePhysicalAttributeRequest struct {
// CreateMaintenancePropertyRequest is the request struct for api CreateMaintenanceProperty
type CreateMaintenancePropertyRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
StartTime string `position:"Query" name:"StartTime"`
ActionOnMaintenance string `position:"Query" name:"ActionOnMaintenance"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
EndTime string `position:"Query" name:"EndTime"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId *[]string `position:"Query" name:"InstanceId" type:"Repeated"`
}
// DescribeInstancePhysicalAttributeResponse is the response struct for api DescribeInstancePhysicalAttribute
type DescribeInstancePhysicalAttributeResponse struct {
// CreateMaintenancePropertyResponse is the response struct for api CreateMaintenanceProperty
type CreateMaintenancePropertyResponse struct {
*responses.BaseResponse
RequestId string `json:"RequestId" xml:"RequestId"`
InstanceId string `json:"InstanceId" xml:"InstanceId"`
VlanId string `json:"VlanId" xml:"VlanId"`
NodeControllerId string `json:"NodeControllerId" xml:"NodeControllerId"`
RackId string `json:"RackId" xml:"RackId"`
RequestId string `json:"RequestId" xml:"RequestId"`
}
// CreateDescribeInstancePhysicalAttributeRequest creates a request to invoke DescribeInstancePhysicalAttribute API
func CreateDescribeInstancePhysicalAttributeRequest() (request *DescribeInstancePhysicalAttributeRequest) {
request = &DescribeInstancePhysicalAttributeRequest{
// CreateCreateMaintenancePropertyRequest creates a request to invoke CreateMaintenanceProperty API
func CreateCreateMaintenancePropertyRequest() (request *CreateMaintenancePropertyRequest) {
request = &CreateMaintenancePropertyRequest{
RpcRequest: &requests.RpcRequest{},
}
request.InitWithApiInfo("Ecs", "2014-05-26", "DescribeInstancePhysicalAttribute", "ecs", "openAPI")
request.InitWithApiInfo("Ecs", "2014-05-26", "CreateMaintenanceProperty", "ecs", "openAPI")
return
}
// CreateDescribeInstancePhysicalAttributeResponse creates a response to parse from DescribeInstancePhysicalAttribute response
func CreateDescribeInstancePhysicalAttributeResponse() (response *DescribeInstancePhysicalAttributeResponse) {
response = &DescribeInstancePhysicalAttributeResponse{
// CreateCreateMaintenancePropertyResponse creates a response to parse from CreateMaintenanceProperty response
func CreateCreateMaintenancePropertyResponse() (response *CreateMaintenancePropertyResponse) {
response = &CreateMaintenancePropertyResponse{
BaseResponse: &responses.BaseResponse{},
}
return
......
......@@ -77,14 +77,14 @@ func (client *Client) CreateNatGatewayWithCallback(request *CreateNatGatewayRequ
type CreateNatGatewayRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
Description string `position:"Query" name:"Description"`
BandwidthPackage *[]CreateNatGatewayBandwidthPackage `position:"Query" name:"BandwidthPackage" type:"Repeated"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
VpcId string `position:"Query" name:"VpcId"`
Name string `position:"Query" name:"Name"`
Description string `position:"Query" name:"Description"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
BandwidthPackage *[]CreateNatGatewayBandwidthPackage `position:"Query" name:"BandwidthPackage" type:"Repeated"`
}
// CreateNatGatewayBandwidthPackage is a repeated param struct in CreateNatGatewayRequest
......
......@@ -88,6 +88,7 @@ type CreateNetworkInterfaceRequest struct {
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
SecurityGroupIds *[]string `position:"Query" name:"SecurityGroupIds" type:"Repeated"`
VSwitchId string `position:"Query" name:"VSwitchId"`
PrimaryIpAddress string `position:"Query" name:"PrimaryIpAddress"`
}
......
......@@ -77,21 +77,21 @@ func (client *Client) CreatePhysicalConnectionWithCallback(request *CreatePhysic
type CreatePhysicalConnectionRequest struct {
*requests.RpcRequest
AccessPointId string `position:"Query" name:"AccessPointId"`
RedundantPhysicalConnectionId string `position:"Query" name:"RedundantPhysicalConnectionId"`
PeerLocation string `position:"Query" name:"PeerLocation"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
PortType string `position:"Query" name:"PortType"`
CircuitCode string `position:"Query" name:"CircuitCode"`
Bandwidth requests.Integer `position:"Query" name:"bandwidth"`
ClientToken string `position:"Query" name:"ClientToken"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
Type string `position:"Query" name:"Type"`
UserCidr string `position:"Query" name:"UserCidr"`
RedundantPhysicalConnectionId string `position:"Query" name:"RedundantPhysicalConnectionId"`
PeerLocation string `position:"Query" name:"PeerLocation"`
Bandwidth requests.Integer `position:"Query" name:"bandwidth"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
LineOperator string `position:"Query" name:"LineOperator"`
Name string `position:"Query" name:"Name"`
UserCidr string `position:"Query" name:"UserCidr"`
}
// CreatePhysicalConnectionResponse is the response struct for api CreatePhysicalConnection
......
......@@ -77,15 +77,15 @@ func (client *Client) CreateRouteEntryWithCallback(request *CreateRouteEntryRequ
type CreateRouteEntryRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
NextHopId string `position:"Query" name:"NextHopId"`
NextHopType string `position:"Query" name:"NextHopType"`
RouteTableId string `position:"Query" name:"RouteTableId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
DestinationCidrBlock string `position:"Query" name:"DestinationCidrBlock"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
NextHopId string `position:"Query" name:"NextHopId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
NextHopType string `position:"Query" name:"NextHopType"`
NextHopList *[]CreateRouteEntryNextHopList `position:"Query" name:"NextHopList" type:"Repeated"`
RouteTableId string `position:"Query" name:"RouteTableId"`
}
// CreateRouteEntryNextHopList is a repeated param struct in CreateRouteEntryRequest
......
......@@ -77,16 +77,16 @@ func (client *Client) CreateSecurityGroupWithCallback(request *CreateSecurityGro
type CreateSecurityGroupRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
SecurityGroupName string `position:"Query" name:"SecurityGroupName"`
SecurityGroupType string `position:"Query" name:"SecurityGroupType"`
ResourceGroupId string `position:"Query" name:"ResourceGroupId"`
VpcId string `position:"Query" name:"VpcId"`
Tag *[]CreateSecurityGroupTag `position:"Query" name:"Tag" type:"Repeated"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
SecurityGroupType string `position:"Query" name:"SecurityGroupType"`
VpcId string `position:"Query" name:"VpcId"`
}
// CreateSecurityGroupTag is a repeated param struct in CreateSecurityGroupRequest
......
......@@ -77,18 +77,15 @@ func (client *Client) CreateSnapshotWithCallback(request *CreateSnapshotRequest,
type CreateSnapshotRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
SnapshotName string `position:"Query" name:"SnapshotName"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
SourceSnapshotId string `position:"Query" name:"SourceSnapshotId"`
RemoveSourceSnapshot requests.Boolean `position:"Query" name:"RemoveSourceSnapshot"`
DiskId string `position:"Query" name:"DiskId"`
RetentionDays requests.Integer `position:"Query" name:"RetentionDays"`
Tag *[]CreateSnapshotTag `position:"Query" name:"Tag" type:"Repeated"`
Category string `position:"Query" name:"Category"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
RetentionDays requests.Integer `position:"Query" name:"RetentionDays"`
}
// CreateSnapshotTag is a repeated param struct in CreateSnapshotRequest
......
......@@ -77,15 +77,15 @@ func (client *Client) CreateVSwitchWithCallback(request *CreateVSwitchRequest, c
type CreateVSwitchRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
Description string `position:"Query" name:"Description"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
VpcId string `position:"Query" name:"VpcId"`
VSwitchName string `position:"Query" name:"VSwitchName"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
CidrBlock string `position:"Query" name:"CidrBlock"`
ZoneId string `position:"Query" name:"ZoneId"`
Description string `position:"Query" name:"Description"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
// CreateVSwitchResponse is the response struct for api CreateVSwitch
......
......@@ -80,16 +80,16 @@ type CreateVirtualBorderRouterRequest struct {
CircuitCode string `position:"Query" name:"CircuitCode"`
VlanId requests.Integer `position:"Query" name:"VlanId"`
ClientToken string `position:"Query" name:"ClientToken"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Description string `position:"Query" name:"Description"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
PeerGatewayIp string `position:"Query" name:"PeerGatewayIp"`
PeeringSubnetMask string `position:"Query" name:"PeeringSubnetMask"`
PhysicalConnectionId string `position:"Query" name:"PhysicalConnectionId"`
Name string `position:"Query" name:"Name"`
LocalGatewayIp string `position:"Query" name:"LocalGatewayIp"`
UserCidr string `position:"Query" name:"UserCidr"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
PhysicalConnectionId string `position:"Query" name:"PhysicalConnectionId"`
Name string `position:"Query" name:"Name"`
VbrOwnerId requests.Integer `position:"Query" name:"VbrOwnerId"`
}
......
......@@ -76,15 +76,15 @@ func (client *Client) CreateVpcWithCallback(request *CreateVpcRequest, callback
// CreateVpcRequest is the request struct for api CreateVpc
type CreateVpcRequest struct {
*requests.RpcRequest
VpcName string `position:"Query" name:"VpcName"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
CidrBlock string `position:"Query" name:"CidrBlock"`
Description string `position:"Query" name:"Description"`
VpcName string `position:"Query" name:"VpcName"`
UserCidr string `position:"Query" name:"UserCidr"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
CidrBlock string `position:"Query" name:"CidrBlock"`
}
// CreateVpcResponse is the response struct for api CreateVpc
......
......@@ -77,8 +77,8 @@ func (client *Client) DeleteAutoSnapshotPolicyWithCallback(request *DeleteAutoSn
type DeleteAutoSnapshotPolicyRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
AutoSnapshotPolicyId string `position:"Query" name:"autoSnapshotPolicyId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -20,24 +20,24 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
)
// DeleteFleet invokes the ecs.DeleteFleet API synchronously
// api document: https://help.aliyun.com/api/ecs/deletefleet.html
func (client *Client) DeleteFleet(request *DeleteFleetRequest) (response *DeleteFleetResponse, err error) {
response = CreateDeleteFleetResponse()
// DeleteDemand invokes the ecs.DeleteDemand API synchronously
// api document: https://help.aliyun.com/api/ecs/deletedemand.html
func (client *Client) DeleteDemand(request *DeleteDemandRequest) (response *DeleteDemandResponse, err error) {
response = CreateDeleteDemandResponse()
err = client.DoAction(request, response)
return
}
// DeleteFleetWithChan invokes the ecs.DeleteFleet API asynchronously
// api document: https://help.aliyun.com/api/ecs/deletefleet.html
// DeleteDemandWithChan invokes the ecs.DeleteDemand API asynchronously
// api document: https://help.aliyun.com/api/ecs/deletedemand.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DeleteFleetWithChan(request *DeleteFleetRequest) (<-chan *DeleteFleetResponse, <-chan error) {
responseChan := make(chan *DeleteFleetResponse, 1)
func (client *Client) DeleteDemandWithChan(request *DeleteDemandRequest) (<-chan *DeleteDemandResponse, <-chan error) {
responseChan := make(chan *DeleteDemandResponse, 1)
errChan := make(chan error, 1)
err := client.AddAsyncTask(func() {
defer close(responseChan)
defer close(errChan)
response, err := client.DeleteFleet(request)
response, err := client.DeleteDemand(request)
if err != nil {
errChan <- err
} else {
......@@ -52,16 +52,16 @@ func (client *Client) DeleteFleetWithChan(request *DeleteFleetRequest) (<-chan *
return responseChan, errChan
}
// DeleteFleetWithCallback invokes the ecs.DeleteFleet API asynchronously
// api document: https://help.aliyun.com/api/ecs/deletefleet.html
// DeleteDemandWithCallback invokes the ecs.DeleteDemand API asynchronously
// api document: https://help.aliyun.com/api/ecs/deletedemand.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DeleteFleetWithCallback(request *DeleteFleetRequest, callback func(response *DeleteFleetResponse, err error)) <-chan int {
func (client *Client) DeleteDemandWithCallback(request *DeleteDemandRequest, callback func(response *DeleteDemandResponse, err error)) <-chan int {
result := make(chan int, 1)
err := client.AddAsyncTask(func() {
var response *DeleteFleetResponse
var response *DeleteDemandResponse
var err error
defer close(result)
response, err = client.DeleteFleet(request)
response, err = client.DeleteDemand(request)
callback(response, err)
result <- 1
})
......@@ -73,35 +73,36 @@ func (client *Client) DeleteFleetWithCallback(request *DeleteFleetRequest, callb
return result
}
// DeleteFleetRequest is the request struct for api DeleteFleet
type DeleteFleetRequest struct {
// DeleteDemandRequest is the request struct for api DeleteDemand
type DeleteDemandRequest struct {
*requests.RpcRequest
Reason string `position:"Query" name:"Reason"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
TerminateInstances requests.Boolean `position:"Query" name:"TerminateInstances"`
ClientToken string `position:"Query" name:"ClientToken"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
FleetId string `position:"Query" name:"FleetId"`
DemandId string `position:"Query" name:"DemandId"`
}
// DeleteFleetResponse is the response struct for api DeleteFleet
type DeleteFleetResponse struct {
// DeleteDemandResponse is the response struct for api DeleteDemand
type DeleteDemandResponse struct {
*responses.BaseResponse
RequestId string `json:"RequestId" xml:"RequestId"`
}
// CreateDeleteFleetRequest creates a request to invoke DeleteFleet API
func CreateDeleteFleetRequest() (request *DeleteFleetRequest) {
request = &DeleteFleetRequest{
// CreateDeleteDemandRequest creates a request to invoke DeleteDemand API
func CreateDeleteDemandRequest() (request *DeleteDemandRequest) {
request = &DeleteDemandRequest{
RpcRequest: &requests.RpcRequest{},
}
request.InitWithApiInfo("Ecs", "2014-05-26", "DeleteFleet", "ecs", "openAPI")
request.InitWithApiInfo("Ecs", "2014-05-26", "DeleteDemand", "ecs", "openAPI")
return
}
// CreateDeleteFleetResponse creates a response to parse from DeleteFleet response
func CreateDeleteFleetResponse() (response *DeleteFleetResponse) {
response = &DeleteFleetResponse{
// CreateDeleteDemandResponse creates a response to parse from DeleteDemand response
func CreateDeleteDemandResponse() (response *DeleteDemandResponse) {
response = &DeleteDemandResponse{
BaseResponse: &responses.BaseResponse{},
}
return
......
......@@ -76,8 +76,8 @@ func (client *Client) DeleteDeploymentSetWithCallback(request *DeleteDeploymentS
// DeleteDeploymentSetRequest is the request struct for api DeleteDeploymentSet
type DeleteDeploymentSetRequest struct {
*requests.RpcRequest
DeploymentSetId string `position:"Query" name:"DeploymentSetId"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
DeploymentSetId string `position:"Query" name:"DeploymentSetId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
......
......@@ -77,9 +77,9 @@ func (client *Client) DeleteDiskWithCallback(request *DeleteDiskRequest, callbac
type DeleteDiskRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
DiskId string `position:"Query" name:"DiskId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
DiskId string `position:"Query" name:"DiskId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -77,10 +77,10 @@ func (client *Client) DeleteForwardEntryWithCallback(request *DeleteForwardEntry
type DeleteForwardEntryRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ForwardTableId string `position:"Query" name:"ForwardTableId"`
ForwardEntryId string `position:"Query" name:"ForwardEntryId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
ForwardTableId string `position:"Query" name:"ForwardTableId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -76,10 +76,10 @@ func (client *Client) DeleteHaVipWithCallback(request *DeleteHaVipRequest, callb
// DeleteHaVipRequest is the request struct for api DeleteHaVip
type DeleteHaVipRequest struct {
*requests.RpcRequest
HaVipId string `position:"Query" name:"HaVipId"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
HaVipId string `position:"Query" name:"HaVipId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -80,8 +80,8 @@ type DeleteImageRequest struct {
ImageId string `position:"Query" name:"ImageId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Force requests.Boolean `position:"Query" name:"Force"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
Force requests.Boolean `position:"Query" name:"Force"`
}
// DeleteImageResponse is the response struct for api DeleteImage
......
......@@ -77,12 +77,12 @@ func (client *Client) DeleteInstanceWithCallback(request *DeleteInstanceRequest,
type DeleteInstanceRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
TerminateSubscription requests.Boolean `position:"Query" name:"TerminateSubscription"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
TerminateSubscription requests.Boolean `position:"Query" name:"TerminateSubscription"`
Force requests.Boolean `position:"Query" name:"Force"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId string `position:"Query" name:"InstanceId"`
Force requests.Boolean `position:"Query" name:"Force"`
}
// DeleteInstanceResponse is the response struct for api DeleteInstance
......
......@@ -77,14 +77,14 @@ func (client *Client) DeleteInstancesWithCallback(request *DeleteInstancesReques
type DeleteInstancesRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
InstanceId *[]string `position:"Query" name:"InstanceId" type:"Repeated"`
ClientToken string `position:"Query" name:"ClientToken"`
TerminateSubscription requests.Boolean `position:"Query" name:"TerminateSubscription"`
DryRun requests.Boolean `position:"Query" name:"DryRun"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
TerminateSubscription requests.Boolean `position:"Query" name:"TerminateSubscription"`
Force requests.Boolean `position:"Query" name:"Force"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
InstanceId *[]string `position:"Query" name:"InstanceId" type:"Repeated"`
Force requests.Boolean `position:"Query" name:"Force"`
}
// DeleteInstancesResponse is the response struct for api DeleteInstances
......
......@@ -77,8 +77,8 @@ func (client *Client) DeleteKeyPairsWithCallback(request *DeleteKeyPairsRequest,
type DeleteKeyPairsRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
KeyPairNames string `position:"Query" name:"KeyPairNames"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -20,24 +20,24 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
)
// DescribeFleetHistory invokes the ecs.DescribeFleetHistory API synchronously
// api document: https://help.aliyun.com/api/ecs/describefleethistory.html
func (client *Client) DescribeFleetHistory(request *DescribeFleetHistoryRequest) (response *DescribeFleetHistoryResponse, err error) {
response = CreateDescribeFleetHistoryResponse()
// DeleteMaintenanceProperty invokes the ecs.DeleteMaintenanceProperty API synchronously
// api document: https://help.aliyun.com/api/ecs/deletemaintenanceproperty.html
func (client *Client) DeleteMaintenanceProperty(request *DeleteMaintenancePropertyRequest) (response *DeleteMaintenancePropertyResponse, err error) {
response = CreateDeleteMaintenancePropertyResponse()
err = client.DoAction(request, response)
return
}
// DescribeFleetHistoryWithChan invokes the ecs.DescribeFleetHistory API asynchronously
// api document: https://help.aliyun.com/api/ecs/describefleethistory.html
// DeleteMaintenancePropertyWithChan invokes the ecs.DeleteMaintenanceProperty API asynchronously
// api document: https://help.aliyun.com/api/ecs/deletemaintenanceproperty.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DescribeFleetHistoryWithChan(request *DescribeFleetHistoryRequest) (<-chan *DescribeFleetHistoryResponse, <-chan error) {
responseChan := make(chan *DescribeFleetHistoryResponse, 1)
func (client *Client) DeleteMaintenancePropertyWithChan(request *DeleteMaintenancePropertyRequest) (<-chan *DeleteMaintenancePropertyResponse, <-chan error) {
responseChan := make(chan *DeleteMaintenancePropertyResponse, 1)
errChan := make(chan error, 1)
err := client.AddAsyncTask(func() {
defer close(responseChan)
defer close(errChan)
response, err := client.DescribeFleetHistory(request)
response, err := client.DeleteMaintenanceProperty(request)
if err != nil {
errChan <- err
} else {
......@@ -52,16 +52,16 @@ func (client *Client) DescribeFleetHistoryWithChan(request *DescribeFleetHistory
return responseChan, errChan
}
// DescribeFleetHistoryWithCallback invokes the ecs.DescribeFleetHistory API asynchronously
// api document: https://help.aliyun.com/api/ecs/describefleethistory.html
// DeleteMaintenancePropertyWithCallback invokes the ecs.DeleteMaintenanceProperty API asynchronously
// api document: https://help.aliyun.com/api/ecs/deletemaintenanceproperty.html
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
func (client *Client) DescribeFleetHistoryWithCallback(request *DescribeFleetHistoryRequest, callback func(response *DescribeFleetHistoryResponse, err error)) <-chan int {
func (client *Client) DeleteMaintenancePropertyWithCallback(request *DeleteMaintenancePropertyRequest, callback func(response *DeleteMaintenancePropertyResponse, err error)) <-chan int {
result := make(chan int, 1)
err := client.AddAsyncTask(func() {
var response *DescribeFleetHistoryResponse
var response *DeleteMaintenancePropertyResponse
var err error
defer close(result)
response, err = client.DescribeFleetHistory(request)
response, err = client.DeleteMaintenanceProperty(request)
callback(response, err)
result <- 1
})
......@@ -73,38 +73,34 @@ func (client *Client) DescribeFleetHistoryWithCallback(request *DescribeFleetHis
return result
}
// DescribeFleetHistoryRequest is the request struct for api DescribeFleetHistory
type DescribeFleetHistoryRequest struct {
// DeleteMaintenancePropertyRequest is the request struct for api DeleteMaintenanceProperty
type DeleteMaintenancePropertyRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
FleetId string `position:"Query" name:"FleetId"`
InstanceId *[]string `position:"Query" name:"InstanceId" type:"Repeated"`
}
// DescribeFleetHistoryResponse is the response struct for api DescribeFleetHistory
type DescribeFleetHistoryResponse struct {
// DeleteMaintenancePropertyResponse is the response struct for api DeleteMaintenanceProperty
type DeleteMaintenancePropertyResponse struct {
*responses.BaseResponse
RequestId string `json:"RequestId" xml:"RequestId"`
TotalCount int `json:"TotalCount" xml:"TotalCount"`
PageNumber int `json:"PageNumber" xml:"PageNumber"`
PageSize int `json:"PageSize" xml:"PageSize"`
FleetHistorys FleetHistorys `json:"FleetHistorys" xml:"FleetHistorys"`
RequestId string `json:"RequestId" xml:"RequestId"`
}
// CreateDescribeFleetHistoryRequest creates a request to invoke DescribeFleetHistory API
func CreateDescribeFleetHistoryRequest() (request *DescribeFleetHistoryRequest) {
request = &DescribeFleetHistoryRequest{
// CreateDeleteMaintenancePropertyRequest creates a request to invoke DeleteMaintenanceProperty API
func CreateDeleteMaintenancePropertyRequest() (request *DeleteMaintenancePropertyRequest) {
request = &DeleteMaintenancePropertyRequest{
RpcRequest: &requests.RpcRequest{},
}
request.InitWithApiInfo("Ecs", "2014-05-26", "DescribeFleetHistory", "ecs", "openAPI")
request.InitWithApiInfo("Ecs", "2014-05-26", "DeleteMaintenanceProperty", "ecs", "openAPI")
return
}
// CreateDescribeFleetHistoryResponse creates a response to parse from DescribeFleetHistory response
func CreateDescribeFleetHistoryResponse() (response *DescribeFleetHistoryResponse) {
response = &DescribeFleetHistoryResponse{
// CreateDeleteMaintenancePropertyResponse creates a response to parse from DeleteMaintenanceProperty response
func CreateDeleteMaintenancePropertyResponse() (response *DeleteMaintenancePropertyResponse) {
response = &DeleteMaintenancePropertyResponse{
BaseResponse: &responses.BaseResponse{},
}
return
......
......@@ -77,9 +77,9 @@ func (client *Client) DeleteNatGatewayWithCallback(request *DeleteNatGatewayRequ
type DeleteNatGatewayRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
NatGatewayId string `position:"Query" name:"NatGatewayId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
NatGatewayId string `position:"Query" name:"NatGatewayId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -77,11 +77,11 @@ func (client *Client) DeletePhysicalConnectionWithCallback(request *DeletePhysic
type DeletePhysicalConnectionRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
PhysicalConnectionId string `position:"Query" name:"PhysicalConnectionId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
PhysicalConnectionId string `position:"Query" name:"PhysicalConnectionId"`
}
// DeletePhysicalConnectionResponse is the response struct for api DeletePhysicalConnection
......
......@@ -77,13 +77,13 @@ func (client *Client) DeleteRouteEntryWithCallback(request *DeleteRouteEntryRequ
type DeleteRouteEntryRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
NextHopId string `position:"Query" name:"NextHopId"`
RouteTableId string `position:"Query" name:"RouteTableId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
DestinationCidrBlock string `position:"Query" name:"DestinationCidrBlock"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
NextHopId string `position:"Query" name:"NextHopId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
NextHopList *[]DeleteRouteEntryNextHopList `position:"Query" name:"NextHopList" type:"Repeated"`
RouteTableId string `position:"Query" name:"RouteTableId"`
}
// DeleteRouteEntryNextHopList is a repeated param struct in DeleteRouteEntryRequest
......
......@@ -77,10 +77,10 @@ func (client *Client) DeleteRouterInterfaceWithCallback(request *DeleteRouterInt
type DeleteRouterInterfaceRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
UserCidr string `position:"Query" name:"UserCidr"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
RouterInterfaceId string `position:"Query" name:"RouterInterfaceId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -77,9 +77,9 @@ func (client *Client) DeleteSecurityGroupWithCallback(request *DeleteSecurityGro
type DeleteSecurityGroupRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
SecurityGroupId string `position:"Query" name:"SecurityGroupId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
SecurityGroupId string `position:"Query" name:"SecurityGroupId"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
......@@ -80,8 +80,8 @@ type DeleteSnapshotRequest struct {
SnapshotId string `position:"Query" name:"SnapshotId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
Force requests.Boolean `position:"Query" name:"Force"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
Force requests.Boolean `position:"Query" name:"Force"`
}
// DeleteSnapshotResponse is the response struct for api DeleteSnapshot
......
......@@ -76,11 +76,11 @@ func (client *Client) DeleteVSwitchWithCallback(request *DeleteVSwitchRequest, c
// DeleteVSwitchRequest is the request struct for api DeleteVSwitch
type DeleteVSwitchRequest struct {
*requests.RpcRequest
VSwitchId string `position:"Query" name:"VSwitchId"`
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
VSwitchId string `position:"Query" name:"VSwitchId"`
}
// DeleteVSwitchResponse is the response struct for api DeleteVSwitch
......
......@@ -77,11 +77,11 @@ func (client *Client) DeleteVirtualBorderRouterWithCallback(request *DeleteVirtu
type DeleteVirtualBorderRouterRequest struct {
*requests.RpcRequest
ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
ClientToken string `position:"Query" name:"ClientToken"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
UserCidr string `position:"Query" name:"UserCidr"`
VbrId string `position:"Query" name:"VbrId"`
UserCidr string `position:"Query" name:"UserCidr"`
ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
OwnerAccount string `position:"Query" name:"OwnerAccount"`
OwnerId requests.Integer `position:"Query" name:"OwnerId"`
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment