diff --git a/Gopkg.lock b/Gopkg.lock
index e100df6d2..b5e1843c1 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -84,6 +84,24 @@
revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
version = "v1.0.5"
+[[projects]]
+ digest = "1:5e9ea5618cb3451ce312505a48a563e95ce26c9ef498cd0a8833255e5e7f5c61"
+ name = "github.com/aliyun/alibaba-cloud-sdk-go"
+ packages = [
+ "sdk",
+ "sdk/auth",
+ "sdk/auth/credentials",
+ "sdk/auth/signers",
+ "sdk/endpoints",
+ "sdk/errors",
+ "sdk/requests",
+ "sdk/responses",
+ "sdk/utils",
+ ]
+ pruneopts = "NUT"
+ revision = "cad214d7d71fba7883fcf3b7e550ba782c15b400"
+ version = "1.27.7"
+
[[projects]]
digest = "1:5a23cd3a5496a0b2da7e3b348d14e77b11a210738c398200d7d6f04ea8cf3bd8"
name = "github.com/asaskevich/govalidator"
@@ -1371,6 +1389,10 @@
"github.com/Azure/go-autorest/autorest/to",
"github.com/BurntSushi/toml",
"github.com/Sirupsen/logrus",
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk",
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth",
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests",
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses",
"github.com/aws/aws-sdk-go/aws",
"github.com/aws/aws-sdk-go/aws/session",
"github.com/aws/aws-sdk-go/service/cloudwatchlogs",
diff --git a/Gopkg.toml b/Gopkg.toml
index 8d0b01045..11b7c6678 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -136,3 +136,7 @@
[[constraint]]
name = "github.com/Azure/go-autorest"
version = "10.8.1"
+
+[[constraint]]
+ name = "github.com/aliyun/alibaba-cloud-sdk-go"
+ version = "1.27.7"
diff --git a/providers/alicloud/README.md b/providers/alicloud/README.md
new file mode 100644
index 000000000..78d6d104d
--- /dev/null
+++ b/providers/alicloud/README.md
@@ -0,0 +1,57 @@
+# Alibaba Cloud ECI
+
+
+
+Alibaba Cloud ECI(Elastic Container Service) is a service that allow you run containers without having to manage servers or clusters.
+
+You can find more infomation via [alibaba cloud ECI web portal](https://www.aliyun.com/product/eci)
+
+## Alibaba Cloud ECI Virtual-Kubelet Provider
+Alibaba ECI provider is an adapter to connect between k8s and ECI service to implement pod from k8s cluster on alibaba cloud platform
+
+## Prerequisites
+To using ECI service on alibaba cloud, you may need open ECI service on [web portal](https://www.aliyun.com/product/eci), and then the ECI service will be available
+
+## Deployment of the ECI provider in your cluster
+configure and launch virtual kubelet
+```
+export ECI_REGION=cn-hangzhou
+export ECI_SECURITY_GROUP=sg-123
+export ECI_VSWITCH=vsw-123
+export ECI_ACCESS_KEY=123
+export ECI_SECRET_KEY=123
+
+VKUBELET_TAINT_KEY=alibabacloud.com/eci virtual-kubelet --provider alicloud
+```
+confirm the virtual kubelet is connected to k8s cluster
+```
+$kubectl get node
+NAME STATUS ROLES AGE VERSION
+cn-shanghai.i-uf69qodr5ntaxleqdhhk Ready 1d v1.9.3
+virtual-kubelet Ready agent 10s v1.8.3
+```
+
+## Schedule K8s Pod to ECI via virtual kubelet
+You can assign pod to virtual kubelet via node-selector and toleration.
+```
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod
+spec:
+ nodeName: virtual-kubelet
+ containers:
+ - name: nginx
+ image: nginx
+ tolerations:
+ - key: alibabacloud.com/eci
+ operator: "Exists"
+ effect: NoSchedule
+```
+
+# Alibaba Cloud Serverless Kubernetes
+Alibaba Cloud serverless kubernetes allows you to quickly create kubernetes container applications without
+having to manage and maintain clusters and servers. It is based on ECI and fully compatible with the Kuberentes API.
+
+You can find more infomation via [alibaba cloud serverless kubernetes product doc](https://www.alibabacloud.com/help/doc-detail/71479.htm)
+
diff --git a/providers/alicloud/config.go b/providers/alicloud/config.go
new file mode 100644
index 000000000..5cf294b72
--- /dev/null
+++ b/providers/alicloud/config.go
@@ -0,0 +1,51 @@
+package alicloud
+
+import (
+ "io"
+
+ "github.com/BurntSushi/toml"
+ "github.com/virtual-kubelet/virtual-kubelet/providers"
+)
+
+type providerConfig struct {
+ Region string
+ OperatingSystem string
+ CPU string
+ Memory string
+ Pods string
+ VSwitch string
+ SecureGroup string
+}
+
+func (p *ECIProvider) loadConfig(r io.Reader) error {
+ var config providerConfig
+ if _, err := toml.DecodeReader(r, &config); err != nil {
+ return err
+ }
+
+ p.region = config.Region
+ if p.region == "" {
+ p.region = "cn-hangzhou"
+ }
+
+ p.vSwitch = config.VSwitch
+ p.secureGroup = config.SecureGroup
+
+ p.cpu = config.CPU
+ if p.cpu == "" {
+ p.cpu = "20"
+ }
+ p.memory = config.Memory
+ if p.memory == "" {
+ p.memory = "100Gi"
+ }
+ p.pods = config.Pods
+ if p.pods == "" {
+ p.pods = "20"
+ }
+ p.operatingSystem = config.OperatingSystem
+ if p.operatingSystem == "" {
+ p.operatingSystem = providers.OperatingSystemLinux
+ }
+ return nil
+}
diff --git a/providers/alicloud/eci.go b/providers/alicloud/eci.go
new file mode 100644
index 000000000..68056c8a2
--- /dev/null
+++ b/providers/alicloud/eci.go
@@ -0,0 +1,855 @@
+package alicloud
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ "encoding/base64"
+ "encoding/hex"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/virtual-kubelet/virtual-kubelet/log"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/virtual-kubelet/virtual-kubelet/manager"
+ "github.com/virtual-kubelet/virtual-kubelet/providers/alicloud/eci"
+ "k8s.io/api/core/v1"
+ k8serr "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/client-go/tools/remotecommand"
+)
+
+// The service account secret mount path.
+const serviceAccountSecretMountPath = "/var/run/secrets/kubernetes.io/serviceaccount"
+
+const podTagTimeFormat = "2006-01-02T15-04-05Z"
+const timeFormat = "2006-01-02T15:04:05Z"
+
+// ECIProvider implements the virtual-kubelet provider interface and communicates with Alibaba Cloud's ECI APIs.
+type ECIProvider struct {
+ eciClient *eci.Client
+ resourceManager *manager.ResourceManager
+ resourceGroup string
+ region string
+ nodeName string
+ operatingSystem string
+ cpu string
+ memory string
+ pods string
+ internalIP string
+ daemonEndpointPort int32
+ secureGroup string
+ vSwitch string
+}
+
+// AuthConfig is the secret returned from an ImageRegistryCredential
+type AuthConfig struct {
+ Username string `json:"username,omitempty"`
+ Password string `json:"password,omitempty"`
+ Auth string `json:"auth,omitempty"`
+ Email string `json:"email,omitempty"`
+ ServerAddress string `json:"serveraddress,omitempty"`
+ IdentityToken string `json:"identitytoken,omitempty"`
+ RegistryToken string `json:"registrytoken,omitempty"`
+}
+
+var validEciRegions = []string{
+ "cn-hangzhou",
+ "cn-shanghai",
+ "cn-beijing",
+ "us-west-1",
+}
+
+// isValidECIRegion checks to make sure we're using a valid ECI region
+func isValidECIRegion(region string) bool {
+ regionLower := strings.ToLower(region)
+ regionTrimmed := strings.Replace(regionLower, " ", "", -1)
+
+ for _, validRegion := range validEciRegions {
+ if regionTrimmed == validRegion {
+ return true
+ }
+ }
+
+ return false
+}
+
+// NewECIProvider creates a new ECIProvider.
+func NewECIProvider(config string, rm *manager.ResourceManager, nodeName, operatingSystem string, internalIP string, daemonEndpointPort int32) (*ECIProvider, error) {
+ var p ECIProvider
+ var err error
+
+ p.resourceManager = rm
+
+ if config != "" {
+ f, err := os.Open(config)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ if err := p.loadConfig(f); err != nil {
+ return nil, err
+ }
+ }
+
+ if r := os.Getenv("ECI_REGION"); r != "" {
+ p.region = r
+ }
+ if p.region == "" {
+ return nil, errors.New("Region can't be empty please set ECI_REGION\n")
+ }
+ if r := p.region; !isValidECIRegion(r) {
+ unsupportedRegionMessage := fmt.Sprintf("Region %s is invalid. Current supported regions are: %s",
+ r, strings.Join(validEciRegions, ", "))
+
+ return nil, errors.New(unsupportedRegionMessage)
+ }
+
+ var accessKey, secretKey string
+
+ if ak := os.Getenv("ECI_ACCESS_KEY"); ak != "" {
+ accessKey = ak
+ }
+ if sk := os.Getenv("ECI_SECRET_KEY"); sk != "" {
+ secretKey = sk
+ }
+ if sg := os.Getenv("ECI_SECURITY_GROUP"); sg != "" {
+ p.secureGroup = sg
+ }
+ if vsw := os.Getenv("ECI_VSWITCH"); vsw != "" {
+ p.vSwitch = vsw
+ }
+ if p.secureGroup == "" {
+ return nil, errors.New("secureGroup can't be empty\n")
+ }
+
+ if p.vSwitch == "" {
+ return nil, errors.New("vSwitch can't be empty\n")
+ }
+
+ p.eciClient, err = eci.NewClientWithAccessKey(p.region, accessKey, secretKey)
+ if err != nil {
+ return nil, err
+ }
+
+ p.cpu = "1000"
+ p.memory = "4Ti"
+ p.pods = "1000"
+
+ if cpuQuota := os.Getenv("ECI_QUOTA_CPU"); cpuQuota != "" {
+ p.cpu = cpuQuota
+ }
+
+ if memoryQuota := os.Getenv("ECI_QUOTA_MEMORY"); memoryQuota != "" {
+ p.memory = memoryQuota
+ }
+
+ if podsQuota := os.Getenv("ECI_QUOTA_POD"); podsQuota != "" {
+ p.pods = podsQuota
+ }
+
+ p.operatingSystem = operatingSystem
+ p.nodeName = nodeName
+ p.internalIP = internalIP
+ p.daemonEndpointPort = daemonEndpointPort
+ return &p, err
+}
+
+// CreatePod accepts a Pod definition and creates
+// an ECI deployment
+func (p *ECIProvider) CreatePod(ctx context.Context, pod *v1.Pod) error {
+ //Ignore daemonSet Pod
+ if pod != nil && pod.OwnerReferences != nil && len(pod.OwnerReferences) != 0 && pod.OwnerReferences[0].Kind == "DaemonSet" {
+ msg := fmt.Sprintf("Skip to create DaemonSet pod %q", pod.Name)
+ log.G(ctx).WithField("Method", "CreatePod").Info(msg)
+ return nil
+ }
+
+ request := eci.CreateCreateContainerGroupRequest()
+ request.RestartPolicy = string(pod.Spec.RestartPolicy)
+
+ // get containers
+ containers, err := p.getContainers(pod)
+ if err != nil {
+ return err
+ }
+
+ // get registry creds
+ creds, err := p.getImagePullSecrets(pod)
+ if err != nil {
+ return err
+ }
+
+ // get volumes
+ volumes, err := p.getVolumes(pod)
+ if err != nil {
+ return err
+ }
+
+ // assign all the things
+ request.Containers = containers
+ request.Volumes = volumes
+ request.ImageRegistryCredentials = creds
+ CreationTimestamp := pod.CreationTimestamp.UTC().Format(podTagTimeFormat)
+ tags := []eci.Tag{
+ eci.Tag{Key: "PodName", Value: pod.Name},
+ eci.Tag{Key: "ClusterName", Value: pod.ClusterName},
+ eci.Tag{Key: "NodeName", Value: pod.Spec.NodeName},
+ eci.Tag{Key: "NameSpace", Value: pod.Namespace},
+ eci.Tag{Key: "UID", Value: string(pod.UID)},
+ eci.Tag{Key: "CreationTimestamp", Value: CreationTimestamp},
+ }
+
+ ContainerGroupName := containerGroupName(pod)
+ request.Tags = tags
+ request.SecurityGroupId = p.secureGroup
+ request.VSwitchId = p.vSwitch
+ request.ContainerGroupName = ContainerGroupName
+ response, err := p.eciClient.CreateContainerGroup(request)
+ if err != nil {
+ return err
+ }
+ msg := fmt.Sprintf("CreateContainerGroup successed. %s, %s, %s", response.RequestId, response.ContainerGroupId, ContainerGroupName)
+ log.G(ctx).WithField("Method", "CreatePod").Info(msg)
+ return nil
+}
+
+func containerGroupName(pod *v1.Pod) string {
+ return fmt.Sprintf("%s-%s", pod.Namespace, pod.Name)
+}
+
+// UpdatePod is a noop, ECI currently does not support live updates of a pod.
+func (p *ECIProvider) UpdatePod(ctx context.Context, pod *v1.Pod) error {
+ return nil
+}
+
+// DeletePod deletes the specified pod out of ECI.
+func (p *ECIProvider) DeletePod(ctx context.Context, pod *v1.Pod) error {
+ eciId := ""
+ for _, cg := range p.GetCgs() {
+ if getECITagValue(&cg, "PodName") == pod.Name && getECITagValue(&cg, "NameSpace") == pod.Namespace {
+ eciId = cg.ContainerGroupId
+ break
+ }
+ }
+ if eciId == "" {
+ return fmt.Errorf("DeletePod cann't find Pod %s-%s", pod.Namespace, pod.Name)
+ }
+
+ request := eci.CreateDeleteContainerGroupRequest()
+ request.ContainerGroupId = eciId
+ _, err := p.eciClient.DeleteContainerGroup(request)
+ return err
+}
+
+// GetPod returns a pod by name that is running inside ECI
+// returns nil if a pod by that name is not found.
+func (p *ECIProvider) GetPod(ctx context.Context, namespace, name string) (*v1.Pod, error) {
+ pods, err := p.GetPods(ctx)
+ if err != nil {
+ return nil, err
+ }
+ for _, pod := range pods {
+ if pod.Name == name && pod.Namespace == namespace {
+ return pod, nil
+ }
+ }
+ return nil, nil
+}
+
+// GetContainerLogs returns the logs of a pod by name that is running inside ECI.
+func (p *ECIProvider) GetContainerLogs(ctx context.Context, namespace, podName, containerName string, tail int) (string, error) {
+ eciId := ""
+ for _, cg := range p.GetCgs() {
+ if getECITagValue(&cg, "PodName") == podName && getECITagValue(&cg, "NameSpace") == namespace {
+ eciId = cg.ContainerGroupId
+ break
+ }
+ }
+ if eciId == "" {
+ return "", errors.New(fmt.Sprintf("GetContainerLogs cann't find Pod %s-%s", namespace, podName))
+ }
+
+ request := eci.CreateDescribeContainerLogRequest()
+ request.ContainerGroupId = eciId
+ request.ContainerName = containerName
+ request.Tail = requests.Integer(tail)
+
+ // get logs from cg
+ logContent := ""
+ retry := 10
+ for i := 0; i < retry; i++ {
+ response, err := p.eciClient.DescribeContainerLog(request)
+ if err != nil {
+ msg := fmt.Sprint("Error getting container logs, retrying")
+ log.G(ctx).WithField("Method", "GetContainerLogs").Info(msg)
+ time.Sleep(5000 * time.Millisecond)
+ } else {
+ logContent = response.Content
+ break
+ }
+ }
+
+ return logContent, nil
+}
+
+// Get full pod name as defined in the provider context
+func (p *ECIProvider) GetPodFullName(namespace string, pod string) string {
+ return fmt.Sprintf("%s-%s", namespace, pod)
+}
+
+// ExecInContainer executes a command in a container in the pod, copying data
+// between in/out/err and the container's stdin/stdout/stderr.
+func (p *ECIProvider) ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, errstream io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error {
+ return nil
+}
+
+// GetPodStatus returns the status of a pod by name that is running inside ECI
+// returns nil if a pod by that name is not found.
+func (p *ECIProvider) GetPodStatus(ctx context.Context, namespace, name string) (*v1.PodStatus, error) {
+ pod, err := p.GetPod(ctx, namespace, name)
+ if err != nil {
+ return nil, err
+ }
+
+ if pod == nil {
+ return nil, nil
+ }
+
+ return &pod.Status, nil
+}
+
+func (p *ECIProvider) GetCgs() []eci.ContainerGroup {
+ cgs := make([]eci.ContainerGroup, 0)
+ request := eci.CreateDescribeContainerGroupsRequest()
+ for {
+ cgsResponse, err := p.eciClient.DescribeContainerGroups(request)
+ if err != nil || len(cgsResponse.ContainerGroups) == 0 {
+ break
+ }
+ request.NextToken = cgsResponse.NextToken
+
+ for _, cg := range cgsResponse.ContainerGroups {
+ if getECITagValue(&cg, "NodeName") != p.nodeName {
+ continue
+ }
+ cgs = append(cgs, cg)
+ }
+ if request.NextToken == "" {
+ break
+ }
+ }
+ return cgs
+}
+
+// GetPods returns a list of all pods known to be running within ECI.
+func (p *ECIProvider) GetPods(ctx context.Context) ([]*v1.Pod, error) {
+ pods := make([]*v1.Pod, 0)
+ for _, cg := range p.GetCgs() {
+ c := cg
+ pod, err := containerGroupToPod(&c)
+ if err != nil {
+ msg := fmt.Sprint("error converting container group to pod", cg.ContainerGroupId, err)
+ log.G(context.TODO()).WithField("Method", "GetPods").Info(msg)
+ continue
+ }
+ pods = append(pods, pod)
+ }
+ return pods, nil
+}
+
+// Capacity returns a resource list containing the capacity limits set for ECI.
+func (p *ECIProvider) Capacity(ctx context.Context) v1.ResourceList {
+ return v1.ResourceList{
+ "cpu": resource.MustParse(p.cpu),
+ "memory": resource.MustParse(p.memory),
+ "pods": resource.MustParse(p.pods),
+ }
+}
+
+// NodeConditions returns a list of conditions (Ready, OutOfDisk, etc), for updates to the node status
+// within Kubernetes.
+func (p *ECIProvider) NodeConditions(ctx context.Context) []v1.NodeCondition {
+ // TODO: Make these dynamic and augment with custom ECI specific conditions of interest
+ return []v1.NodeCondition{
+ {
+ Type: "Ready",
+ Status: v1.ConditionTrue,
+ LastHeartbeatTime: metav1.Now(),
+ LastTransitionTime: metav1.Now(),
+ Reason: "KubeletReady",
+ Message: "kubelet is ready.",
+ },
+ {
+ Type: "OutOfDisk",
+ Status: v1.ConditionFalse,
+ LastHeartbeatTime: metav1.Now(),
+ LastTransitionTime: metav1.Now(),
+ Reason: "KubeletHasSufficientDisk",
+ Message: "kubelet has sufficient disk space available",
+ },
+ {
+ Type: "MemoryPressure",
+ Status: v1.ConditionFalse,
+ LastHeartbeatTime: metav1.Now(),
+ LastTransitionTime: metav1.Now(),
+ Reason: "KubeletHasSufficientMemory",
+ Message: "kubelet has sufficient memory available",
+ },
+ {
+ Type: "DiskPressure",
+ Status: v1.ConditionFalse,
+ LastHeartbeatTime: metav1.Now(),
+ LastTransitionTime: metav1.Now(),
+ Reason: "KubeletHasNoDiskPressure",
+ Message: "kubelet has no disk pressure",
+ },
+ {
+ Type: "NetworkUnavailable",
+ Status: v1.ConditionFalse,
+ LastHeartbeatTime: metav1.Now(),
+ LastTransitionTime: metav1.Now(),
+ Reason: "RouteCreated",
+ Message: "RouteController created a route",
+ },
+ }
+}
+
+// NodeAddresses returns a list of addresses for the node status
+// within Kubernetes.
+func (p *ECIProvider) NodeAddresses(ctx context.Context) []v1.NodeAddress {
+ // TODO: Make these dynamic and augment with custom ECI specific conditions of interest
+ return []v1.NodeAddress{
+ {
+ Type: "InternalIP",
+ Address: p.internalIP,
+ },
+ }
+}
+
+// NodeDaemonEndpoints returns NodeDaemonEndpoints for the node status
+// within Kubernetes.
+func (p *ECIProvider) NodeDaemonEndpoints(ctx context.Context) *v1.NodeDaemonEndpoints {
+ return &v1.NodeDaemonEndpoints{
+ KubeletEndpoint: v1.DaemonEndpoint{
+ Port: p.daemonEndpointPort,
+ },
+ }
+}
+
+// OperatingSystem returns the operating system that was provided by the config.
+func (p *ECIProvider) OperatingSystem() string {
+ return p.operatingSystem
+}
+
+func (p *ECIProvider) getImagePullSecrets(pod *v1.Pod) ([]eci.ImageRegistryCredential, error) {
+ ips := make([]eci.ImageRegistryCredential, 0, len(pod.Spec.ImagePullSecrets))
+ for _, ref := range pod.Spec.ImagePullSecrets {
+ secret, err := p.resourceManager.GetSecret(ref.Name, pod.Namespace)
+ if err != nil {
+ return ips, err
+ }
+ if secret == nil {
+ return nil, fmt.Errorf("error getting image pull secret")
+ }
+ // TODO: Check if secret type is v1.SecretTypeDockercfg and use DockerConfigKey instead of hardcoded value
+ // TODO: Check if secret type is v1.SecretTypeDockerConfigJson and use DockerConfigJsonKey to determine if it's in json format
+ // TODO: Return error if it's not one of these two types
+ switch secret.Type {
+ case v1.SecretTypeDockercfg:
+ ips, err = readDockerCfgSecret(secret, ips)
+ case v1.SecretTypeDockerConfigJson:
+ ips, err = readDockerConfigJSONSecret(secret, ips)
+ default:
+ return nil, fmt.Errorf("image pull secret type is not one of kubernetes.io/dockercfg or kubernetes.io/dockerconfigjson")
+ }
+
+ if err != nil {
+ return ips, err
+ }
+ }
+ return ips, nil
+}
+
+func readDockerCfgSecret(secret *v1.Secret, ips []eci.ImageRegistryCredential) ([]eci.ImageRegistryCredential, error) {
+ var err error
+ var authConfigs map[string]AuthConfig
+ repoData, ok := secret.Data[string(v1.DockerConfigKey)]
+
+ if !ok {
+ return ips, fmt.Errorf("no dockercfg present in secret")
+ }
+
+ err = json.Unmarshal(repoData, &authConfigs)
+ if err != nil {
+ return ips, fmt.Errorf("failed to unmarshal auth config %+v", err)
+ }
+
+ for server, authConfig := range authConfigs {
+ ips = append(ips, eci.ImageRegistryCredential{
+ Password: authConfig.Password,
+ Server: server,
+ UserName: authConfig.Username,
+ })
+ }
+
+ return ips, err
+}
+
+func readDockerConfigJSONSecret(secret *v1.Secret, ips []eci.ImageRegistryCredential) ([]eci.ImageRegistryCredential, error) {
+ var err error
+ repoData, ok := secret.Data[string(v1.DockerConfigJsonKey)]
+
+ if !ok {
+ return ips, fmt.Errorf("no dockerconfigjson present in secret")
+ }
+
+ var authConfigs map[string]map[string]AuthConfig
+
+ err = json.Unmarshal(repoData, &authConfigs)
+ if err != nil {
+ return ips, err
+ }
+
+ auths, ok := authConfigs["auths"]
+
+ if !ok {
+ return ips, fmt.Errorf("malformed dockerconfigjson in secret")
+ }
+
+ for server, authConfig := range auths {
+ ips = append(ips, eci.ImageRegistryCredential{
+ Password: authConfig.Password,
+ Server: server,
+ UserName: authConfig.Username,
+ })
+ }
+
+ return ips, err
+}
+
+func (p *ECIProvider) getContainers(pod *v1.Pod) ([]eci.CreateContainer, error) {
+ containers := make([]eci.CreateContainer, 0, len(pod.Spec.Containers))
+ for _, container := range pod.Spec.Containers {
+ c := eci.CreateContainer{
+ Name: container.Name,
+ Image: container.Image,
+ Commands: append(container.Command, container.Args...),
+ Ports: make([]eci.ContainerPort, 0, len(container.Ports)),
+ }
+
+ for _, p := range container.Ports {
+ c.Ports = append(c.Ports, eci.ContainerPort{
+ Port: requests.Integer(strconv.FormatInt(int64(p.ContainerPort), 10)),
+ Protocol: string(p.Protocol),
+ })
+ }
+
+ c.VolumeMounts = make([]eci.VolumeMount, 0, len(container.VolumeMounts))
+ for _, v := range container.VolumeMounts {
+ c.VolumeMounts = append(c.VolumeMounts, eci.VolumeMount{
+ Name: v.Name,
+ MountPath: v.MountPath,
+ ReadOnly: requests.Boolean(strconv.FormatBool(v.ReadOnly)),
+ })
+ }
+
+ c.EnvironmentVars = make([]eci.EnvironmentVar, 0, len(container.Env))
+ for _, e := range container.Env {
+ c.EnvironmentVars = append(c.EnvironmentVars, eci.EnvironmentVar{Key: e.Name, Value: e.Value})
+ }
+
+ // ECI CPU request must be times of 10m
+ cpuRequest := 1.00
+ if _, ok := container.Resources.Requests[v1.ResourceCPU]; ok {
+ cpuRequest = float64(container.Resources.Requests.Cpu().MilliValue()) / 1000.00
+ if cpuRequest < 0.01 {
+ cpuRequest = 0.01
+ }
+ }
+
+ c.Cpu = requests.Float(fmt.Sprintf("%.2f", cpuRequest))
+
+ // ECI memory request must be times of 0.1 GB
+ memoryRequest := 2.0
+ if _, ok := container.Resources.Requests[v1.ResourceMemory]; ok {
+ memoryRequest = float64(container.Resources.Requests.Memory().Value()) / 1000000000.0
+ if memoryRequest < 2.0 {
+ memoryRequest = 2.0
+ }
+ }
+
+ c.Memory = requests.Float(fmt.Sprintf("%.1f", memoryRequest))
+
+ c.ImagePullPolicy = string(container.ImagePullPolicy)
+ c.WorkingDir = container.WorkingDir
+
+ containers = append(containers, c)
+ }
+ return containers, nil
+}
+
+func (p *ECIProvider) getVolumes(pod *v1.Pod) ([]eci.Volume, error) {
+ volumes := make([]eci.Volume, 0, len(pod.Spec.Volumes))
+ for _, v := range pod.Spec.Volumes {
+ // Handle the case for the EmptyDir.
+ if v.EmptyDir != nil {
+ volumes = append(volumes, eci.Volume{
+ Type: eci.VOL_TYPE_EMPTYDIR,
+ Name: v.Name,
+ EmptyDirVolumeEnable: requests.Boolean(strconv.FormatBool(true)),
+ })
+ continue
+ }
+
+ // Handle the case for the NFS.
+ if v.NFS != nil {
+ volumes = append(volumes, eci.Volume{
+ Type: eci.VOL_TYPE_NFS,
+ Name: v.Name,
+ NfsVolumeServer: v.NFS.Server,
+ NfsVolumePath: v.NFS.Path,
+ NfsVolumeReadOnly: requests.Boolean(strconv.FormatBool(v.NFS.ReadOnly)),
+ })
+ continue
+ }
+
+ // Handle the case for ConfigMap volume.
+ if v.ConfigMap != nil {
+ ConfigFileToPaths := make([]eci.ConfigFileToPath, 0)
+ configMap, err := p.resourceManager.GetConfigMap(v.ConfigMap.Name, pod.Namespace)
+ if v.ConfigMap.Optional != nil && !*v.ConfigMap.Optional && k8serr.IsNotFound(err) {
+ return nil, fmt.Errorf("ConfigMap %s is required by Pod %s and does not exist", v.ConfigMap.Name, pod.Name)
+ }
+ if configMap == nil {
+ continue
+ }
+
+ for k, v := range configMap.Data {
+ var b bytes.Buffer
+ enc := base64.NewEncoder(base64.StdEncoding, &b)
+ enc.Write([]byte(v))
+
+ ConfigFileToPaths = append(ConfigFileToPaths, eci.ConfigFileToPath{Path: k, Content: b.String()})
+ }
+
+ if len(ConfigFileToPaths) != 0 {
+ volumes = append(volumes, eci.Volume{
+ Type: eci.VOL_TYPE_CONFIGFILEVOLUME,
+ Name: v.Name,
+ ConfigFileVolumeConfigFileToPaths: ConfigFileToPaths,
+ })
+ }
+ continue
+ }
+
+ // If we've made it this far we have found a volume type that isn't supported
+ return nil, fmt.Errorf("Pod %s requires volume %s which is of an unsupported type\n", pod.Name, v.Name)
+ }
+
+ return volumes, nil
+}
+
+func containerGroupToPod(cg *eci.ContainerGroup) (*v1.Pod, error) {
+ var podCreationTimestamp, containerStartTime metav1.Time
+
+ CreationTimestamp := getECITagValue(cg, "CreationTimestamp")
+ if CreationTimestamp != "" {
+ if t, err := time.Parse(podTagTimeFormat, CreationTimestamp); err == nil {
+ podCreationTimestamp = metav1.NewTime(t)
+ }
+ }
+
+ if t, err := time.Parse(timeFormat, cg.Containers[0].CurrentState.StartTime); err == nil {
+ containerStartTime = metav1.NewTime(t)
+ }
+
+ // Use the Provisioning State if it's not Succeeded,
+ // otherwise use the state of the instance.
+ eciState := cg.Status
+
+ containers := make([]v1.Container, 0, len(cg.Containers))
+ containerStatuses := make([]v1.ContainerStatus, 0, len(cg.Containers))
+ for _, c := range cg.Containers {
+ container := v1.Container{
+ Name: c.Name,
+ Image: c.Image,
+ Command: c.Commands,
+ Resources: v1.ResourceRequirements{
+ Requests: v1.ResourceList{
+ v1.ResourceCPU: resource.MustParse(fmt.Sprintf("%.2f", c.Cpu)),
+ v1.ResourceMemory: resource.MustParse(fmt.Sprintf("%.1fG", c.Memory)),
+ },
+ },
+ }
+
+ container.Resources.Limits = v1.ResourceList{
+ v1.ResourceCPU: resource.MustParse(fmt.Sprintf("%.2f", c.Cpu)),
+ v1.ResourceMemory: resource.MustParse(fmt.Sprintf("%.1fG", c.Memory)),
+ }
+
+ containers = append(containers, container)
+ containerStatus := v1.ContainerStatus{
+ Name: c.Name,
+ State: eciContainerStateToContainerState(c.CurrentState),
+ LastTerminationState: eciContainerStateToContainerState(c.PreviousState),
+ Ready: eciStateToPodPhase(c.CurrentState.State) == v1.PodRunning,
+ RestartCount: int32(c.RestartCount),
+ Image: c.Image,
+ ImageID: "",
+ ContainerID: getContainerID(cg.ContainerGroupId, c.Name),
+ }
+
+ // Add to containerStatuses
+ containerStatuses = append(containerStatuses, containerStatus)
+ }
+
+ pod := v1.Pod{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "Pod",
+ APIVersion: "v1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: getECITagValue(cg, "PodName"),
+ Namespace: getECITagValue(cg, "NameSpace"),
+ ClusterName: getECITagValue(cg, "ClusterName"),
+ UID: types.UID(getECITagValue(cg, "UID")),
+ CreationTimestamp: podCreationTimestamp,
+ },
+ Spec: v1.PodSpec{
+ NodeName: getECITagValue(cg, "NodeName"),
+ Volumes: []v1.Volume{},
+ Containers: containers,
+ },
+ Status: v1.PodStatus{
+ Phase: eciStateToPodPhase(eciState),
+ Conditions: eciStateToPodConditions(eciState, podCreationTimestamp),
+ Message: "",
+ Reason: "",
+ HostIP: "",
+ PodIP: cg.InternetIp,
+ StartTime: &containerStartTime,
+ ContainerStatuses: containerStatuses,
+ },
+ }
+
+ return &pod, nil
+}
+
+func getContainerID(cgID, containerName string) string {
+ if cgID == "" {
+ return ""
+ }
+
+ containerResourceID := fmt.Sprintf("%s/containers/%s", cgID, containerName)
+
+ h := sha256.New()
+ h.Write([]byte(strings.ToUpper(containerResourceID)))
+ hashBytes := h.Sum(nil)
+ return fmt.Sprintf("eci://%s", hex.EncodeToString(hashBytes))
+}
+
+func eciStateToPodPhase(state string) v1.PodPhase {
+ switch state {
+ case "Scheduling":
+ return v1.PodPending
+ case "ScheduleFailed":
+ return v1.PodFailed
+ case "Pending":
+ return v1.PodPending
+ case "Running":
+ return v1.PodRunning
+ case "Failed":
+ return v1.PodFailed
+ case "Succeeded":
+ return v1.PodSucceeded
+ }
+ return v1.PodUnknown
+}
+
+func eciStateToPodConditions(state string, transitionTime metav1.Time) []v1.PodCondition {
+ switch state {
+ case "Running", "Succeeded":
+ return []v1.PodCondition{
+ v1.PodCondition{
+ Type: v1.PodReady,
+ Status: v1.ConditionTrue,
+ LastTransitionTime: transitionTime,
+ }, v1.PodCondition{
+ Type: v1.PodInitialized,
+ Status: v1.ConditionTrue,
+ LastTransitionTime: transitionTime,
+ }, v1.PodCondition{
+ Type: v1.PodScheduled,
+ Status: v1.ConditionTrue,
+ LastTransitionTime: transitionTime,
+ },
+ }
+ }
+ return []v1.PodCondition{}
+}
+
+func eciContainerStateToContainerState(cs eci.ContainerState) v1.ContainerState {
+ t1, err := time.Parse(timeFormat, cs.StartTime)
+ if err != nil {
+ return v1.ContainerState{}
+ }
+
+ startTime := metav1.NewTime(t1)
+
+ // Handle the case where the container is running.
+ if cs.State == "Running" || cs.State == "Succeeded" {
+ return v1.ContainerState{
+ Running: &v1.ContainerStateRunning{
+ StartedAt: startTime,
+ },
+ }
+ }
+
+ t2, err := time.Parse(timeFormat, cs.FinishTime)
+ if err != nil {
+ return v1.ContainerState{}
+ }
+
+ finishTime := metav1.NewTime(t2)
+
+ // Handle the case where the container failed.
+ if cs.State == "Failed" || cs.State == "Canceled" {
+ return v1.ContainerState{
+ Terminated: &v1.ContainerStateTerminated{
+ ExitCode: int32(cs.ExitCode),
+ Reason: cs.State,
+ Message: cs.DetailStatus,
+ StartedAt: startTime,
+ FinishedAt: finishTime,
+ },
+ }
+ }
+
+ // Handle the case where the container is pending.
+ // Which should be all other eci states.
+ return v1.ContainerState{
+ Waiting: &v1.ContainerStateWaiting{
+ Reason: cs.State,
+ Message: cs.DetailStatus,
+ },
+ }
+}
+
+func getECITagValue(cg *eci.ContainerGroup, key string) string {
+ for _, tag := range cg.Tags {
+ if tag.Key == key {
+ return tag.Value
+ }
+ }
+ return ""
+}
diff --git a/providers/alicloud/eci.svg b/providers/alicloud/eci.svg
new file mode 100644
index 000000000..e31def4c6
--- /dev/null
+++ b/providers/alicloud/eci.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/providers/alicloud/eci.toml b/providers/alicloud/eci.toml
new file mode 100644
index 000000000..acb3090e6
--- /dev/null
+++ b/providers/alicloud/eci.toml
@@ -0,0 +1,5 @@
+Region = "cn-hangzhou"
+OperatingSystem = "Linux"
+CPU = "20"
+Memory = "100Gi"
+Pods = "20"
diff --git a/providers/alicloud/eci/client.go b/providers/alicloud/eci/client.go
new file mode 100644
index 000000000..fed034af5
--- /dev/null
+++ b/providers/alicloud/eci/client.go
@@ -0,0 +1,81 @@
+package eci
+
+//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"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
+)
+
+// Client is the sdk client struct, each func corresponds to an OpenAPI
+type Client struct {
+ sdk.Client
+}
+
+// NewClient creates a sdk client with environment variables
+func NewClient() (client *Client, err error) {
+ client = &Client{}
+ err = client.Init()
+ return
+}
+
+// NewClientWithOptions creates a sdk client with regionId/sdkConfig/credential
+// this is the common api to create a sdk client
+func NewClientWithOptions(regionId string, config *sdk.Config, credential auth.Credential) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithOptions(regionId, config, credential)
+ return
+}
+
+// NewClientWithAccessKey is a shortcut to create sdk client with accesskey
+// usage: https://help.aliyun.com/document_detail/66217.html
+func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithAccessKey(regionId, accessKeyId, accessKeySecret)
+ return
+}
+
+// NewClientWithStsToken is a shortcut to create sdk client with sts token
+// usage: https://help.aliyun.com/document_detail/66222.html
+func NewClientWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken)
+ return
+}
+
+// NewClientWithRamRoleArn is a shortcut to create sdk client with ram roleArn
+// usage: https://help.aliyun.com/document_detail/66222.html
+func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName)
+ return
+}
+
+// NewClientWithEcsRamRole is a shortcut to create sdk client with ecs ram role
+// usage: https://help.aliyun.com/document_detail/66223.html
+func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithEcsRamRole(regionId, roleName)
+ return
+}
+
+// NewClientWithRsaKeyPair is a shortcut to create sdk client with rsa key pair
+// attention: rsa key pair auth is only Japan regions available
+func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration)
+ return
+}
diff --git a/providers/alicloud/eci/create_container_group.go b/providers/alicloud/eci/create_container_group.go
new file mode 100644
index 000000000..2c0249e8d
--- /dev/null
+++ b/providers/alicloud/eci/create_container_group.go
@@ -0,0 +1,137 @@
+package eci
+
+//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"
+)
+
+// CreateContainerGroup invokes the eci.CreateContainerGroup API synchronously
+// api document: https://help.aliyun.com/api/eci/createcontainergroup.html
+func (client *Client) CreateContainerGroup(request *CreateContainerGroupRequest) (response *CreateContainerGroupResponse, err error) {
+ response = CreateCreateContainerGroupResponse()
+ err = client.DoAction(request, response)
+ return
+}
+
+// CreateContainerGroupWithChan invokes the eci.CreateContainerGroup API asynchronously
+// api document: https://help.aliyun.com/api/eci/createcontainergroup.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) CreateContainerGroupWithChan(request *CreateContainerGroupRequest) (<-chan *CreateContainerGroupResponse, <-chan error) {
+ responseChan := make(chan *CreateContainerGroupResponse, 1)
+ errChan := make(chan error, 1)
+ err := client.AddAsyncTask(func() {
+ defer close(responseChan)
+ defer close(errChan)
+ response, err := client.CreateContainerGroup(request)
+ if err != nil {
+ errChan <- err
+ } else {
+ responseChan <- response
+ }
+ })
+ if err != nil {
+ errChan <- err
+ close(responseChan)
+ close(errChan)
+ }
+ return responseChan, errChan
+}
+
+// CreateContainerGroupWithCallback invokes the eci.CreateContainerGroup API asynchronously
+// api document: https://help.aliyun.com/api/eci/createcontainergroup.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) CreateContainerGroupWithCallback(request *CreateContainerGroupRequest, callback func(response *CreateContainerGroupResponse, err error)) <-chan int {
+ result := make(chan int, 1)
+ err := client.AddAsyncTask(func() {
+ var response *CreateContainerGroupResponse
+ var err error
+ defer close(result)
+ response, err = client.CreateContainerGroup(request)
+ callback(response, err)
+ result <- 1
+ })
+ if err != nil {
+ defer close(result)
+ callback(nil, err)
+ result <- 0
+ }
+ return result
+}
+
+// CreateContainerGroupRequest is the request struct for api CreateContainerGroup
+type CreateContainerGroupRequest struct {
+ *requests.RpcRequest
+ Containers []CreateContainer `position:"Query" name:"Container" type:"Repeated"`
+ ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
+ SecurityGroupId string `position:"Query" name:"SecurityGroupId"`
+ ImageRegistryCredentials []ImageRegistryCredential `position:"Query" name:"ImageRegistryCredential" type:"Repeated"`
+ Tags []Tag `position:"Query" name:"Tag" type:"Repeated"`
+ ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
+ RestartPolicy string `position:"Query" name:"RestartPolicy"`
+ OwnerAccount string `position:"Query" name:"OwnerAccount"`
+ OwnerId requests.Integer `position:"Query" name:"OwnerId"`
+ VSwitchId string `position:"Query" name:"VSwitchId"`
+ Volumes []Volume `position:"Query" name:"Volume" type:"Repeated"`
+ ContainerGroupName string `position:"Query" name:"ContainerGroupName"`
+ ZoneId string `position:"Query" name:"ZoneId"`
+}
+
+type CreateContainer struct {
+ Name string `position:"Query" name:"Name"`
+ Image string `position:"Query" name:"Image"`
+ Memory requests.Float `position:"Query" name:"Memory"`
+ Cpu requests.Float `position:"Query" name:"Cpu"`
+ WorkingDir string `position:"Query" name:"WorkingDir"`
+ ImagePullPolicy string `position:"Query" name:"ImagePullPolicy"`
+ Commands []string `position:"Query" name:"Command" type:"Repeated"`
+ Args []string `position:"Query" name:"Arg" type:"Repeated"`
+ VolumeMounts []VolumeMount `position:"Query" name:"VolumeMount" type:"Repeated"`
+ Ports []ContainerPort `position:"Query" name:"Port" type:"Repeated"`
+ EnvironmentVars []EnvironmentVar `position:"Query" name:"EnvironmentVar" type:"Repeated"`
+}
+
+// CreateContainerGroupImageRegistryCredential is a repeated param struct in CreateContainerGroupRequest
+type ImageRegistryCredential struct {
+ Server string `name:"Server"`
+ UserName string `name:"UserName"`
+ Password string `name:"Password"`
+}
+
+// CreateContainerGroupResponse is the response struct for api CreateContainerGroup
+type CreateContainerGroupResponse struct {
+ *responses.BaseResponse
+ RequestId string `json:"RequestId" xml:"RequestId"`
+ ContainerGroupId string `json:"ContainerGroupId" xml:"ContainerGroupId"`
+}
+
+// CreateCreateContainerGroupRequest creates a request to invoke CreateContainerGroup API
+func CreateCreateContainerGroupRequest() (request *CreateContainerGroupRequest) {
+ request = &CreateContainerGroupRequest{
+ RpcRequest: &requests.RpcRequest{},
+ }
+ request.InitWithApiInfo("Eci", "2018-08-08", "CreateContainerGroup", "eci", "openAPI")
+ return
+}
+
+// CreateCreateContainerGroupResponse creates a response to parse from CreateContainerGroup response
+func CreateCreateContainerGroupResponse() (response *CreateContainerGroupResponse) {
+ response = &CreateContainerGroupResponse{
+ BaseResponse: &responses.BaseResponse{},
+ }
+ return
+}
diff --git a/providers/alicloud/eci/delete_container_group.go b/providers/alicloud/eci/delete_container_group.go
new file mode 100644
index 000000000..5b288430a
--- /dev/null
+++ b/providers/alicloud/eci/delete_container_group.go
@@ -0,0 +1,107 @@
+package eci
+
+//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"
+)
+
+// DeleteContainerGroup invokes the eci.DeleteContainerGroup API synchronously
+// api document: https://help.aliyun.com/api/eci/deletecontainergroup.html
+func (client *Client) DeleteContainerGroup(request *DeleteContainerGroupRequest) (response *DeleteContainerGroupResponse, err error) {
+ response = CreateDeleteContainerGroupResponse()
+ err = client.DoAction(request, response)
+ return
+}
+
+// DeleteContainerGroupWithChan invokes the eci.DeleteContainerGroup API asynchronously
+// api document: https://help.aliyun.com/api/eci/deletecontainergroup.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) DeleteContainerGroupWithChan(request *DeleteContainerGroupRequest) (<-chan *DeleteContainerGroupResponse, <-chan error) {
+ responseChan := make(chan *DeleteContainerGroupResponse, 1)
+ errChan := make(chan error, 1)
+ err := client.AddAsyncTask(func() {
+ defer close(responseChan)
+ defer close(errChan)
+ response, err := client.DeleteContainerGroup(request)
+ if err != nil {
+ errChan <- err
+ } else {
+ responseChan <- response
+ }
+ })
+ if err != nil {
+ errChan <- err
+ close(responseChan)
+ close(errChan)
+ }
+ return responseChan, errChan
+}
+
+// DeleteContainerGroupWithCallback invokes the eci.DeleteContainerGroup API asynchronously
+// api document: https://help.aliyun.com/api/eci/deletecontainergroup.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) DeleteContainerGroupWithCallback(request *DeleteContainerGroupRequest, callback func(response *DeleteContainerGroupResponse, err error)) <-chan int {
+ result := make(chan int, 1)
+ err := client.AddAsyncTask(func() {
+ var response *DeleteContainerGroupResponse
+ var err error
+ defer close(result)
+ response, err = client.DeleteContainerGroup(request)
+ callback(response, err)
+ result <- 1
+ })
+ if err != nil {
+ defer close(result)
+ callback(nil, err)
+ result <- 0
+ }
+ return result
+}
+
+// DeleteContainerGroupRequest is the request struct for api DeleteContainerGroup
+type DeleteContainerGroupRequest struct {
+ *requests.RpcRequest
+ ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
+ ContainerGroupId string `position:"Query" name:"ContainerGroupId"`
+ ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
+ OwnerAccount string `position:"Query" name:"OwnerAccount"`
+ OwnerId requests.Integer `position:"Query" name:"OwnerId"`
+}
+
+// DeleteContainerGroupResponse is the response struct for api DeleteContainerGroup
+type DeleteContainerGroupResponse struct {
+ *responses.BaseResponse
+ RequestId string `json:"RequestId" xml:"RequestId"`
+}
+
+// CreateDeleteContainerGroupRequest creates a request to invoke DeleteContainerGroup API
+func CreateDeleteContainerGroupRequest() (request *DeleteContainerGroupRequest) {
+ request = &DeleteContainerGroupRequest{
+ RpcRequest: &requests.RpcRequest{},
+ }
+ request.InitWithApiInfo("Eci", "2018-08-08", "DeleteContainerGroup", "eci", "openAPI")
+ return
+}
+
+// CreateDeleteContainerGroupResponse creates a response to parse from DeleteContainerGroup response
+func CreateDeleteContainerGroupResponse() (response *DeleteContainerGroupResponse) {
+ response = &DeleteContainerGroupResponse{
+ BaseResponse: &responses.BaseResponse{},
+ }
+ return
+}
diff --git a/providers/alicloud/eci/describe_container_groups.go b/providers/alicloud/eci/describe_container_groups.go
new file mode 100644
index 000000000..b4941c1b4
--- /dev/null
+++ b/providers/alicloud/eci/describe_container_groups.go
@@ -0,0 +1,122 @@
+package eci
+
+//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"
+)
+
+// DescribeContainerGroups invokes the eci.DescribeContainerGroups API synchronously
+// api document: https://help.aliyun.com/api/eci/describecontainergroups.html
+func (client *Client) DescribeContainerGroups(request *DescribeContainerGroupsRequest) (response *DescribeContainerGroupsResponse, err error) {
+ response = CreateDescribeContainerGroupsResponse()
+ err = client.DoAction(request, response)
+ return
+}
+
+// DescribeContainerGroupsWithChan invokes the eci.DescribeContainerGroups API asynchronously
+// api document: https://help.aliyun.com/api/eci/describecontainergroups.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) DescribeContainerGroupsWithChan(request *DescribeContainerGroupsRequest) (<-chan *DescribeContainerGroupsResponse, <-chan error) {
+ responseChan := make(chan *DescribeContainerGroupsResponse, 1)
+ errChan := make(chan error, 1)
+ err := client.AddAsyncTask(func() {
+ defer close(responseChan)
+ defer close(errChan)
+ response, err := client.DescribeContainerGroups(request)
+ if err != nil {
+ errChan <- err
+ } else {
+ responseChan <- response
+ }
+ })
+ if err != nil {
+ errChan <- err
+ close(responseChan)
+ close(errChan)
+ }
+ return responseChan, errChan
+}
+
+// DescribeContainerGroupsWithCallback invokes the eci.DescribeContainerGroups API asynchronously
+// api document: https://help.aliyun.com/api/eci/describecontainergroups.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) DescribeContainerGroupsWithCallback(request *DescribeContainerGroupsRequest, callback func(response *DescribeContainerGroupsResponse, err error)) <-chan int {
+ result := make(chan int, 1)
+ err := client.AddAsyncTask(func() {
+ var response *DescribeContainerGroupsResponse
+ var err error
+ defer close(result)
+ response, err = client.DescribeContainerGroups(request)
+ callback(response, err)
+ result <- 1
+ })
+ if err != nil {
+ defer close(result)
+ callback(nil, err)
+ result <- 0
+ }
+ return result
+}
+
+// DescribeContainerGroupsRequest is the request struct for api DescribeContainerGroups
+type DescribeContainerGroupsRequest struct {
+ *requests.RpcRequest
+ ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
+ NextToken string `position:"Query" name:"NextToken"`
+ Limit requests.Integer `position:"Query" name:"Limit"`
+ Tags *[]DescribeContainerGroupsTag `position:"Query" name:"Tag" type:"Repeated"`
+ ContainerGroupId string `position:"Query" name:"ContainerGroupId"`
+ 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"`
+ ContainerGroupName string `position:"Query" name:"ContainerGroupName"`
+ ZoneId string `position:"Query" name:"ZoneId"`
+}
+
+// DescribeContainerGroupsTag is a repeated param struct in DescribeContainerGroupsRequest
+type DescribeContainerGroupsTag struct {
+ Key string `name:"Key"`
+ Value string `name:"Value"`
+}
+
+// DescribeContainerGroupsResponse is the response struct for api DescribeContainerGroups
+type DescribeContainerGroupsResponse struct {
+ *responses.BaseResponse
+ RequestId string `json:"RequestId" xml:"RequestId"`
+ NextToken string `json:"NextToken" xml:"NextToken"`
+ TotalCount int `json:"TotalCount" xml:"TotalCount"`
+ ContainerGroups []ContainerGroup `json:"ContainerGroups" xml:"ContainerGroups"`
+}
+
+// CreateDescribeContainerGroupsRequest creates a request to invoke DescribeContainerGroups API
+func CreateDescribeContainerGroupsRequest() (request *DescribeContainerGroupsRequest) {
+ request = &DescribeContainerGroupsRequest{
+ RpcRequest: &requests.RpcRequest{},
+ }
+ request.InitWithApiInfo("Eci", "2018-08-08", "DescribeContainerGroups", "eci", "openAPI")
+ return
+}
+
+// CreateDescribeContainerGroupsResponse creates a response to parse from DescribeContainerGroups response
+func CreateDescribeContainerGroupsResponse() (response *DescribeContainerGroupsResponse) {
+ response = &DescribeContainerGroupsResponse{
+ BaseResponse: &responses.BaseResponse{},
+ }
+ return
+}
diff --git a/providers/alicloud/eci/describe_container_log.go b/providers/alicloud/eci/describe_container_log.go
new file mode 100644
index 000000000..07685685b
--- /dev/null
+++ b/providers/alicloud/eci/describe_container_log.go
@@ -0,0 +1,112 @@
+package eci
+
+//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"
+)
+
+// DescribeContainerLog invokes the eci.DescribeContainerLog API synchronously
+// api document: https://help.aliyun.com/api/eci/describecontainerlog.html
+func (client *Client) DescribeContainerLog(request *DescribeContainerLogRequest) (response *DescribeContainerLogResponse, err error) {
+ response = CreateDescribeContainerLogResponse()
+ err = client.DoAction(request, response)
+ return
+}
+
+// DescribeContainerLogWithChan invokes the eci.DescribeContainerLog API asynchronously
+// api document: https://help.aliyun.com/api/eci/describecontainerlog.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) DescribeContainerLogWithChan(request *DescribeContainerLogRequest) (<-chan *DescribeContainerLogResponse, <-chan error) {
+ responseChan := make(chan *DescribeContainerLogResponse, 1)
+ errChan := make(chan error, 1)
+ err := client.AddAsyncTask(func() {
+ defer close(responseChan)
+ defer close(errChan)
+ response, err := client.DescribeContainerLog(request)
+ if err != nil {
+ errChan <- err
+ } else {
+ responseChan <- response
+ }
+ })
+ if err != nil {
+ errChan <- err
+ close(responseChan)
+ close(errChan)
+ }
+ return responseChan, errChan
+}
+
+// DescribeContainerLogWithCallback invokes the eci.DescribeContainerLog API asynchronously
+// api document: https://help.aliyun.com/api/eci/describecontainerlog.html
+// asynchronous document: https://help.aliyun.com/document_detail/66220.html
+func (client *Client) DescribeContainerLogWithCallback(request *DescribeContainerLogRequest, callback func(response *DescribeContainerLogResponse, err error)) <-chan int {
+ result := make(chan int, 1)
+ err := client.AddAsyncTask(func() {
+ var response *DescribeContainerLogResponse
+ var err error
+ defer close(result)
+ response, err = client.DescribeContainerLog(request)
+ callback(response, err)
+ result <- 1
+ })
+ if err != nil {
+ defer close(result)
+ callback(nil, err)
+ result <- 0
+ }
+ return result
+}
+
+// DescribeContainerLogRequest is the request struct for api DescribeContainerLog
+type DescribeContainerLogRequest struct {
+ *requests.RpcRequest
+ ResourceOwnerId requests.Integer `position:"Query" name:"ResourceOwnerId"`
+ ContainerName string `position:"Query" name:"ContainerName"`
+ StartTime string `position:"Query" name:"StartTime"`
+ ContainerGroupId string `position:"Query" name:"ContainerGroupId"`
+ ResourceOwnerAccount string `position:"Query" name:"ResourceOwnerAccount"`
+ Tail requests.Integer `position:"Query" name:"Tail"`
+ OwnerAccount string `position:"Query" name:"OwnerAccount"`
+ OwnerId requests.Integer `position:"Query" name:"OwnerId"`
+}
+
+// DescribeContainerLogResponse is the response struct for api DescribeContainerLog
+type DescribeContainerLogResponse struct {
+ *responses.BaseResponse
+ RequestId string `json:"RequestId" xml:"RequestId"`
+ ContainerName string `json:"ContainerName" xml:"ContainerName"`
+ Content string `json:"Content" xml:"Content"`
+}
+
+// CreateDescribeContainerLogRequest creates a request to invoke DescribeContainerLog API
+func CreateDescribeContainerLogRequest() (request *DescribeContainerLogRequest) {
+ request = &DescribeContainerLogRequest{
+ RpcRequest: &requests.RpcRequest{},
+ }
+ request.InitWithApiInfo("Eci", "2018-08-08", "DescribeContainerLog", "eci", "openAPI")
+ return
+}
+
+// CreateDescribeContainerLogResponse creates a response to parse from DescribeContainerLog response
+func CreateDescribeContainerLogResponse() (response *DescribeContainerLogResponse) {
+ response = &DescribeContainerLogResponse{
+ BaseResponse: &responses.BaseResponse{},
+ }
+ return
+}
diff --git a/providers/alicloud/eci/struct_config_file_to_path.go b/providers/alicloud/eci/struct_config_file_to_path.go
new file mode 100644
index 000000000..de0679aed
--- /dev/null
+++ b/providers/alicloud/eci/struct_config_file_to_path.go
@@ -0,0 +1,22 @@
+package eci
+
+//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.
+
+// ConfigFileVolumeConfigFileToPath is a nested struct in eci response
+type ConfigFileToPath struct {
+ Content string `json:"Content" xml:"Content" position:"Query" name:"Content"`
+ Path string `json:"Path" xml:"Path" position:"Query" name:"Path"`
+}
diff --git a/providers/alicloud/eci/struct_container.go b/providers/alicloud/eci/struct_container.go
new file mode 100644
index 000000000..b71a61cfd
--- /dev/null
+++ b/providers/alicloud/eci/struct_container.go
@@ -0,0 +1,34 @@
+package eci
+
+//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.
+
+// Container is a nested struct in eci response
+type Container struct {
+ Name string `json:"Name" xml:"Name" position:"Query" name:"Name"`
+ Image string `json:"Image" xml:"Image" position:"Query" name:"Image"`
+ Memory float64 `json:"Memory" xml:"Memory" position:"Query" name:"Memory"`
+ Cpu float64 `json:"Cpu" xml:"Cpu" position:"Query" name:"Cpu" `
+ RestartCount int `json:"RestartCount" xml:"RestartCount"`
+ WorkingDir string `json:"WorkingDir" xml:"WorkingDir" position:"Query" name:"WorkingDir"`
+ ImagePullPolicy string `json:"ImagePullPolicy" xml:"ImagePullPolicy" position:"Query" name:"ImagePullPolicy"`
+ Commands []string `json:"Commands" xml:"Commands" position:"Query" name:"Command" type:"Repeated"`
+ Args []string `json:"Args" xml:"Args" position:"Query" name:"Arg" type:"Repeated"`
+ PreviousState ContainerState `json:"PreviousState" xml:"PreviousState"`
+ CurrentState ContainerState `json:"CurrentState" xml:"CurrentState"`
+ VolumeMounts []VolumeMount `json:"VolumeMounts" xml:"VolumeMounts" position:"Query" name:"VolumeMount" type:"Repeated"`
+ Ports []ContainerPort `json:"Ports" xml:"Ports" position:"Query" name:"Port" type:"Repeated"`
+ EnvironmentVars []EnvironmentVar `json:"EnvironmentVars" xml:"EnvironmentVars" position:"Query" name:"EnvironmentVar" type:"Repeated"`
+}
diff --git a/providers/alicloud/eci/struct_container_group.go b/providers/alicloud/eci/struct_container_group.go
new file mode 100644
index 000000000..e5c0f67fa
--- /dev/null
+++ b/providers/alicloud/eci/struct_container_group.go
@@ -0,0 +1,38 @@
+package eci
+
+//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.
+
+// ContainerGroup is a nested struct in eci response
+type ContainerGroup struct {
+ ContainerGroupId string `json:"ContainerGroupId" xml:"ContainerGroupId"`
+ ContainerGroupName string `json:"ContainerGroupName" xml:"ContainerGroupName"`
+ RegionId string `json:"RegionId" xml:"RegionId"`
+ ZoneId string `json:"ZoneId" xml:"ZoneId"`
+ Memory float64 `json:"Memory" xml:"Memory"`
+ Cpu float64 `json:"Cpu" xml:"Cpu"`
+ VSwitchId string `json:"VSwitchId" xml:"VSwitchId"`
+ SecurityGroupId string `json:"SecurityGroupId" xml:"SecurityGroupId"`
+ RestartPolicy string `json:"RestartPolicy" xml:"RestartPolicy"`
+ IntranetIp string `json:"IntranetIp" xml:"IntranetIp"`
+ Status string `json:"Status" xml:"Status"`
+ InternetIp string `json:"InternetIp" xml:"InternetIp"`
+ CreationTime string `json:"CreationTime" xml:"CreationTime"`
+ SucceededTime string `json:"SucceededTime" xml:"SucceededTime"`
+ Tags []Tag `json:"Tags" xml:"Tags"`
+ Events []Event `json:"Events" xml:"Events"`
+ Containers []Container `json:"Containers" xml:"Containers"`
+ Volumes []Volume `json:"Volumes" xml:"Volumes"`
+}
diff --git a/providers/alicloud/eci/struct_container_port.go b/providers/alicloud/eci/struct_container_port.go
new file mode 100644
index 000000000..28150db07
--- /dev/null
+++ b/providers/alicloud/eci/struct_container_port.go
@@ -0,0 +1,26 @@
+package eci
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+)
+
+//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.
+
+// ContainerPort is a nested struct in eci response
+type ContainerPort struct {
+ Port requests.Integer `json:"Port" xml:"Port" position:"Query" name:"Port"`
+ Protocol string `json:"Protocol" xml:"Protocol" position:"Query" name:"Protocol"`
+}
diff --git a/providers/alicloud/eci/struct_container_state.go b/providers/alicloud/eci/struct_container_state.go
new file mode 100644
index 000000000..64bf2743c
--- /dev/null
+++ b/providers/alicloud/eci/struct_container_state.go
@@ -0,0 +1,25 @@
+package eci
+
+//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.
+
+// CurrentState is a nested struct in eci response
+type ContainerState struct {
+ State string `json:"State" xml:"State"`
+ DetailStatus string `json:"DetailStatus" xml:"DetailStatus"`
+ ExitCode int `json:"ExitCode" xml:"ExitCode"`
+ StartTime string `json:"StartTime" xml:"StartTime"`
+ FinishTime string `json:"FinishTime" xml:"FinishTime"`
+}
diff --git a/providers/alicloud/eci/struct_environment_var.go b/providers/alicloud/eci/struct_environment_var.go
new file mode 100644
index 000000000..cc858f99d
--- /dev/null
+++ b/providers/alicloud/eci/struct_environment_var.go
@@ -0,0 +1,22 @@
+package eci
+
+//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.
+
+// EnvironmentVar is a nested struct in eci response
+type EnvironmentVar struct {
+ Key string `json:"Key" xml:"Key" position:"Query" name:"Key"`
+ Value string `json:"Value" xml:"Value" position:"Query" name:"Value"`
+}
diff --git a/providers/alicloud/eci/struct_event.go b/providers/alicloud/eci/struct_event.go
new file mode 100644
index 000000000..30afd70be
--- /dev/null
+++ b/providers/alicloud/eci/struct_event.go
@@ -0,0 +1,26 @@
+package eci
+
+//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.
+
+// Event is a nested struct in eci response
+type Event struct {
+ Count int `json:"Count" xml:"Count"`
+ Type string `json:"Type" xml:"Type"`
+ Name string `json:"Name" xml:"Name"`
+ Message string `json:"Message" xml:"Message"`
+ FirstTimestamp string `json:"FirstTimestamp" xml:"FirstTimestamp"`
+ LastTimestamp string `json:"LastTimestamp" xml:"LastTimestamp"`
+}
diff --git a/providers/alicloud/eci/struct_tag.go b/providers/alicloud/eci/struct_tag.go
new file mode 100644
index 000000000..dc828e32b
--- /dev/null
+++ b/providers/alicloud/eci/struct_tag.go
@@ -0,0 +1,22 @@
+package eci
+
+//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.
+
+// Label is a nested struct in eci response
+type Tag struct {
+ Key string `json:"Key" xml:"Key" position:"Query" name:"Key"`
+ Value string `json:"Value" xml:"Value" position:"Query" name:"Value"`
+}
diff --git a/providers/alicloud/eci/struct_volume.go b/providers/alicloud/eci/struct_volume.go
new file mode 100644
index 000000000..d9e844a26
--- /dev/null
+++ b/providers/alicloud/eci/struct_volume.go
@@ -0,0 +1,35 @@
+package eci
+
+import "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+
+//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.
+
+// Volume is a nested struct in eci response
+const (
+ VOL_TYPE_NFS = "NFSVolume"
+ VOL_TYPE_EMPTYDIR = "EmptyDirVolume"
+ VOL_TYPE_CONFIGFILEVOLUME = "ConfigFileVolume"
+)
+
+type Volume struct {
+ Type string `json:"Type" xml:"Type" position:"Query" name:"Type"`
+ Name string `json:"Name" xml:"Name" position:"Query" name:"Name"`
+ NfsVolumePath string `json:"NfsVolumePath" xml:"NfsVolumePath" position:"Query" name:"NFSVolume.Path"`
+ NfsVolumeServer string `json:"NfsVolumeServer" xml:"NfsVolumeServer" position:"Query" name:"NFSVolume.Server"`
+ NfsVolumeReadOnly requests.Boolean `json:"NfsVolumeReadOnly" xml:"NfsVolumeReadOnly" position:"Query" name:"NFSVolume.ReadOnly"`
+ EmptyDirVolumeEnable requests.Boolean `json:"EmptyDirVolumeEnable" xml:"EmptyDirVolumeEnable" position:"Query" name:"EmptyDirVolume.Enable"`
+ ConfigFileVolumeConfigFileToPaths []ConfigFileToPath `json:"ConfigFileVolumeConfigFileToPaths" xml:"ConfigFileVolume" position:"Query" name:"ConfigFileVolume.ConfigFileToPath" type:"Repeated"`
+}
diff --git a/providers/alicloud/eci/struct_volume_mount.go b/providers/alicloud/eci/struct_volume_mount.go
new file mode 100644
index 000000000..49c140cf7
--- /dev/null
+++ b/providers/alicloud/eci/struct_volume_mount.go
@@ -0,0 +1,25 @@
+package eci
+
+import "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+
+//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.
+
+// VolumeMount is a nested struct in eci response
+type VolumeMount struct {
+ MountPath string `json:"MountPath" xml:"MountPath" position:"Query" name:"MountPath"`
+ ReadOnly requests.Boolean `json:"ReadOnly" xml:"ReadOnly" position:"Query" name:"ReadOnly"`
+ Name string `json:"Name" xml:"Name" position:"Query" name:"Name"`
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go
new file mode 100644
index 000000000..7f20b7a40
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go
@@ -0,0 +1,18 @@
+/*
+ * 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 auth
+
+type Credential interface {
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go
new file mode 100644
index 000000000..68f822633
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go
@@ -0,0 +1,34 @@
+package credentials
+
+// Deprecated: Use AccessKeyCredential in this package instead.
+type BaseCredential struct {
+ AccessKeyId string
+ AccessKeySecret string
+}
+
+type AccessKeyCredential struct {
+ AccessKeyId string
+ AccessKeySecret string
+}
+
+// Deprecated: Use NewAccessKeyCredential in this package instead.
+func NewBaseCredential(accessKeyId, accessKeySecret string) *BaseCredential {
+ return &BaseCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ }
+}
+
+func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential {
+ return &AccessKeyCredential{
+ AccessKeyId: baseCred.AccessKeyId,
+ AccessKeySecret: baseCred.AccessKeySecret,
+ }
+}
+
+func NewAccessKeyCredential(accessKeyId, accessKeySecret string) *AccessKeyCredential {
+ return &AccessKeyCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go
new file mode 100644
index 000000000..1e1f73ae4
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go
@@ -0,0 +1,29 @@
+package credentials
+
+// Deprecated: Use EcsRamRoleCredential in this package instead.
+type StsRoleNameOnEcsCredential struct {
+ RoleName string
+}
+
+// Deprecated: Use NewEcsRamRoleCredential in this package instead.
+func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential {
+ return &StsRoleNameOnEcsCredential{
+ RoleName: roleName,
+ }
+}
+
+func (oldCred *StsRoleNameOnEcsCredential) ToEcsRamRoleCredential() *EcsRamRoleCredential {
+ return &EcsRamRoleCredential{
+ RoleName: oldCred.RoleName,
+ }
+}
+
+type EcsRamRoleCredential struct {
+ RoleName string
+}
+
+func NewEcsRamRoleCredential(roleName string) *EcsRamRoleCredential {
+ return &EcsRamRoleCredential{
+ RoleName: roleName,
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go
new file mode 100644
index 000000000..00d688eb8
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go
@@ -0,0 +1,15 @@
+package credentials
+
+type RsaKeyPairCredential struct {
+ PrivateKey string
+ PublicKeyId string
+ SessionExpiration int
+}
+
+func NewRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration int) *RsaKeyPairCredential {
+ return &RsaKeyPairCredential{
+ PrivateKey: privateKey,
+ PublicKeyId: publicKeyId,
+ SessionExpiration: sessionExpiration,
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go
new file mode 100644
index 000000000..554431ff0
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go
@@ -0,0 +1,15 @@
+package credentials
+
+type StsTokenCredential struct {
+ AccessKeyId string
+ AccessKeySecret string
+ AccessKeyStsToken string
+}
+
+func NewStsTokenCredential(accessKeyId, accessKeySecret, accessKeyStsToken string) *StsTokenCredential {
+ return &StsTokenCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ AccessKeyStsToken: accessKeyStsToken,
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go
new file mode 100644
index 000000000..7a9db75d2
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go
@@ -0,0 +1,49 @@
+package credentials
+
+// Deprecated: Use RamRoleArnCredential in this package instead.
+type StsRoleArnCredential struct {
+ AccessKeyId string
+ AccessKeySecret string
+ RoleArn string
+ RoleSessionName string
+ RoleSessionExpiration int
+}
+
+type RamRoleArnCredential struct {
+ AccessKeyId string
+ AccessKeySecret string
+ RoleArn string
+ RoleSessionName string
+ RoleSessionExpiration int
+}
+
+// Deprecated: Use RamRoleArnCredential in this package instead.
+func NewStsRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *StsRoleArnCredential {
+ return &StsRoleArnCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ RoleArn: roleArn,
+ RoleSessionName: roleSessionName,
+ RoleSessionExpiration: roleSessionExpiration,
+ }
+}
+
+func (oldCred *StsRoleArnCredential) ToRamRoleArnCredential() *RamRoleArnCredential {
+ return &RamRoleArnCredential{
+ AccessKeyId: oldCred.AccessKeyId,
+ AccessKeySecret: oldCred.AccessKeySecret,
+ RoleArn: oldCred.RoleArn,
+ RoleSessionName: oldCred.RoleSessionName,
+ RoleSessionExpiration: oldCred.RoleSessionExpiration,
+ }
+}
+
+func NewRamRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *RamRoleArnCredential {
+ return &RamRoleArnCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ RoleArn: roleArn,
+ RoleSessionName: roleSessionName,
+ RoleSessionExpiration: roleSessionExpiration,
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go
new file mode 100644
index 000000000..8666dd064
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go
@@ -0,0 +1,121 @@
+/*
+ * 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 auth
+
+import (
+ "bytes"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
+ "sort"
+ "strings"
+)
+
+func signRoaRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) {
+ completeROASignParams(request, signer, regionId)
+ stringToSign := buildRoaStringToSign(request)
+ request.SetStringToSign(stringToSign)
+ signature := signer.Sign(stringToSign, "")
+ accessKeyId, err := signer.GetAccessKeyId()
+ if err != nil {
+ return nil
+ }
+
+ request.GetHeaders()["Authorization"] = "acs " + accessKeyId + ":" + signature
+
+ return
+}
+
+func completeROASignParams(request requests.AcsRequest, signer Signer, regionId string) {
+ headerParams := request.GetHeaders()
+
+ // complete query params
+ queryParams := request.GetQueryParams()
+ //if _, ok := queryParams["RegionId"]; !ok {
+ // queryParams["RegionId"] = regionId
+ //}
+ if extraParam := signer.GetExtraParam(); extraParam != nil {
+ for key, value := range extraParam {
+ if key == "SecurityToken" {
+ headerParams["x-acs-security-token"] = value
+ continue
+ }
+
+ queryParams[key] = value
+ }
+ }
+
+ // complete header params
+ headerParams["Date"] = utils.GetTimeInFormatRFC2616()
+ headerParams["x-acs-signature-method"] = signer.GetName()
+ headerParams["x-acs-signature-version"] = signer.GetVersion()
+ if request.GetFormParams() != nil && len(request.GetFormParams()) > 0 {
+ formString := utils.GetUrlFormedMap(request.GetFormParams())
+ request.SetContent([]byte(formString))
+ headerParams["Content-Type"] = requests.Form
+ }
+ contentMD5 := utils.GetMD5Base64(request.GetContent())
+ headerParams["Content-MD5"] = contentMD5
+ if _, contains := headerParams["Content-Type"]; !contains {
+ headerParams["Content-Type"] = requests.Raw
+ }
+ switch format := request.GetAcceptFormat(); format {
+ case "JSON":
+ headerParams["Accept"] = requests.Json
+ case "XML":
+ headerParams["Accept"] = requests.Xml
+ default:
+ headerParams["Accept"] = requests.Raw
+ }
+}
+
+func buildRoaStringToSign(request requests.AcsRequest) (stringToSign string) {
+
+ headers := request.GetHeaders()
+
+ stringToSignBuilder := bytes.Buffer{}
+ stringToSignBuilder.WriteString(request.GetMethod())
+ stringToSignBuilder.WriteString(requests.HeaderSeparator)
+
+ // append header keys for sign
+ appendIfContain(headers, &stringToSignBuilder, "Accept", requests.HeaderSeparator)
+ appendIfContain(headers, &stringToSignBuilder, "Content-MD5", requests.HeaderSeparator)
+ appendIfContain(headers, &stringToSignBuilder, "Content-Type", requests.HeaderSeparator)
+ appendIfContain(headers, &stringToSignBuilder, "Date", requests.HeaderSeparator)
+
+ // sort and append headers witch starts with 'x-acs-'
+ var acsHeaders []string
+ for key := range headers {
+ if strings.HasPrefix(key, "x-acs-") {
+ acsHeaders = append(acsHeaders, key)
+ }
+ }
+ sort.Strings(acsHeaders)
+ for _, key := range acsHeaders {
+ stringToSignBuilder.WriteString(key + ":" + headers[key])
+ stringToSignBuilder.WriteString(requests.HeaderSeparator)
+ }
+
+ // append query params
+ stringToSignBuilder.WriteString(request.BuildQueries())
+ stringToSign = stringToSignBuilder.String()
+ return
+}
+
+func appendIfContain(sourceMap map[string]string, target *bytes.Buffer, key, separator string) {
+ if value, contain := sourceMap[key]; contain && len(value) > 0 {
+ target.WriteString(sourceMap[key])
+ target.WriteString(separator)
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go
new file mode 100644
index 000000000..0c6f6d111
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go
@@ -0,0 +1,96 @@
+/*
+ * 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 auth
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
+ "net/url"
+ "sort"
+ "strings"
+)
+
+func signRpcRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) {
+ err = completeRpcSignParams(request, signer, regionId)
+ if err != nil {
+ return
+ }
+ // remove while retry
+ if _, containsSign := request.GetQueryParams()["Signature"]; containsSign {
+ delete(request.GetQueryParams(), "Signature")
+ }
+ stringToSign := buildRpcStringToSign(request)
+ request.SetStringToSign(stringToSign)
+ signature := signer.Sign(stringToSign, "&")
+ request.GetQueryParams()["Signature"] = signature
+
+ return
+}
+
+func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId string) (err error) {
+ queryParams := request.GetQueryParams()
+ queryParams["Version"] = request.GetVersion()
+ queryParams["Action"] = request.GetActionName()
+ queryParams["Format"] = request.GetAcceptFormat()
+ queryParams["Timestamp"] = utils.GetTimeInFormatISO8601()
+ queryParams["SignatureMethod"] = signer.GetName()
+ queryParams["SignatureType"] = signer.GetType()
+ queryParams["SignatureVersion"] = signer.GetVersion()
+ queryParams["SignatureNonce"] = utils.GetUUIDV4()
+ queryParams["AccessKeyId"], err = signer.GetAccessKeyId()
+
+ if err != nil {
+ return
+ }
+
+ if _, contains := queryParams["RegionId"]; !contains {
+ queryParams["RegionId"] = regionId
+ }
+ if extraParam := signer.GetExtraParam(); extraParam != nil {
+ for key, value := range extraParam {
+ queryParams[key] = value
+ }
+ }
+
+ request.GetHeaders()["Content-Type"] = requests.Form
+ formString := utils.GetUrlFormedMap(request.GetFormParams())
+ request.SetContent([]byte(formString))
+
+ return
+}
+
+func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) {
+ signParams := make(map[string]string)
+ for key, value := range request.GetQueryParams() {
+ signParams[key] = value
+ }
+ for key, value := range request.GetFormParams() {
+ signParams[key] = value
+ }
+
+ // sort params by key
+ var paramKeySlice []string
+ for key := range signParams {
+ paramKeySlice = append(paramKeySlice, key)
+ }
+ sort.Strings(paramKeySlice)
+ stringToSign = utils.GetUrlFormedMap(signParams)
+ stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
+ stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
+ stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
+ stringToSign = url.QueryEscape(stringToSign)
+ stringToSign = request.GetMethod() + "&%2F&" + stringToSign
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go
new file mode 100644
index 000000000..ba946d0fd
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go
@@ -0,0 +1,95 @@
+/*
+ * 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 auth
+
+import (
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "reflect"
+)
+
+type Signer interface {
+ GetName() string
+ GetType() string
+ GetVersion() string
+ GetAccessKeyId() (string, error)
+ GetExtraParam() map[string]string
+ Sign(stringToSign, secretSuffix string) string
+ Shutdown()
+}
+
+func NewSignerWithCredential(credential Credential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer Signer, err error) {
+ switch instance := credential.(type) {
+ case *credentials.AccessKeyCredential:
+ {
+ signer, err = signers.NewAccessKeySigner(instance)
+ }
+ case *credentials.StsTokenCredential:
+ {
+ signer, err = signers.NewStsTokenSigner(instance)
+ }
+
+ case *credentials.RamRoleArnCredential:
+ {
+ signer, err = signers.NewRamRoleArnSigner(instance, commonApi)
+ }
+ case *credentials.RsaKeyPairCredential:
+ {
+ signer, err = signers.NewSignerKeyPair(instance, commonApi)
+ }
+ case *credentials.EcsRamRoleCredential:
+ {
+ signer, err = signers.NewEcsRamRoleSigner(instance, commonApi)
+ }
+ case *credentials.BaseCredential: // deprecated user interface
+ {
+ signer, err = signers.NewAccessKeySigner(instance.ToAccessKeyCredential())
+ }
+ case *credentials.StsRoleArnCredential: // deprecated user interface
+ {
+ signer, err = signers.NewRamRoleArnSigner(instance.ToRamRoleArnCredential(), commonApi)
+ }
+ case *credentials.StsRoleNameOnEcsCredential: // deprecated user interface
+ {
+ signer, err = signers.NewEcsRamRoleSigner(instance.ToEcsRamRoleCredential(), commonApi)
+ }
+ default:
+ message := fmt.Sprintf(errors.UnsupportedCredentialErrorMessage, reflect.TypeOf(credential))
+ err = errors.NewClientError(errors.UnsupportedCredentialErrorCode, message, nil)
+ }
+ return
+}
+
+func Sign(request requests.AcsRequest, signer Signer, regionId string) (err error) {
+ switch request.GetStyle() {
+ case requests.ROA:
+ {
+ signRoaRequest(request, signer, regionId)
+ }
+ case requests.RPC:
+ {
+ err = signRpcRequest(request, signer, regionId)
+ }
+ default:
+ message := fmt.Sprintf(errors.UnknownRequestTypeErrorMessage, reflect.TypeOf(request))
+ err = errors.NewClientError(errors.UnknownRequestTypeErrorCode, message, nil)
+ }
+
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go
new file mode 100644
index 000000000..975e985b9
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go
@@ -0,0 +1,63 @@
+/*
+ * 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 signers
+
+import (
+ "crypto"
+ "crypto/hmac"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/x509"
+ "encoding/base64"
+ "fmt"
+ /*"encoding/pem"
+ "io/ioutil"
+ "os/user"
+ "crypto/sha256"*/)
+
+func ShaHmac1(source, secret string) string {
+ key := []byte(secret)
+ hmac := hmac.New(sha1.New, key)
+ hmac.Write([]byte(source))
+ signedBytes := hmac.Sum(nil)
+ signedString := base64.StdEncoding.EncodeToString(signedBytes)
+ return signedString
+}
+
+func Sha256WithRsa(source, secret string) string {
+ decodeString, err := base64.StdEncoding.DecodeString(secret)
+ if err != nil {
+ fmt.Println("DecodeString err", err)
+ }
+ private, err := x509.ParsePKCS8PrivateKey(decodeString)
+ if err != nil {
+ fmt.Println("ParsePKCS8PrivateKey err", err)
+ }
+
+ h := crypto.Hash.New(crypto.SHA256)
+ h.Write([]byte(source))
+ hashed := h.Sum(nil)
+ signature, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey),
+ crypto.SHA256, hashed)
+ if err != nil {
+ fmt.Println("Error from signing:", err)
+ return ""
+ }
+
+ signedString := base64.StdEncoding.EncodeToString(signature)
+ //fmt.Printf("Encoded: %v\n", signedString)
+ return signedString
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go
new file mode 100644
index 000000000..bb73d2441
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go
@@ -0,0 +1,53 @@
+/*
+ * 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 signers
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "time"
+)
+
+const defaultInAdvanceScale = 0.8
+
+type credentialUpdater struct {
+ credentialExpiration int
+ lastUpdateTimestamp int64
+ inAdvanceScale float64
+ buildRequestMethod func() (*requests.CommonRequest, error)
+ responseCallBack func(response *responses.CommonResponse) error
+ refreshApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error)
+}
+
+func (updater *credentialUpdater) needUpdateCredential() (result bool) {
+ if updater.inAdvanceScale == 0 {
+ updater.inAdvanceScale = defaultInAdvanceScale
+ }
+ return time.Now().Unix()-updater.lastUpdateTimestamp >= int64(float64(updater.credentialExpiration)*updater.inAdvanceScale)
+}
+
+func (updater *credentialUpdater) updateCredential() (err error) {
+ request, err := updater.buildRequestMethod()
+ if err != nil {
+ return
+ }
+ response, err := updater.refreshApi(request)
+ if err != nil {
+ return
+ }
+ updater.lastUpdateTimestamp = time.Now().Unix()
+ err = updater.responseCallBack(response)
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go
new file mode 100644
index 000000000..99c624c88
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go
@@ -0,0 +1,7 @@
+package signers
+
+type SessionCredential struct {
+ AccessKeyId string
+ AccessKeySecret string
+ StsToken string
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go
new file mode 100644
index 000000000..92466ea55
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go
@@ -0,0 +1,58 @@
+/*
+ * 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 signers
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+)
+
+type AccessKeySigner struct {
+ credential *credentials.AccessKeyCredential
+}
+
+func (signer *AccessKeySigner) GetExtraParam() map[string]string {
+ return nil
+}
+
+func NewAccessKeySigner(credential *credentials.AccessKeyCredential) (*AccessKeySigner, error) {
+ return &AccessKeySigner{
+ credential: credential,
+ }, nil
+}
+
+func (*AccessKeySigner) GetName() string {
+ return "HMAC-SHA1"
+}
+
+func (*AccessKeySigner) GetType() string {
+ return ""
+}
+
+func (*AccessKeySigner) GetVersion() string {
+ return "1.0"
+}
+
+func (signer *AccessKeySigner) GetAccessKeyId() (accessKeyId string, err error) {
+ return signer.credential.AccessKeyId, nil
+}
+
+func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string {
+ secret := signer.credential.AccessKeySecret + secretSuffix
+ return ShaHmac1(stringToSign, secret)
+}
+
+func (signer *AccessKeySigner) Shutdown() {
+
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go
new file mode 100644
index 000000000..6cacc140d
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go
@@ -0,0 +1,175 @@
+/*
+ * 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 signers
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "github.com/jmespath/go-jmespath"
+ "net/http"
+ "strings"
+ "time"
+)
+
+type EcsRamRoleSigner struct {
+ *credentialUpdater
+ sessionCredential *SessionCredential
+ credential *credentials.EcsRamRoleCredential
+ commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
+}
+
+func NewEcsRamRoleSigner(credential *credentials.EcsRamRoleCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *EcsRamRoleSigner, err error) {
+ signer = &EcsRamRoleSigner{
+ credential: credential,
+ commonApi: commonApi,
+ }
+
+ signer.credentialUpdater = &credentialUpdater{
+ credentialExpiration: defaultDurationSeconds / 60,
+ buildRequestMethod: signer.buildCommonRequest,
+ responseCallBack: signer.refreshCredential,
+ refreshApi: signer.refreshApi,
+ }
+
+ return
+}
+
+func (*EcsRamRoleSigner) GetName() string {
+ return "HMAC-SHA1"
+}
+
+func (*EcsRamRoleSigner) GetType() string {
+ return ""
+}
+
+func (*EcsRamRoleSigner) GetVersion() string {
+ return "1.0"
+}
+
+func (signer *EcsRamRoleSigner) GetAccessKeyId() (accessKeyId string, err error) {
+ if signer.sessionCredential == nil || signer.needUpdateCredential() {
+ err = signer.updateCredential()
+ }
+ if err != nil && (signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0) {
+ return "", err
+ }
+ return signer.sessionCredential.AccessKeyId, nil
+}
+
+func (signer *EcsRamRoleSigner) GetExtraParam() map[string]string {
+ if signer.sessionCredential == nil {
+ return make(map[string]string)
+ }
+ if len(signer.sessionCredential.StsToken) <= 0 {
+ return make(map[string]string)
+ }
+ return map[string]string{"SecurityToken": signer.sessionCredential.StsToken}
+}
+
+func (signer *EcsRamRoleSigner) Sign(stringToSign, secretSuffix string) string {
+ secret := signer.sessionCredential.AccessKeyId + secretSuffix
+ return ShaHmac1(stringToSign, secret)
+}
+
+func (signer *EcsRamRoleSigner) buildCommonRequest() (request *requests.CommonRequest, err error) {
+ request = requests.NewCommonRequest()
+ return
+}
+
+func (signer *EcsRamRoleSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
+ requestUrl := "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + signer.credential.RoleName
+ httpRequest, err := http.NewRequest(requests.GET, requestUrl, strings.NewReader(""))
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err", err)
+ return
+ }
+ httpClient := &http.Client{}
+ httpResponse, err := httpClient.Do(httpRequest)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err", err)
+ return
+ }
+
+ response = responses.NewCommonResponse()
+ err = responses.Unmarshal(response, httpResponse, "")
+
+ return
+}
+
+func (signer *EcsRamRoleSigner) refreshCredential(response *responses.CommonResponse) (err error) {
+ if response.GetHttpStatus() != http.StatusOK {
+ fmt.Println("refresh Ecs sts token err, httpStatus: " + string(response.GetHttpStatus()) + ", message = " + response.GetHttpContentString())
+ return
+ }
+ var data interface{}
+ err = json.Unmarshal(response.GetHttpContentBytes(), &data)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err, json.Unmarshal fail", err)
+ return
+ }
+ code, err := jmespath.Search("Code", data)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err, fail to get Code", err)
+ return
+ }
+ if code.(string) != "Success" {
+ fmt.Println("refresh Ecs sts token err, Code is not Success", err)
+ return
+ }
+ accessKeyId, err := jmespath.Search("AccessKeyId", data)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err, fail to get AccessKeyId", err)
+ return
+ }
+ accessKeySecret, err := jmespath.Search("AccessKeySecret", data)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err, fail to get AccessKeySecret", err)
+ return
+ }
+ securityToken, err := jmespath.Search("SecurityToken", data)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err, fail to get SecurityToken", err)
+ return
+ }
+ expiration, err := jmespath.Search("Expiration", data)
+ if err != nil {
+ fmt.Println("refresh Ecs sts token err, fail to get Expiration", err)
+ return
+ }
+ if accessKeyId == nil || accessKeySecret == nil || securityToken == nil {
+ return
+ }
+
+ expirationTime, err := time.Parse("2006-01-02T15:04:05Z", expiration.(string))
+ signer.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix())
+ signer.sessionCredential = &SessionCredential{
+ AccessKeyId: accessKeyId.(string),
+ AccessKeySecret: accessKeySecret.(string),
+ StsToken: securityToken.(string),
+ }
+
+ return
+}
+
+func (signer *EcsRamRoleSigner) GetSessionCredential() *SessionCredential {
+ return signer.sessionCredential
+}
+
+func (signer *EcsRamRoleSigner) Shutdown() {
+
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go
new file mode 100644
index 000000000..c5fe39456
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go
@@ -0,0 +1,148 @@
+/*
+ * 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 signers
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "github.com/jmespath/go-jmespath"
+ "net/http"
+ "strconv"
+)
+
+type SignerKeyPair struct {
+ *credentialUpdater
+ sessionCredential *SessionCredential
+ credential *credentials.RsaKeyPairCredential
+ commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
+}
+
+func NewSignerKeyPair(credential *credentials.RsaKeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) {
+ signer = &SignerKeyPair{
+ credential: credential,
+ commonApi: commonApi,
+ }
+
+ signer.credentialUpdater = &credentialUpdater{
+ credentialExpiration: credential.SessionExpiration,
+ buildRequestMethod: signer.buildCommonRequest,
+ responseCallBack: signer.refreshCredential,
+ refreshApi: signer.refreshApi,
+ }
+
+ if credential.SessionExpiration > 0 {
+ if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 {
+ signer.credentialExpiration = credential.SessionExpiration
+ } else {
+ err = errors.NewClientError(errors.InvalidParamErrorCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil)
+ }
+ } else {
+ signer.credentialExpiration = defaultDurationSeconds
+ }
+ return
+}
+
+func (*SignerKeyPair) GetName() string {
+ return "HMAC-SHA1"
+}
+
+func (*SignerKeyPair) GetType() string {
+ return ""
+}
+
+func (*SignerKeyPair) GetVersion() string {
+ return "1.0"
+}
+
+func (signer *SignerKeyPair) GetAccessKeyId() (accessKeyId string, err error) {
+ if signer.sessionCredential == nil || signer.needUpdateCredential() {
+ err = signer.updateCredential()
+ }
+ if err != nil && (signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0) {
+ return "", err
+ }
+ return signer.sessionCredential.AccessKeyId, err
+}
+
+func (signer *SignerKeyPair) GetExtraParam() map[string]string {
+ if signer.sessionCredential == nil || signer.needUpdateCredential() {
+ signer.updateCredential()
+ }
+ if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 {
+ return make(map[string]string)
+ }
+ return make(map[string]string)
+}
+
+func (signer *SignerKeyPair) Sign(stringToSign, secretSuffix string) string {
+ secret := signer.sessionCredential.AccessKeyId + secretSuffix
+ return ShaHmac1(stringToSign, secret)
+}
+
+func (signer *SignerKeyPair) buildCommonRequest() (request *requests.CommonRequest, err error) {
+ request = requests.NewCommonRequest()
+ request.Product = "Sts"
+ request.Version = "2015-04-01"
+ request.ApiName = "GenerateSessionAccessKey"
+ request.Scheme = requests.HTTPS
+ request.QueryParams["PublicKeyId"] = signer.credential.PublicKeyId
+ request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration)
+ return
+}
+
+func (signerKeyPair *SignerKeyPair) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
+ signerV2, err := NewSignerV2(signerKeyPair.credential)
+ return signerKeyPair.commonApi(request, signerV2)
+}
+
+func (signer *SignerKeyPair) refreshCredential(response *responses.CommonResponse) (err error) {
+ if response.GetHttpStatus() != http.StatusOK {
+ message := "refresh session AccessKey failed"
+ err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message)
+ return
+ }
+ var data interface{}
+ err = json.Unmarshal(response.GetHttpContentBytes(), &data)
+ if err != nil {
+ fmt.Println("refresh KeyPair err, json.Unmarshal fail", err)
+ return
+ }
+ accessKeyId, err := jmespath.Search("SessionAccessKey.SessionAccessKeyId", data)
+ if err != nil {
+ fmt.Println("refresh KeyPair err, fail to get SessionAccessKeyId", err)
+ return
+ }
+ accessKeySecret, err := jmespath.Search("SessionAccessKey.SessionAccessKeySecret", data)
+ if err != nil {
+ fmt.Println("refresh KeyPair err, fail to get SessionAccessKeySecret", err)
+ return
+ }
+ if accessKeyId == nil || accessKeySecret == nil {
+ return
+ }
+ signer.sessionCredential = &SessionCredential{
+ AccessKeyId: accessKeyId.(string),
+ AccessKeySecret: accessKeySecret.(string),
+ }
+ return
+}
+
+func (signer *SignerKeyPair) Shutdown() {
+
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go
new file mode 100644
index 000000000..bfcaa9573
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go
@@ -0,0 +1,174 @@
+/*
+ * 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 signers
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "github.com/jmespath/go-jmespath"
+ "net/http"
+ "strconv"
+ "time"
+)
+
+const (
+ defaultDurationSeconds = 3600
+)
+
+type RamRoleArnSigner struct {
+ *credentialUpdater
+ roleSessionName string
+ sessionCredential *SessionCredential
+ credential *credentials.RamRoleArnCredential
+ commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
+}
+
+func NewRamRoleArnSigner(credential *credentials.RamRoleArnCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *RamRoleArnSigner, err error) {
+ signer = &RamRoleArnSigner{
+ credential: credential,
+ commonApi: commonApi,
+ }
+
+ signer.credentialUpdater = &credentialUpdater{
+ credentialExpiration: credential.RoleSessionExpiration,
+ buildRequestMethod: signer.buildCommonRequest,
+ responseCallBack: signer.refreshCredential,
+ refreshApi: signer.refreshApi,
+ }
+
+ if len(credential.RoleSessionName) > 0 {
+ signer.roleSessionName = credential.RoleSessionName
+ } else {
+ signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
+ }
+ if credential.RoleSessionExpiration > 0 {
+ if credential.RoleSessionExpiration >= 900 && credential.RoleSessionExpiration <= 3600 {
+ signer.credentialExpiration = credential.RoleSessionExpiration
+ } else {
+ err = errors.NewClientError(errors.InvalidParamErrorCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil)
+ }
+ } else {
+ signer.credentialExpiration = defaultDurationSeconds
+ }
+ return
+}
+
+func (*RamRoleArnSigner) GetName() string {
+ return "HMAC-SHA1"
+}
+
+func (*RamRoleArnSigner) GetType() string {
+ return ""
+}
+
+func (*RamRoleArnSigner) GetVersion() string {
+ return "1.0"
+}
+
+func (signer *RamRoleArnSigner) GetAccessKeyId() (accessKeyId string, err error) {
+ if signer.sessionCredential == nil || signer.needUpdateCredential() {
+ err = signer.updateCredential()
+ }
+ if err != nil && (signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0) {
+ return "", err
+ }
+ return signer.sessionCredential.AccessKeyId, nil
+}
+
+func (signer *RamRoleArnSigner) GetExtraParam() map[string]string {
+ if signer.sessionCredential == nil || signer.needUpdateCredential() {
+ signer.updateCredential()
+ }
+ if signer.sessionCredential == nil || len(signer.sessionCredential.StsToken) <= 0 {
+ return make(map[string]string)
+ }
+ return map[string]string{"SecurityToken": signer.sessionCredential.StsToken}
+}
+
+func (signer *RamRoleArnSigner) Sign(stringToSign, secretSuffix string) string {
+ secret := signer.sessionCredential.AccessKeySecret + secretSuffix
+ return ShaHmac1(stringToSign, secret)
+}
+
+func (signer *RamRoleArnSigner) buildCommonRequest() (request *requests.CommonRequest, err error) {
+ request = requests.NewCommonRequest()
+ request.Product = "Sts"
+ request.Version = "2015-04-01"
+ request.ApiName = "AssumeRole"
+ request.Scheme = requests.HTTPS
+ request.QueryParams["RoleArn"] = signer.credential.RoleArn
+ request.QueryParams["RoleSessionName"] = signer.credential.RoleSessionName
+ request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration)
+ return
+}
+
+func (signer *RamRoleArnSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
+ credential := &credentials.AccessKeyCredential{
+ AccessKeyId: signer.credential.AccessKeyId,
+ AccessKeySecret: signer.credential.AccessKeySecret,
+ }
+ signerV1, err := NewAccessKeySigner(credential)
+ return signer.commonApi(request, signerV1)
+}
+
+func (signer *RamRoleArnSigner) refreshCredential(response *responses.CommonResponse) (err error) {
+ if response.GetHttpStatus() != http.StatusOK {
+ message := "refresh session token failed"
+ err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message)
+ return
+ }
+ var data interface{}
+ err = json.Unmarshal(response.GetHttpContentBytes(), &data)
+ if err != nil {
+ fmt.Println("refresh RoleArn sts token err, json.Unmarshal fail", err)
+ return
+ }
+ accessKeyId, err := jmespath.Search("Credentials.AccessKeyId", data)
+ if err != nil {
+ fmt.Println("refresh RoleArn sts token err, fail to get AccessKeyId", err)
+ return
+ }
+ accessKeySecret, err := jmespath.Search("Credentials.AccessKeySecret", data)
+ if err != nil {
+ fmt.Println("refresh RoleArn sts token err, fail to get AccessKeySecret", err)
+ return
+ }
+ securityToken, err := jmespath.Search("Credentials.SecurityToken", data)
+ if err != nil {
+ fmt.Println("refresh RoleArn sts token err, fail to get SecurityToken", err)
+ return
+ }
+ if accessKeyId == nil || accessKeySecret == nil || securityToken == nil {
+ return
+ }
+ signer.sessionCredential = &SessionCredential{
+ AccessKeyId: accessKeyId.(string),
+ AccessKeySecret: accessKeySecret.(string),
+ StsToken: securityToken.(string),
+ }
+ return
+}
+
+func (signer *RamRoleArnSigner) GetSessionCredential() *SessionCredential {
+ return signer.sessionCredential
+}
+
+func (signer *RamRoleArnSigner) Shutdown() {
+
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go
new file mode 100644
index 000000000..9e178d0fb
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go
@@ -0,0 +1,58 @@
+/*
+ * 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 signers
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+)
+
+type StsTokenSigner struct {
+ credential *credentials.StsTokenCredential
+}
+
+func NewStsTokenSigner(credential *credentials.StsTokenCredential) (*StsTokenSigner, error) {
+ return &StsTokenSigner{
+ credential: credential,
+ }, nil
+}
+
+func (*StsTokenSigner) GetName() string {
+ return "HMAC-SHA1"
+}
+
+func (*StsTokenSigner) GetType() string {
+ return ""
+}
+
+func (*StsTokenSigner) GetVersion() string {
+ return "1.0"
+}
+
+func (signer *StsTokenSigner) GetAccessKeyId() (accessKeyId string, err error) {
+ return signer.credential.AccessKeyId, nil
+}
+
+func (signer *StsTokenSigner) GetExtraParam() map[string]string {
+ return map[string]string{"SecurityToken": signer.credential.AccessKeyStsToken}
+}
+
+func (signer *StsTokenSigner) Sign(stringToSign, secretSuffix string) string {
+ secret := signer.credential.AccessKeySecret + secretSuffix
+ return ShaHmac1(stringToSign, secret)
+}
+
+func (signer *StsTokenSigner) Shutdown() {
+
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go
new file mode 100644
index 000000000..1814fe7bd
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go
@@ -0,0 +1,58 @@
+/*
+ * 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 signers
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+)
+
+type SignerV2 struct {
+ credential *credentials.RsaKeyPairCredential
+}
+
+func (signer *SignerV2) GetExtraParam() map[string]string {
+ return nil
+}
+
+func NewSignerV2(credential *credentials.RsaKeyPairCredential) (*SignerV2, error) {
+ return &SignerV2{
+ credential: credential,
+ }, nil
+}
+
+func (*SignerV2) GetName() string {
+ return "SHA256withRSA"
+}
+
+func (*SignerV2) GetType() string {
+ return "PRIVATEKEY"
+}
+
+func (*SignerV2) GetVersion() string {
+ return "1.0"
+}
+
+func (signer *SignerV2) GetAccessKeyId() (accessKeyId string, err error) {
+ return signer.credential.PublicKeyId, err
+}
+
+func (signer *SignerV2) Sign(stringToSign, secretSuffix string) string {
+ secret := signer.credential.PrivateKey
+ return Sha256WithRsa(stringToSign, secret)
+}
+
+func (signer *SignerV2) Shutdown() {
+
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go
new file mode 100644
index 000000000..e204676ba
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go
@@ -0,0 +1,419 @@
+/*
+ * 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 sdk
+
+import (
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "net"
+ "net/http"
+ "strconv"
+ "sync"
+)
+
+// this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
+var Version = "0.0.1"
+
+type Client struct {
+ regionId string
+ config *Config
+ signer auth.Signer
+ httpClient *http.Client
+ asyncTaskQueue chan func()
+
+ debug bool
+ isRunning bool
+ // void "panic(write to close channel)" cause of addAsync() after Shutdown()
+ asyncChanLock *sync.RWMutex
+}
+
+func (client *Client) Init() (err error) {
+ panic("not support yet")
+}
+
+func (client *Client) InitWithOptions(regionId string, config *Config, credential auth.Credential) (err error) {
+ client.isRunning = true
+ client.asyncChanLock = new(sync.RWMutex)
+ client.regionId = regionId
+ client.config = config
+ if err != nil {
+ return
+ }
+ client.httpClient = &http.Client{}
+
+ if config.HttpTransport != nil {
+ client.httpClient.Transport = config.HttpTransport
+ }
+
+ if config.Timeout > 0 {
+ client.httpClient.Timeout = config.Timeout
+ }
+
+ if config.EnableAsync {
+ client.EnableAsync(config.GoRoutinePoolSize, config.MaxTaskQueueSize)
+ }
+
+ client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner)
+
+ return
+}
+
+func (client *Client) EnableAsync(routinePoolSize, maxTaskQueueSize int) {
+ client.asyncTaskQueue = make(chan func(), maxTaskQueueSize)
+ for i := 0; i < routinePoolSize; i++ {
+ go func() {
+ for client.isRunning {
+ select {
+ case task, notClosed := <-client.asyncTaskQueue:
+ if notClosed {
+ task()
+ }
+ }
+ }
+ }()
+ }
+}
+
+func (client *Client) InitWithAccessKey(regionId, accessKeyId, accessKeySecret string) (err error) {
+ config := client.InitClientConfig()
+ credential := &credentials.BaseCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ }
+ return client.InitWithOptions(regionId, config, credential)
+}
+
+func (client *Client) InitWithStsToken(regionId, accessKeyId, accessKeySecret, securityToken string) (err error) {
+ config := client.InitClientConfig()
+ credential := &credentials.StsTokenCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ AccessKeyStsToken: securityToken,
+ }
+ return client.InitWithOptions(regionId, config, credential)
+}
+
+func (client *Client) InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (err error) {
+ config := client.InitClientConfig()
+ credential := &credentials.RamRoleArnCredential{
+ AccessKeyId: accessKeyId,
+ AccessKeySecret: accessKeySecret,
+ RoleArn: roleArn,
+ RoleSessionName: roleSessionName,
+ }
+ return client.InitWithOptions(regionId, config, credential)
+}
+
+func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
+ config := client.InitClientConfig()
+ credential := &credentials.RsaKeyPairCredential{
+ PrivateKey: privateKey,
+ PublicKeyId: publicKeyId,
+ SessionExpiration: sessionExpiration,
+ }
+ return client.InitWithOptions(regionId, config, credential)
+}
+
+func (client *Client) InitWithEcsRamRole(regionId, roleName string) (err error) {
+ config := client.InitClientConfig()
+ credential := &credentials.EcsRamRoleCredential{
+ RoleName: roleName,
+ }
+ return client.InitWithOptions(regionId, config, credential)
+}
+
+func (client *Client) InitClientConfig() (config *Config) {
+ if client.config != nil {
+ return client.config
+ } else {
+ return NewConfig()
+ }
+}
+
+func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) {
+ return client.DoActionWithSigner(request, response, nil)
+}
+
+func (client *Client) BuildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (err error) {
+ // add clientVersion
+ request.GetHeaders()["x-sdk-core-version"] = Version
+
+ regionId := client.regionId
+ if len(request.GetRegionId()) > 0 {
+ regionId = request.GetRegionId()
+ }
+
+ // resolve endpoint
+ resolveParam := &endpoints.ResolveParam{
+ Domain: request.GetDomain(),
+ Product: request.GetProduct(),
+ RegionId: regionId,
+ LocationProduct: request.GetLocationServiceCode(),
+ LocationEndpointType: request.GetLocationEndpointType(),
+ CommonApi: client.ProcessCommonRequest,
+ }
+ endpoint, err := endpoints.Resolve(resolveParam)
+ if err != nil {
+ return
+ }
+ request.SetDomain(endpoint)
+
+ // init request params
+ err = requests.InitParams(request)
+ if err != nil {
+ return
+ }
+
+ // signature
+ var finalSigner auth.Signer
+ if signer != nil {
+ finalSigner = signer
+ } else {
+ finalSigner = client.signer
+ }
+ httpRequest, err := buildHttpRequest(request, finalSigner, regionId)
+ if client.config.UserAgent != "" {
+ httpRequest.Header.Set("User-Agent", client.config.UserAgent)
+ }
+ return err
+}
+
+func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) {
+
+ // add clientVersion
+ request.GetHeaders()["x-sdk-core-version"] = Version
+
+ regionId := client.regionId
+ if len(request.GetRegionId()) > 0 {
+ regionId = request.GetRegionId()
+ }
+
+ // resolve endpoint
+ resolveParam := &endpoints.ResolveParam{
+ Domain: request.GetDomain(),
+ Product: request.GetProduct(),
+ RegionId: regionId,
+ LocationProduct: request.GetLocationServiceCode(),
+ LocationEndpointType: request.GetLocationEndpointType(),
+ CommonApi: client.ProcessCommonRequest,
+ }
+ endpoint, err := endpoints.Resolve(resolveParam)
+ if err != nil {
+ return
+ }
+ request.SetDomain(endpoint)
+
+ if request.GetScheme() == "" {
+ request.SetScheme(client.config.Scheme)
+ }
+ // init request params
+ err = requests.InitParams(request)
+ if err != nil {
+ return
+ }
+
+ // signature
+ var finalSigner auth.Signer
+ if signer != nil {
+ finalSigner = signer
+ } else {
+ finalSigner = client.signer
+ }
+ httpRequest, err := buildHttpRequest(request, finalSigner, regionId)
+ if client.config.UserAgent != "" {
+ httpRequest.Header.Set("User-Agent", client.config.UserAgent)
+ }
+ if err != nil {
+ return
+ }
+ var httpResponse *http.Response
+ for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
+ httpResponse, err = client.httpClient.Do(httpRequest)
+
+ var timeout bool
+ // receive error
+ if err != nil {
+ if !client.config.AutoRetry {
+ return
+ } else if timeout = isTimeout(err); !timeout {
+ // if not timeout error, return
+ return
+ } else if retryTimes >= client.config.MaxRetryTime {
+ // timeout but reached the max retry times, return
+ timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, strconv.Itoa(retryTimes+1), strconv.Itoa(retryTimes+1))
+ err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err)
+ return
+ }
+ }
+ // if status code >= 500 or timeout, will trigger retry
+ if client.config.AutoRetry && (timeout || isServerError(httpResponse)) {
+ // rewrite signatureNonce and signature
+ httpRequest, err = buildHttpRequest(request, finalSigner, regionId)
+ if err != nil {
+ return
+ }
+ continue
+ }
+ break
+ }
+ err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
+ // wrap server errors
+ if serverErr, ok := err.(*errors.ServerError); ok {
+ var wrapInfo = map[string]string{}
+ wrapInfo["StringToSign"] = request.GetStringToSign()
+ err = errors.WrapServerError(serverErr, wrapInfo)
+ }
+ return
+}
+
+func buildHttpRequest(request requests.AcsRequest, singer auth.Signer, regionId string) (httpRequest *http.Request, err error) {
+ err = auth.Sign(request, singer, regionId)
+ if err != nil {
+ return
+ }
+ requestMethod := request.GetMethod()
+ requestUrl := request.BuildUrl()
+ body := request.GetBodyReader()
+ httpRequest, err = http.NewRequest(requestMethod, requestUrl, body)
+ if err != nil {
+ return
+ }
+ for key, value := range request.GetHeaders() {
+ httpRequest.Header[key] = []string{value}
+ }
+ // host is a special case
+ if host, containsHost := request.GetHeaders()["Host"]; containsHost {
+ httpRequest.Host = host
+ }
+ return
+}
+
+func isTimeout(err error) bool {
+ if err == nil {
+ return false
+ }
+ netErr, isNetError := err.(net.Error)
+ return isNetError && netErr.Timeout()
+}
+
+func isServerError(httpResponse *http.Response) bool {
+ return httpResponse.StatusCode >= http.StatusInternalServerError
+}
+
+/**
+only block when any one of the following occurs:
+1. the asyncTaskQueue is full, increase the queue size to avoid this
+2. Shutdown() in progressing, the client is being closed
+**/
+func (client *Client) AddAsyncTask(task func()) (err error) {
+ if client.asyncTaskQueue != nil {
+ client.asyncChanLock.RLock()
+ defer client.asyncChanLock.RUnlock()
+ if client.isRunning {
+ client.asyncTaskQueue <- task
+ }
+ } else {
+ err = errors.NewClientError(errors.AsyncFunctionNotEnabledCode, errors.AsyncFunctionNotEnabledMessage, nil)
+ }
+ return
+}
+
+func (client *Client) GetConfig() *Config {
+ return client.config
+}
+
+func NewClient() (client *Client, err error) {
+ client = &Client{}
+ err = client.Init()
+ return
+}
+
+func NewClientWithOptions(regionId string, config *Config, credential auth.Credential) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithOptions(regionId, config, credential)
+ return
+}
+
+func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithAccessKey(regionId, accessKeyId, accessKeySecret)
+ return
+}
+
+func NewClientWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken)
+ return
+}
+
+func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName)
+ return
+}
+
+func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithEcsRamRole(regionId, roleName)
+ return
+}
+
+func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) {
+ client = &Client{}
+ err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration)
+ return
+}
+
+// Deprecated: Use NewClientWithRamRoleArn in this package instead.
+func NewClientWithStsRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) {
+ return NewClientWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName)
+}
+
+// Deprecated: Use NewClientWithEcsRamRole in this package instead.
+func NewClientWithStsRoleNameOnEcs(regionId string, roleName string) (client *Client, err error) {
+ return NewClientWithEcsRamRole(regionId, roleName)
+}
+
+func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
+ request.TransToAcsRequest()
+ response = responses.NewCommonResponse()
+ err = client.DoAction(request, response)
+ return
+}
+
+func (client *Client) ProcessCommonRequestWithSigner(request *requests.CommonRequest, signerInterface interface{}) (response *responses.CommonResponse, err error) {
+ if signer, isSigner := signerInterface.(auth.Signer); isSigner {
+ request.TransToAcsRequest()
+ response = responses.NewCommonResponse()
+ err = client.DoActionWithSigner(request, response, signer)
+ return
+ } else {
+ panic("should not be here")
+ }
+}
+
+func (client *Client) Shutdown() {
+ client.signer.Shutdown()
+ // lock the addAsync()
+ client.asyncChanLock.Lock()
+ defer client.asyncChanLock.Unlock()
+ client.isRunning = false
+ close(client.asyncTaskQueue)
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go
new file mode 100644
index 000000000..c67c2ad09
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go
@@ -0,0 +1,85 @@
+/*
+ * 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 sdk
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
+ "net/http"
+ "time"
+)
+
+type Config struct {
+ AutoRetry bool `default:"true"`
+ MaxRetryTime int `default:"3"`
+ UserAgent string `default:""`
+ Debug bool `default:"false"`
+ Timeout time.Duration `default:"10000000000"`
+ HttpTransport *http.Transport `default:""`
+ EnableAsync bool `default:"false"`
+ MaxTaskQueueSize int `default:"1000"`
+ GoRoutinePoolSize int `default:"5"`
+ Scheme string `default:"HTTP"`
+}
+
+func NewConfig() (config *Config) {
+ config = &Config{}
+ utils.InitStructWithDefaultTag(config)
+ return
+}
+
+func (c *Config) WithTimeout(timeout time.Duration) *Config {
+ c.Timeout = timeout
+ return c
+}
+
+func (c *Config) WithAutoRetry(isAutoRetry bool) *Config {
+ c.AutoRetry = isAutoRetry
+ return c
+}
+
+func (c *Config) WithMaxRetryTime(maxRetryTime int) *Config {
+ c.MaxRetryTime = maxRetryTime
+ return c
+}
+
+func (c *Config) WithUserAgent(userAgent string) *Config {
+ c.UserAgent = userAgent
+ return c
+}
+
+func (c *Config) WithHttpTransport(httpTransport *http.Transport) *Config {
+ c.HttpTransport = httpTransport
+ return c
+}
+
+func (c *Config) WithEnableAsync(isEnableAsync bool) *Config {
+ c.EnableAsync = isEnableAsync
+ return c
+}
+
+func (c *Config) WithMaxTaskQueueSize(maxTaskQueueSize int) *Config {
+ c.MaxTaskQueueSize = maxTaskQueueSize
+ return c
+}
+
+func (c *Config) WithGoRoutinePoolSize(goRoutinePoolSize int) *Config {
+ c.GoRoutinePoolSize = goRoutinePoolSize
+ return c
+}
+
+func (c *Config) WithDebug(isDebug bool) *Config {
+ c.Debug = isDebug
+ return c
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go
new file mode 100644
index 000000000..ec0d56f60
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go
@@ -0,0 +1,505 @@
+package endpoints
+
+import (
+ "encoding/json"
+ "fmt"
+ "sync"
+)
+
+const endpointsJson = "{" +
+ " \"products\":[" +
+ " {" +
+ " \"code\": \"aegis\"," +
+ " \"document_id\": \"28449\"," +
+ " \"location_service_code\": \"vipaegis\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"aegis.cn-hangzhou.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"alidns\"," +
+ " \"document_id\": \"29739\"," +
+ " \"location_service_code\": \"alidns\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"alidns.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"arms\"," +
+ " \"document_id\": \"42924\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"ap-southeast-1\"," +
+ " \"endpoint\": \"arms.ap-southeast-1.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-beijing\"," +
+ " \"endpoint\": \"arms.cn-beijing.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-hangzhou\"," +
+ " \"endpoint\": \"arms.cn-hangzhou.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-hongkong\"," +
+ " \"endpoint\": \"arms.cn-hongkong.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-qingdao\"," +
+ " \"endpoint\": \"arms.cn-qingdao.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shanghai\"," +
+ " \"endpoint\": \"arms.cn-shanghai.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shenzhen\"," +
+ " \"endpoint\": \"arms.cn-shenzhen.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"arms.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"batchcompute\"," +
+ " \"document_id\": \"44717\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"ap-southeast-1\"," +
+ " \"endpoint\": \"batchcompute.ap-southeast-1.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-beijing\"," +
+ " \"endpoint\": \"batchcompute.cn-beijing.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-hangzhou\"," +
+ " \"endpoint\": \"batchcompute.cn-hangzhou.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-huhehaote\"," +
+ " \"endpoint\": \"batchcompute.cn-huhehaote.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-qingdao\"," +
+ " \"endpoint\": \"batchcompute.cn-qingdao.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shanghai\"," +
+ " \"endpoint\": \"batchcompute.cn-shanghai.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shenzhen\"," +
+ " \"endpoint\": \"batchcompute.cn-shenzhen.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-zhangjiakou\"," +
+ " \"endpoint\": \"batchcompute.cn-zhangjiakou.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"us-west-1\"," +
+ " \"endpoint\": \"batchcompute.us-west-1.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"batchcompute.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"ccc\"," +
+ " \"document_id\": \"63027\"," +
+ " \"location_service_code\": \"ccc\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"cn-hangzhou\"," +
+ " \"endpoint\": \"ccc.cn-hangzhou.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shanghai\"," +
+ " \"endpoint\": \"ccc.cn-shanghai.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"ccc.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cdn\"," +
+ " \"document_id\": \"27148\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cdn.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cds\"," +
+ " \"document_id\": \"62887\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cds.cn-beijing.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"chatbot\"," +
+ " \"document_id\": \"60760\"," +
+ " \"location_service_code\": \"beebot\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"chatbot.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cloudapi\"," +
+ " \"document_id\": \"43590\"," +
+ " \"location_service_code\": \"apigateway\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"ap-northeast-1\"," +
+ " \"endpoint\": \"apigateway.ap-northeast-1.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"us-west-1\"," +
+ " \"endpoint\": \"apigateway.us-west-1.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"apigateway.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cloudauth\"," +
+ " \"document_id\": \"60687\"," +
+ " \"location_service_code\": \"cloudauth\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cloudauth.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cloudphoto\"," +
+ " \"document_id\": \"59902\"," +
+ " \"location_service_code\": \"cloudphoto\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"cloudphoto.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cloudwf\"," +
+ " \"document_id\": \"58111\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cloudwf.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cms\"," +
+ " \"document_id\": \"28615\"," +
+ " \"location_service_code\": \"cms\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cr\"," +
+ " \"document_id\": \"60716\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cr.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"cs\"," +
+ " \"document_id\": \"26043\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cs.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"csb\"," +
+ " \"document_id\": \"64837\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"cn-beijing\"," +
+ " \"endpoint\": \"csb.cn-beijing.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-hangzhou\"," +
+ " \"endpoint\": \"csb.cn-hangzhou.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"csb.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"dds\"," +
+ " \"document_id\": \"61715\"," +
+ " \"location_service_code\": \"dds\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"mongodb.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"mongodb.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"dm\"," +
+ " \"document_id\": \"29434\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"ap-southeast-1\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"ap-southeast-2\"," +
+ " \"endpoint\": \"dm.ap-southeast-2.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-beijing\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-hangzhou\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-hongkong\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-qingdao\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shanghai\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"cn-shenzhen\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"us-east-1\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"us-west-1\"," +
+ " \"endpoint\": \"dm.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"dm.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"dm.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"domain\"," +
+ " \"document_id\": \"42875\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"domain.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"domain.aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"domain-intl\"," +
+ " \"document_id\": \"\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"domain-intl.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"domain-intl.aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"drds\"," +
+ " \"document_id\": \"51111\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"drds.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"drds.aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"ecs\"," +
+ " \"document_id\": \"25484\"," +
+ " \"location_service_code\": \"ecs\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"emr\"," +
+ " \"document_id\": \"28140\"," +
+ " \"location_service_code\": \"emr\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"emr.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"ess\"," +
+ " \"document_id\": \"25925\"," +
+ " \"location_service_code\": \"ess\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"ess.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"green\"," +
+ " \"document_id\": \"28427\"," +
+ " \"location_service_code\": \"green\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"green.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"hpc\"," +
+ " \"document_id\": \"35201\"," +
+ " \"location_service_code\": \"hpc\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"hpc.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"httpdns\"," +
+ " \"document_id\": \"52679\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"httpdns-api.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"iot\"," +
+ " \"document_id\": \"30557\"," +
+ " \"location_service_code\": \"iot\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"iot.[RegionId].aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"itaas\"," +
+ " \"document_id\": \"55759\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"itaas.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"jaq\"," +
+ " \"document_id\": \"35037\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"jaq.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"live\"," +
+ " \"document_id\": \"48207\"," +
+ " \"location_service_code\": \"live\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"live.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"mts\"," +
+ " \"document_id\": \"29212\"," +
+ " \"location_service_code\": \"mts\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"nas\"," +
+ " \"document_id\": \"62598\"," +
+ " \"location_service_code\": \"nas\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"ons\"," +
+ " \"document_id\": \"44416\"," +
+ " \"location_service_code\": \"ons\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"polardb\"," +
+ " \"document_id\": \"58764\"," +
+ " \"location_service_code\": \"polardb\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"ap-south-1\"," +
+ " \"endpoint\": \"polardb.ap-south-1.aliyuncs.com\"" +
+ " }, {" +
+ " \"region\": \"ap-southeast-5\"," +
+ " \"endpoint\": \"polardb.ap-southeast-5.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"polardb.aliyuncs.com\"" +
+ " }," +
+ " {" +
+ " \"code\": \"push\"," +
+ " \"document_id\": \"30074\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"cloudpush.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"qualitycheck\"," +
+ " \"document_id\": \"50807\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": [ {" +
+ " \"region\": \"cn-hangzhou\"," +
+ " \"endpoint\": \"qualitycheck.cn-hangzhou.aliyuncs.com\"" +
+ " }]," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"r-kvstore\"," +
+ " \"document_id\": \"60831\"," +
+ " \"location_service_code\": \"redisa\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"ram\"," +
+ " \"document_id\": \"28672\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"ram.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"rds\"," +
+ " \"document_id\": \"26223\"," +
+ " \"location_service_code\": \"rds\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"ros\"," +
+ " \"document_id\": \"28899\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"ros.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"sas-api\"," +
+ " \"document_id\": \"28498\"," +
+ " \"location_service_code\": \"sas\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"slb\"," +
+ " \"document_id\": \"27565\"," +
+ " \"location_service_code\": \"slb\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"sts\"," +
+ " \"document_id\": \"28756\"," +
+ " \"location_service_code\": \"\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"sts.aliyuncs.com\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"vod\"," +
+ " \"document_id\": \"60574\"," +
+ " \"location_service_code\": \"vod\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"vpc\"," +
+ " \"document_id\": \"34962\"," +
+ " \"location_service_code\": \"vpc\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }," +
+ " {" +
+ " \"code\": \"waf\"," +
+ " \"document_id\": \"62847\"," +
+ " \"location_service_code\": \"waf\"," +
+ " \"regional_endpoints\": []," +
+ " \"global_endpoint\": \"\"," +
+ " \"regional_endpoint_pattern\": \"\"" +
+ " }]" +
+ "}"
+
+var initOnce sync.Once
+var data interface{}
+
+func getEndpointConfigData() interface{} {
+ initOnce.Do(func() {
+ err := json.Unmarshal([]byte(endpointsJson), &data)
+ if err != nil {
+ fmt.Println("init endpoint config data failed.", err)
+ }
+ })
+ return data
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go
new file mode 100644
index 000000000..864b7cc4c
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go
@@ -0,0 +1,37 @@
+/*
+ * 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
+
+import (
+ "fmt"
+ "github.com/jmespath/go-jmespath"
+ "strings"
+)
+
+type LocalGlobalResolver struct {
+}
+
+func (resolver *LocalGlobalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
+ // get the global endpoints configs
+ endpointExpression := fmt.Sprintf("products[?code=='%s'].global_endpoint", strings.ToLower(param.Product))
+ endpointData, err := jmespath.Search(endpointExpression, getEndpointConfigData())
+ if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 {
+ endpoint = endpointData.([]interface{})[0].(string)
+ support = len(endpoint) > 0
+ return endpoint, support, nil
+ }
+ support = false
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go
new file mode 100644
index 000000000..f8aa0f92a
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go
@@ -0,0 +1,41 @@
+/*
+ * 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
+
+import (
+ "fmt"
+ "github.com/jmespath/go-jmespath"
+ "strings"
+)
+
+type LocalRegionalResolver struct {
+}
+
+func (resolver *LocalRegionalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
+ // get the regional endpoints configs
+ regionalExpression := fmt.Sprintf("products[?code=='%s'].regional_endpoints", strings.ToLower(param.Product))
+ regionalData, err := jmespath.Search(regionalExpression, getEndpointConfigData())
+ if err == nil && regionalData != nil && len(regionalData.([]interface{})) > 0 {
+ endpointExpression := fmt.Sprintf("[0][?region=='%s'].endpoint", strings.ToLower(param.RegionId))
+ endpointData, err := jmespath.Search(endpointExpression, regionalData)
+ if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 {
+ endpoint = endpointData.([]interface{})[0].(string)
+ support = len(endpoint) > 0
+ return endpoint, support, nil
+ }
+ }
+ support = false
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go
new file mode 100644
index 000000000..803bc57d5
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go
@@ -0,0 +1,139 @@
+/*
+ * 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
+
+import (
+ "encoding/json"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "sync"
+ "time"
+)
+
+const (
+ EndpointCacheExpireTime = 3600 //Seconds
+)
+
+var lastClearTimePerProduct = struct {
+ sync.RWMutex
+ cache map[string]int64
+}{cache: make(map[string]int64)}
+
+var endpointCache = struct {
+ sync.RWMutex
+ cache map[string]string
+}{cache: make(map[string]string)}
+
+type LocationResolver struct {
+}
+
+func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
+ if len(param.LocationProduct) <= 0 {
+ support = false
+ return
+ }
+
+ //get from cache
+ cacheKey := param.Product + "#" + param.RegionId
+ if endpointCache.cache != nil && len(endpointCache.cache[cacheKey]) > 0 && !CheckCacheIsExpire(cacheKey) {
+ endpoint = endpointCache.cache[cacheKey]
+ support = true
+ return
+ }
+
+ //get from remote
+ getEndpointRequest := requests.NewCommonRequest()
+
+ getEndpointRequest.Product = "Location"
+ getEndpointRequest.Version = "2015-06-12"
+ getEndpointRequest.ApiName = "DescribeEndpoints"
+ getEndpointRequest.Domain = "location.aliyuncs.com"
+ getEndpointRequest.Method = "GET"
+ getEndpointRequest.Scheme = requests.HTTPS
+
+ getEndpointRequest.QueryParams["Id"] = param.RegionId
+ getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct
+ if len(param.LocationEndpointType) > 0 {
+ getEndpointRequest.QueryParams["Type"] = param.LocationEndpointType
+ } else {
+ getEndpointRequest.QueryParams["Type"] = "openAPI"
+ }
+
+ response, err := param.CommonApi(getEndpointRequest)
+ var getEndpointResponse GetEndpointResponse
+ if !response.IsSuccess() {
+ support = false
+ return
+ }
+
+ json.Unmarshal([]byte(response.GetHttpContentString()), &getEndpointResponse)
+ if !getEndpointResponse.Success || getEndpointResponse.Endpoints == nil {
+ support = false
+ return
+ }
+ if len(getEndpointResponse.Endpoints.Endpoint) <= 0 {
+ support = false
+ return
+ }
+ if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 {
+ endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint
+ endpointCache.Lock()
+ endpointCache.cache[cacheKey] = endpoint
+ endpointCache.Unlock()
+ lastClearTimePerProduct.Lock()
+ lastClearTimePerProduct.cache[cacheKey] = time.Now().Unix()
+ lastClearTimePerProduct.Unlock()
+ support = true
+ return
+ }
+
+ support = false
+ return
+}
+
+func CheckCacheIsExpire(cacheKey string) bool {
+ lastClearTime := lastClearTimePerProduct.cache[cacheKey]
+ if lastClearTime <= 0 {
+ lastClearTime = time.Now().Unix()
+ lastClearTimePerProduct.Lock()
+ lastClearTimePerProduct.cache[cacheKey] = lastClearTime
+ lastClearTimePerProduct.Unlock()
+ }
+
+ now := time.Now().Unix()
+ elapsedTime := now - lastClearTime
+ if elapsedTime > EndpointCacheExpireTime {
+ return true
+ }
+
+ return false
+}
+
+type GetEndpointResponse struct {
+ Endpoints *EndpointsObj
+ RequestId string
+ Success bool
+}
+
+type EndpointsObj struct {
+ Endpoint []EndpointObj
+}
+
+type EndpointObj struct {
+ Protocols map[string]string
+ Type string
+ Namespace string
+ Id string
+ SerivceCode string
+ Endpoint string
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go
new file mode 100644
index 000000000..f7b5a1aa2
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go
@@ -0,0 +1,39 @@
+/*
+ * 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
+
+import (
+ "fmt"
+ "strings"
+)
+
+const keyFormatter = "%s::%s"
+
+var endpointMapping = make(map[string]string)
+
+func AddEndpointMapping(regionId, productId, endpoint string) (err error) {
+ key := fmt.Sprintf(keyFormatter, strings.ToLower(regionId), strings.ToLower(productId))
+ endpointMapping[key] = endpoint
+ return nil
+}
+
+type MappingResolver struct {
+}
+
+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
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go
new file mode 100644
index 000000000..e58cfbf28
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go
@@ -0,0 +1,80 @@
+/*
+ * 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
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
+ "sync"
+)
+
+const (
+ ResolveEndpointUserGuideLink = ""
+)
+
+var once sync.Once
+var resolvers []Resolver
+
+type Resolver interface {
+ TryResolve(param *ResolveParam) (endpoint string, support bool, err error)
+}
+
+func Resolve(param *ResolveParam) (endpoint string, err error) {
+ supportedResolvers := getAllResolvers()
+ for _, resolver := range supportedResolvers {
+ endpoint, supported, err := resolver.TryResolve(param)
+ if supported {
+ return endpoint, err
+ }
+ }
+
+ // not support
+ errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointErrorMessage, param, ResolveEndpointUserGuideLink)
+ err = errors.NewClientError(errors.CanNotResolveEndpointErrorCode, errorMsg, nil)
+ return
+}
+
+func getAllResolvers() []Resolver {
+ once.Do(func() {
+ resolvers = []Resolver{
+ &SimpleHostResolver{},
+ &MappingResolver{},
+ &LocationResolver{},
+ &LocalRegionalResolver{},
+ &LocalGlobalResolver{},
+ }
+ })
+ return resolvers
+}
+
+type ResolveParam struct {
+ Domain string
+ Product string
+ RegionId string
+ LocationProduct string
+ LocationEndpointType string
+ CommonApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"`
+}
+
+func (param *ResolveParam) String() string {
+ jsonBytes, err := json.Marshal(param)
+ if err != nil {
+ return fmt.Sprint("ResolveParam.String() process error:", err)
+ }
+ return string(jsonBytes)
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go
new file mode 100644
index 000000000..3e2e731ea
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go
@@ -0,0 +1,25 @@
+/*
+ * 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
+
+type SimpleHostResolver struct {
+}
+
+func (resolver *SimpleHostResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
+ if support = len(param.Domain) > 0; support {
+ endpoint = param.Domain
+ }
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go
new file mode 100644
index 000000000..3d4048b4e
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go
@@ -0,0 +1,92 @@
+/*
+ * 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 errors
+
+import "fmt"
+
+const (
+ DefaultClientErrorStatus = 400
+ DefaultClientErrorCode = "SDK.ClientError"
+
+ UnsupportedCredentialErrorCode = "SDK.UnsupportedCredential"
+ UnsupportedCredentialErrorMessage = "Specified credential (type = %s) is not supported, please check"
+
+ CanNotResolveEndpointErrorCode = "SDK.CanNotResolveEndpoint"
+ CanNotResolveEndpointErrorMessage = "Can not resolve endpoint(param = %s), please check your accessKey with secret, and read the user guide\n %s"
+
+ UnsupportedParamPositionErrorCode = "SDK.UnsupportedParamPosition"
+ UnsupportedParamPositionErrorMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry"
+
+ AsyncFunctionNotEnabledCode = "SDK.AsyncFunctionNotEnabled"
+ AsyncFunctionNotEnabledMessage = "Async function is not enabled in client, please invoke 'client.EnableAsync' function"
+
+ UnknownRequestTypeErrorCode = "SDK.UnknownRequestType"
+ UnknownRequestTypeErrorMessage = "Unknown Request Type: %s"
+
+ MissingParamErrorCode = "SDK.MissingParam"
+ InvalidParamErrorCode = "SDK.InvalidParam"
+
+ JsonUnmarshalErrorCode = "SDK.JsonUnmarshalError"
+ JsonUnmarshalErrorMessage = "Failed to unmarshal response, but you can get the data via response.GetHttpStatusCode() and response.GetHttpContentString()"
+
+ TimeoutErrorCode = "SDK.TimeoutError"
+ TimeoutErrorMessage = "The request timed out %s times(%s for retry), perhaps we should have the threshold raised a little?"
+)
+
+type ClientError struct {
+ errorCode string
+ message string
+ originError error
+}
+
+func NewClientError(errorCode, message string, originErr error) Error {
+ return &ClientError{
+ errorCode: errorCode,
+ message: message,
+ originError: originErr,
+ }
+}
+
+func (err *ClientError) Error() string {
+ clientErrMsg := fmt.Sprintf("[%s] %s", err.errorCode, err.message)
+ if err.originError != nil {
+ return clientErrMsg + "\ncaused by:\n" + err.originError.Error()
+ }
+ return clientErrMsg
+}
+
+func (err *ClientError) OriginError() error {
+ return err.originError
+}
+
+func (*ClientError) HttpStatus() int {
+ return DefaultClientErrorStatus
+}
+
+func (err *ClientError) ErrorCode() string {
+ if err.errorCode == "" {
+ return DefaultClientErrorCode
+ } else {
+ return err.errorCode
+ }
+}
+
+func (err *ClientError) Message() string {
+ return err.message
+}
+
+func (err *ClientError) String() string {
+ return err.Error()
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go
new file mode 100644
index 000000000..49962f3b5
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go
@@ -0,0 +1,23 @@
+/*
+ * 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 errors
+
+type Error interface {
+ error
+ HttpStatus() int
+ ErrorCode() string
+ Message() string
+ OriginError() error
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go
new file mode 100644
index 000000000..d90638c0a
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go
@@ -0,0 +1,122 @@
+/*
+ * 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 errors
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/jmespath/go-jmespath"
+)
+
+var wrapperList = []ServerErrorWrapper{
+ &SignatureDostNotMatchWrapper{},
+}
+
+type ServerError struct {
+ httpStatus int
+ requestId string
+ hostId string
+ errorCode string
+ recommend string
+ message string
+ comment string
+}
+
+type ServerErrorWrapper interface {
+ tryWrap(error *ServerError, wrapInfo map[string]string) (bool, *ServerError)
+}
+
+func (err *ServerError) Error() string {
+ return fmt.Sprintf("SDK.ServerError\nErrorCode: %s\nRecommend: %s\nRequestId: %s\nMessage: %s",
+ err.errorCode, err.comment+err.recommend, err.requestId, err.message)
+}
+
+func NewServerError(httpStatus int, responseContent, comment string) Error {
+ result := &ServerError{
+ httpStatus: httpStatus,
+ message: responseContent,
+ comment: comment,
+ }
+
+ var data interface{}
+ err := json.Unmarshal([]byte(responseContent), &data)
+ if err == nil {
+ requestId, _ := jmespath.Search("RequestId", data)
+ hostId, _ := jmespath.Search("HostId", data)
+ errorCode, _ := jmespath.Search("Code", data)
+ recommend, _ := jmespath.Search("Recommend", data)
+ message, _ := jmespath.Search("Message", data)
+
+ if requestId != nil {
+ result.requestId = requestId.(string)
+ }
+ if hostId != nil {
+ result.hostId = hostId.(string)
+ }
+ if errorCode != nil {
+ result.errorCode = errorCode.(string)
+ }
+ if recommend != nil {
+ result.recommend = recommend.(string)
+ }
+ if message != nil {
+ result.message = message.(string)
+ }
+ }
+
+ return result
+}
+
+func WrapServerError(originError *ServerError, wrapInfo map[string]string) *ServerError {
+ for _, wrapper := range wrapperList {
+ ok, newError := wrapper.tryWrap(originError, wrapInfo)
+ if ok {
+ return newError
+ }
+ }
+ return originError
+}
+
+func (err *ServerError) HttpStatus() int {
+ return err.httpStatus
+}
+
+func (err *ServerError) ErrorCode() string {
+ return err.errorCode
+}
+
+func (err *ServerError) Message() string {
+ return err.message
+}
+
+func (err *ServerError) OriginError() error {
+ return nil
+}
+
+func (err *ServerError) HostId() string {
+ return err.hostId
+}
+
+func (err *ServerError) RequestId() string {
+ return err.requestId
+}
+
+func (err *ServerError) Recommend() string {
+ return err.recommend
+}
+
+func (err *ServerError) Comment() string {
+ return err.comment
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go
new file mode 100644
index 000000000..33b3e4c44
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go
@@ -0,0 +1,29 @@
+package errors
+
+import "strings"
+
+const SignatureDostNotMatchErrorCode = "SignatureDoesNotMatch"
+const MessagePrefix = "Specified signature is not matched with our calculation. server string to sign is:"
+
+type SignatureDostNotMatchWrapper struct {
+}
+
+func (*SignatureDostNotMatchWrapper) tryWrap(error *ServerError, wrapInfo map[string]string) (bool, *ServerError) {
+ clientStringToSign := wrapInfo["StringToSign"]
+ if error.errorCode == SignatureDostNotMatchErrorCode && clientStringToSign != "" {
+ message := error.message
+ if strings.HasPrefix(message, MessagePrefix) {
+ serverStringToSign := message[len(MessagePrefix):]
+ if clientStringToSign == serverStringToSign {
+ // user secret is error
+ error.recommend = "Please check you AccessKeySecret"
+ } else {
+ error.recommend = "This may be a bug with the SDK and we hope you can submit this question in the " +
+ "github issue(https://github.com/aliyun/alibaba-cloud-sdk-go/issues), thanks very much"
+ }
+ }
+ return true, error
+ } else {
+ return false, nil
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_reqeust.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_reqeust.go
new file mode 100644
index 000000000..5f4a42bb4
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_reqeust.go
@@ -0,0 +1,309 @@
+/*
+ * 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 requests
+
+import (
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "io"
+ "reflect"
+ "strconv"
+)
+
+const (
+ RPC = "RPC"
+ ROA = "ROA"
+
+ HTTP = "HTTP"
+ HTTPS = "HTTPS"
+
+ DefaultHttpPort = "80"
+
+ GET = "GET"
+ PUT = "PUT"
+ POST = "POST"
+ DELETE = "DELETE"
+ HEAD = "HEAD"
+ OPTIONS = "OPTIONS"
+
+ Json = "application/json"
+ Xml = "application/xml"
+ Raw = "application/octet-stream"
+ Form = "application/x-www-form-urlencoded"
+
+ Header = "Header"
+ Query = "Query"
+ Body = "Body"
+ Path = "Path"
+
+ HeaderSeparator = "\n"
+)
+
+// interface
+type AcsRequest interface {
+ GetScheme() string
+ GetMethod() string
+ GetDomain() string
+ GetPort() string
+ GetRegionId() string
+ GetUrl() string
+ GetQueries() string
+ GetHeaders() map[string]string
+ GetQueryParams() map[string]string
+ GetFormParams() map[string]string
+ GetContent() []byte
+ GetBodyReader() io.Reader
+ GetStyle() string
+ GetProduct() string
+ GetVersion() string
+ GetActionName() string
+ GetAcceptFormat() string
+ GetLocationServiceCode() string
+ GetLocationEndpointType() string
+
+ SetStringToSign(stringToSign string)
+ GetStringToSign() string
+
+ SetDomain(domain string)
+ SetContent(content []byte)
+ SetScheme(scheme string)
+ BuildUrl() string
+ BuildQueries() string
+
+ addHeaderParam(key, value string)
+ addQueryParam(key, value string)
+ addFormParam(key, value string)
+ addPathParam(key, value string)
+}
+
+// base class
+type baseRequest struct {
+ Scheme string
+ Method string
+ Domain string
+ Port string
+ RegionId string
+
+ product string
+ version string
+
+ actionName string
+
+ AcceptFormat string
+
+ QueryParams map[string]string
+ Headers map[string]string
+ FormParams map[string]string
+ Content []byte
+
+ locationServiceCode string
+ locationEndpointType string
+
+ queries string
+
+ stringToSign string
+}
+
+func (request *baseRequest) GetQueryParams() map[string]string {
+ return request.QueryParams
+}
+
+func (request *baseRequest) GetFormParams() map[string]string {
+ return request.FormParams
+}
+
+func (request *baseRequest) GetContent() []byte {
+ return request.Content
+}
+
+func (request *baseRequest) GetVersion() string {
+ return request.version
+}
+
+func (request *baseRequest) GetActionName() string {
+ return request.actionName
+}
+
+func (request *baseRequest) SetContent(content []byte) {
+ request.Content = content
+}
+
+func (request *baseRequest) addHeaderParam(key, value string) {
+ request.Headers[key] = value
+}
+
+func (request *baseRequest) addQueryParam(key, value string) {
+ request.QueryParams[key] = value
+}
+
+func (request *baseRequest) addFormParam(key, value string) {
+ request.FormParams[key] = value
+}
+
+func (request *baseRequest) GetAcceptFormat() string {
+ return request.AcceptFormat
+}
+
+func (request *baseRequest) GetLocationServiceCode() string {
+ return request.locationServiceCode
+}
+
+func (request *baseRequest) GetLocationEndpointType() string {
+ return request.locationEndpointType
+}
+
+func (request *baseRequest) GetProduct() string {
+ return request.product
+}
+
+func (request *baseRequest) GetScheme() string {
+ return request.Scheme
+}
+
+func (request *baseRequest) SetScheme(scheme string) {
+ request.Scheme = scheme
+}
+
+func (request *baseRequest) GetMethod() string {
+ return request.Method
+}
+
+func (request *baseRequest) GetDomain() string {
+ return request.Domain
+}
+
+func (request *baseRequest) SetDomain(host string) {
+ request.Domain = host
+}
+
+func (request *baseRequest) GetPort() string {
+ return request.Port
+}
+
+func (request *baseRequest) GetRegionId() string {
+ return request.RegionId
+}
+
+func (request *baseRequest) GetHeaders() map[string]string {
+ return request.Headers
+}
+
+func (request *baseRequest) SetContentType(contentType string) {
+ request.Headers["Content-Type"] = contentType
+}
+
+func (request *baseRequest) GetContentType() (contentType string, contains bool) {
+ contentType, contains = request.Headers["Content-Type"]
+ return
+}
+
+func (request *baseRequest) SetStringToSign(stringToSign string) {
+ request.stringToSign = stringToSign
+}
+
+func (request *baseRequest) GetStringToSign() string {
+ return request.stringToSign
+}
+
+func defaultBaseRequest() (request *baseRequest) {
+ request = &baseRequest{
+ Scheme: "",
+ AcceptFormat: "JSON",
+ Method: GET,
+ QueryParams: make(map[string]string),
+ Headers: map[string]string{
+ "x-sdk-client": "golang/1.0.0",
+ "x-sdk-invoke-type": "normal",
+ "Accept-Encoding": "identity",
+ },
+ FormParams: make(map[string]string),
+ }
+ return
+}
+
+func InitParams(request AcsRequest) (err error) {
+ requestValue := reflect.ValueOf(request).Elem()
+ err = flatRepeatedList(requestValue, request, "", "")
+ return
+}
+
+func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, prefix string) (err error) {
+ dataType := dataValue.Type()
+ for i := 0; i < dataType.NumField(); i++ {
+ field := dataType.Field(i)
+ name, containsNameTag := field.Tag.Lookup("name")
+ fieldPosition := position
+ if fieldPosition == "" {
+ fieldPosition, _ = field.Tag.Lookup("position")
+ }
+ typeTag, containsTypeTag := field.Tag.Lookup("type")
+ if containsNameTag {
+ if !containsTypeTag {
+ // simple param
+ key := prefix + name
+ value := dataValue.Field(i).String()
+ err = addParam(request, fieldPosition, key, value)
+ if err != nil {
+ return
+ }
+ } 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()
+ }
+ 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().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
+}
+
+func addParam(request AcsRequest, position, name, value string) (err error) {
+ if len(value) > 0 {
+ switch position {
+ case Header:
+ request.addHeaderParam(name, value)
+ case Query:
+ request.addQueryParam(name, value)
+ case Path:
+ request.addPathParam(name, value)
+ case Body:
+ request.addFormParam(name, value)
+ default:
+ errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position)
+ err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil)
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go
new file mode 100644
index 000000000..d5d841b42
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go
@@ -0,0 +1,128 @@
+package requests
+
+import (
+ "bytes"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "io"
+ "strings"
+)
+
+type CommonRequest struct {
+ *baseRequest
+
+ Version string
+ ApiName string
+ Product string
+
+ // roa params
+ PathPattern string
+ PathParams map[string]string
+
+ Ontology AcsRequest
+}
+
+func NewCommonRequest() (request *CommonRequest) {
+ request = &CommonRequest{
+ baseRequest: defaultBaseRequest(),
+ }
+ request.Headers["x-sdk-invoke-type"] = "common"
+ request.PathParams = make(map[string]string)
+ return
+}
+
+func (request *CommonRequest) String() string {
+ request.TransToAcsRequest()
+ request.BuildQueries()
+ request.BuildUrl()
+
+ resultBuilder := bytes.Buffer{}
+
+ mapOutput := func(m map[string]string) {
+ if len(m) > 0 {
+ for key, value := range m {
+ resultBuilder.WriteString(key + ": " + value + "\n")
+ }
+ }
+ }
+
+ // Request Line
+ resultBuilder.WriteString("\n")
+ resultBuilder.WriteString(fmt.Sprintf("%s %s %s/1.1\n", request.Method, request.GetQueries(), strings.ToUpper(request.Scheme)))
+
+ // Headers
+ resultBuilder.WriteString("Host" + ": " + request.Domain + "\n")
+ mapOutput(request.Headers)
+
+ resultBuilder.WriteString("\n")
+ // Body
+ if len(request.Content) > 0 {
+ resultBuilder.WriteString(string(request.Content) + "\n")
+ } else {
+ mapOutput(request.FormParams)
+ }
+
+ return resultBuilder.String()
+}
+
+func (request *CommonRequest) TransToAcsRequest() {
+ if len(request.Version) == 0 {
+ errors.NewClientError(errors.MissingParamErrorCode, "Common request [version] is required", nil)
+ }
+ if len(request.ApiName) == 0 && len(request.PathPattern) == 0 {
+ errors.NewClientError(errors.MissingParamErrorCode, "At least one of [ApiName] and [PathPattern] should has a value", nil)
+ }
+ if len(request.Domain) == 0 && len(request.Product) == 0 {
+ errors.NewClientError(errors.MissingParamErrorCode, "At least one of [Domain] and [Product] should has a value", nil)
+ }
+
+ if len(request.PathPattern) > 0 {
+ roaRequest := &RoaRequest{}
+ roaRequest.initWithCommonRequest(request)
+ request.Ontology = roaRequest
+ } else {
+ rpcRequest := &RpcRequest{}
+ rpcRequest.baseRequest = request.baseRequest
+ rpcRequest.product = request.Product
+ rpcRequest.version = request.Version
+ rpcRequest.actionName = request.ApiName
+ request.Ontology = rpcRequest
+ }
+
+}
+
+func (request *CommonRequest) BuildUrl() string {
+ if len(request.Port) > 0 {
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.BuildQueries()
+ }
+
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + request.BuildQueries()
+}
+
+func (request *CommonRequest) BuildQueries() string {
+ return request.Ontology.BuildQueries()
+}
+
+func (request *CommonRequest) GetUrl() string {
+ if len(request.Port) > 0 {
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.GetQueries()
+ }
+
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + request.GetQueries()
+}
+
+func (request *CommonRequest) GetQueries() string {
+ return request.Ontology.GetQueries()
+}
+
+func (request *CommonRequest) GetBodyReader() io.Reader {
+ return request.Ontology.GetBodyReader()
+}
+
+func (request *CommonRequest) GetStyle() string {
+ return request.Ontology.GetStyle()
+}
+
+func (request *CommonRequest) addPathParam(key, value string) {
+ request.PathParams[key] = value
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go
new file mode 100644
index 000000000..cd1ab178f
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go
@@ -0,0 +1,146 @@
+/*
+ * 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 requests
+
+import (
+ "bytes"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
+ "io"
+ "net/url"
+ "sort"
+ "strings"
+)
+
+type RoaRequest struct {
+ *baseRequest
+ pathPattern string
+ PathParams map[string]string
+}
+
+func (*RoaRequest) GetStyle() string {
+ return ROA
+}
+
+func (request *RoaRequest) GetBodyReader() io.Reader {
+ if request.FormParams != nil && len(request.FormParams) > 0 {
+ formString := utils.GetUrlFormedMap(request.FormParams)
+ return strings.NewReader(formString)
+ } else if len(request.Content) > 0 {
+ return bytes.NewReader(request.Content)
+ } else {
+ return nil
+ }
+}
+
+func (request *RoaRequest) GetQueries() string {
+ return request.queries
+}
+
+// for sign method, need not url encoded
+func (request *RoaRequest) BuildQueries() string {
+ return request.buildQueries(false)
+}
+
+func (request *RoaRequest) buildQueries(needParamEncode bool) string {
+ // replace path params with value
+ path := request.pathPattern
+ for key, value := range request.PathParams {
+ path = strings.Replace(path, "["+key+"]", value, 1)
+ }
+
+ queryParams := request.QueryParams
+ // check if path contains params
+ splitArray := strings.Split(path, "?")
+ path = splitArray[0]
+ if len(splitArray) > 1 && len(splitArray[1]) > 0 {
+ queryParams[splitArray[1]] = ""
+ }
+ // sort QueryParams by key
+ var queryKeys []string
+ for key := range queryParams {
+ queryKeys = append(queryKeys, key)
+ }
+ sort.Strings(queryKeys)
+
+ // append urlBuilder
+ urlBuilder := bytes.Buffer{}
+ urlBuilder.WriteString(path)
+ if len(queryKeys) > 0 {
+ urlBuilder.WriteString("?")
+ }
+ for i := 0; i < len(queryKeys); i++ {
+ queryKey := queryKeys[i]
+ urlBuilder.WriteString(queryKey)
+ if value := queryParams[queryKey]; len(value) > 0 {
+ urlBuilder.WriteString("=")
+ if needParamEncode {
+ urlBuilder.WriteString(url.QueryEscape(value))
+ } else {
+ urlBuilder.WriteString(value)
+ }
+ }
+ if i < len(queryKeys)-1 {
+ urlBuilder.WriteString("&")
+ }
+ }
+ result := urlBuilder.String()
+ result = popStandardUrlencode(result)
+ request.queries = result
+ return request.queries
+}
+
+func popStandardUrlencode(stringToSign string) (result string) {
+ result = strings.Replace(stringToSign, "+", "%20", -1)
+ result = strings.Replace(result, "*", "%2A", -1)
+ result = strings.Replace(result, "%7E", "~", -1)
+ return
+}
+
+func (request *RoaRequest) GetUrl() string {
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.GetQueries()
+}
+
+func (request *RoaRequest) BuildUrl() string {
+ // for network trans, need url encoded
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.buildQueries(true)
+}
+
+func (request *RoaRequest) addPathParam(key, value string) {
+ request.PathParams[key] = value
+}
+
+func (request *RoaRequest) InitWithApiInfo(product, version, action, uriPattern, serviceCode, endpointType string) {
+ request.baseRequest = defaultBaseRequest()
+ request.PathParams = make(map[string]string)
+ request.Headers["x-acs-version"] = version
+ request.pathPattern = uriPattern
+ request.locationServiceCode = serviceCode
+ request.locationEndpointType = endpointType
+ //request.product = product
+ //request.version = version
+ //request.actionName = action
+}
+
+func (request *RoaRequest) initWithCommonRequest(commonRequest *CommonRequest) {
+ request.baseRequest = commonRequest.baseRequest
+ request.PathParams = commonRequest.PathParams
+ //request.product = commonRequest.Product
+ //request.version = commonRequest.Version
+ request.Headers["x-acs-version"] = commonRequest.Version
+ //request.actionName = commonRequest.ApiName
+ request.pathPattern = commonRequest.PathPattern
+ request.locationServiceCode = ""
+ request.locationEndpointType = ""
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go
new file mode 100644
index 000000000..7a61c19f4
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go
@@ -0,0 +1,81 @@
+/*
+ * 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 requests
+
+import (
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
+ "io"
+ "strings"
+)
+
+type RpcRequest struct {
+ *baseRequest
+}
+
+func (request *RpcRequest) init() {
+ request.baseRequest = defaultBaseRequest()
+ request.Method = POST
+}
+
+func (*RpcRequest) GetStyle() string {
+ return RPC
+}
+
+func (request *RpcRequest) GetBodyReader() io.Reader {
+ if request.FormParams != nil && len(request.FormParams) > 0 {
+ formString := utils.GetUrlFormedMap(request.FormParams)
+ return strings.NewReader(formString)
+ } else {
+ return strings.NewReader("")
+ }
+}
+
+func (request *RpcRequest) BuildQueries() string {
+ request.queries = "/?" + utils.GetUrlFormedMap(request.QueryParams)
+ return request.queries
+}
+
+func (request *RpcRequest) GetQueries() string {
+ return request.queries
+}
+
+func (request *RpcRequest) BuildUrl() string {
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + ":" + request.Port + request.BuildQueries()
+}
+
+func (request *RpcRequest) GetUrl() string {
+ return strings.ToLower(request.Scheme) + "://" + request.Domain + request.GetQueries()
+}
+
+func (request *RpcRequest) GetVersion() string {
+ return request.version
+}
+
+func (request *RpcRequest) GetActionName() string {
+ return request.actionName
+}
+
+func (request *RpcRequest) addPathParam(key, value string) {
+ panic("not support")
+}
+
+func (request *RpcRequest) InitWithApiInfo(product, version, action, serviceCode, endpointType string) {
+ request.init()
+ request.product = product
+ request.version = version
+ request.actionName = action
+ request.locationServiceCode = serviceCode
+ request.locationEndpointType = endpointType
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go
new file mode 100644
index 000000000..28af63ea1
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go
@@ -0,0 +1,53 @@
+package requests
+
+import "strconv"
+
+type Integer string
+
+func NewInteger(integer int) Integer {
+ return Integer(strconv.Itoa(integer))
+}
+
+func (integer Integer) HasValue() bool {
+ return integer != ""
+}
+
+func (integer Integer) GetValue() (int, error) {
+ return strconv.Atoi(string(integer))
+}
+
+func NewInteger64(integer int64) Integer {
+ return Integer(strconv.FormatInt(integer, 10))
+}
+
+func (integer Integer) GetValue64() (int64, error) {
+ return strconv.ParseInt(string(integer), 10, 0)
+}
+
+type Boolean string
+
+func NewBoolean(bool bool) Boolean {
+ return Boolean(strconv.FormatBool(bool))
+}
+
+func (boolean Boolean) HasValue() bool {
+ return boolean != ""
+}
+
+func (boolean Boolean) GetValue() (bool, error) {
+ return strconv.ParseBool(string(boolean))
+}
+
+type Float string
+
+func NewFloat(f float64) Float {
+ return Float(strconv.FormatFloat(f, 'f', 6, 64))
+}
+
+func (float Float) HasValue() bool {
+ return float != ""
+}
+
+func (float Float) GetValue() (float64, error) {
+ return strconv.ParseFloat(string(float), 64)
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go
new file mode 100644
index 000000000..43ba6fc26
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go
@@ -0,0 +1,341 @@
+package responses
+
+import (
+ "encoding/json"
+ "github.com/json-iterator/go"
+ "io"
+ "math"
+ "strconv"
+ "strings"
+ "sync"
+ "unsafe"
+)
+
+const maxUint = ^uint(0)
+const maxInt = int(maxUint >> 1)
+const minInt = -maxInt - 1
+
+var jsonParser jsoniter.API
+var initJson = &sync.Once{}
+
+func initJsonParserOnce() {
+ initJson.Do(func() {
+ registerBetterFuzzyDecoder()
+ jsonParser = jsoniter.ConfigCompatibleWithStandardLibrary
+ })
+}
+
+func registerBetterFuzzyDecoder() {
+ jsoniter.RegisterTypeDecoder("string", &nullableFuzzyStringDecoder{})
+ jsoniter.RegisterTypeDecoder("bool", &fuzzyBoolDecoder{})
+ jsoniter.RegisterTypeDecoder("float32", &nullableFuzzyFloat32Decoder{})
+ jsoniter.RegisterTypeDecoder("float64", &nullableFuzzyFloat64Decoder{})
+ jsoniter.RegisterTypeDecoder("int", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(maxInt) || val < float64(minInt) {
+ iter.ReportError("fuzzy decode int", "exceed range")
+ return
+ }
+ *((*int)(ptr)) = int(val)
+ } else {
+ *((*int)(ptr)) = iter.ReadInt()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("uint", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(maxUint) || val < 0 {
+ iter.ReportError("fuzzy decode uint", "exceed range")
+ return
+ }
+ *((*uint)(ptr)) = uint(val)
+ } else {
+ *((*uint)(ptr)) = iter.ReadUint()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("int8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxInt8) || val < float64(math.MinInt8) {
+ iter.ReportError("fuzzy decode int8", "exceed range")
+ return
+ }
+ *((*int8)(ptr)) = int8(val)
+ } else {
+ *((*int8)(ptr)) = iter.ReadInt8()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("uint8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxUint8) || val < 0 {
+ iter.ReportError("fuzzy decode uint8", "exceed range")
+ return
+ }
+ *((*uint8)(ptr)) = uint8(val)
+ } else {
+ *((*uint8)(ptr)) = iter.ReadUint8()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("int16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxInt16) || val < float64(math.MinInt16) {
+ iter.ReportError("fuzzy decode int16", "exceed range")
+ return
+ }
+ *((*int16)(ptr)) = int16(val)
+ } else {
+ *((*int16)(ptr)) = iter.ReadInt16()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("uint16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxUint16) || val < 0 {
+ iter.ReportError("fuzzy decode uint16", "exceed range")
+ return
+ }
+ *((*uint16)(ptr)) = uint16(val)
+ } else {
+ *((*uint16)(ptr)) = iter.ReadUint16()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("int32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxInt32) || val < float64(math.MinInt32) {
+ iter.ReportError("fuzzy decode int32", "exceed range")
+ return
+ }
+ *((*int32)(ptr)) = int32(val)
+ } else {
+ *((*int32)(ptr)) = iter.ReadInt32()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("uint32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxUint32) || val < 0 {
+ iter.ReportError("fuzzy decode uint32", "exceed range")
+ return
+ }
+ *((*uint32)(ptr)) = uint32(val)
+ } else {
+ *((*uint32)(ptr)) = iter.ReadUint32()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("int64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxInt64) || val < float64(math.MinInt64) {
+ iter.ReportError("fuzzy decode int64", "exceed range")
+ return
+ }
+ *((*int64)(ptr)) = int64(val)
+ } else {
+ *((*int64)(ptr)) = iter.ReadInt64()
+ }
+ }})
+ jsoniter.RegisterTypeDecoder("uint64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if isFloat {
+ val := iter.ReadFloat64()
+ if val > float64(math.MaxUint64) || val < 0 {
+ iter.ReportError("fuzzy decode uint64", "exceed range")
+ return
+ }
+ *((*uint64)(ptr)) = uint64(val)
+ } else {
+ *((*uint64)(ptr)) = iter.ReadUint64()
+ }
+ }})
+}
+
+type nullableFuzzyStringDecoder struct {
+}
+
+func (decoder *nullableFuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ valueType := iter.WhatIsNext()
+ switch valueType {
+ case jsoniter.NumberValue:
+ var number json.Number
+ iter.ReadVal(&number)
+ *((*string)(ptr)) = string(number)
+ case jsoniter.StringValue:
+ *((*string)(ptr)) = iter.ReadString()
+ case jsoniter.BoolValue:
+ *((*string)(ptr)) = strconv.FormatBool(iter.ReadBool())
+ case jsoniter.NilValue:
+ iter.ReadNil()
+ *((*string)(ptr)) = ""
+ default:
+ iter.ReportError("fuzzyStringDecoder", "not number or string or bool")
+ }
+}
+
+type fuzzyBoolDecoder struct {
+}
+
+func (decoder *fuzzyBoolDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ valueType := iter.WhatIsNext()
+ switch valueType {
+ case jsoniter.BoolValue:
+ *((*bool)(ptr)) = iter.ReadBool()
+ case jsoniter.NumberValue:
+ var number json.Number
+ iter.ReadVal(&number)
+ num, err := number.Int64()
+ if err != nil {
+ iter.ReportError("fuzzyBoolDecoder", "get value from json.number failed")
+ }
+ if num == 0 {
+ *((*bool)(ptr)) = false
+ } else {
+ *((*bool)(ptr)) = true
+ }
+ case jsoniter.StringValue:
+ strValue := strings.ToLower(iter.ReadString())
+ if strValue == "true" {
+ *((*bool)(ptr)) = true
+ } else if strValue == "false" || strValue == "" {
+ *((*bool)(ptr)) = false
+ } else {
+ iter.ReportError("fuzzyBoolDecoder", "unsupported bool value: "+strValue)
+ }
+ case jsoniter.NilValue:
+ iter.ReadNil()
+ *((*bool)(ptr)) = false
+ default:
+ iter.ReportError("fuzzyBoolDecoder", "not number or string or nil")
+ }
+}
+
+type tolerateEmptyArrayDecoder struct {
+ valDecoder jsoniter.ValDecoder
+}
+
+func (decoder *tolerateEmptyArrayDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ if iter.WhatIsNext() == jsoniter.ArrayValue {
+ iter.Skip()
+ newIter := iter.Pool().BorrowIterator([]byte("{}"))
+ defer iter.Pool().ReturnIterator(newIter)
+ decoder.valDecoder.Decode(ptr, newIter)
+ } else {
+ decoder.valDecoder.Decode(ptr, iter)
+ }
+}
+
+type nullableFuzzyIntegerDecoder struct {
+ fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator)
+}
+
+func (decoder *nullableFuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ valueType := iter.WhatIsNext()
+ var str string
+ switch valueType {
+ case jsoniter.NumberValue:
+ var number json.Number
+ iter.ReadVal(&number)
+ str = string(number)
+ case jsoniter.StringValue:
+ str = iter.ReadString()
+ // support empty string
+ if str == "" {
+ str = "0"
+ }
+ case jsoniter.BoolValue:
+ if iter.ReadBool() {
+ str = "1"
+ } else {
+ str = "0"
+ }
+ case jsoniter.NilValue:
+ iter.ReadNil()
+ str = "0"
+ default:
+ iter.ReportError("fuzzyIntegerDecoder", "not number or string")
+ }
+ newIter := iter.Pool().BorrowIterator([]byte(str))
+ defer iter.Pool().ReturnIterator(newIter)
+ isFloat := strings.IndexByte(str, '.') != -1
+ decoder.fun(isFloat, ptr, newIter)
+ if newIter.Error != nil && newIter.Error != io.EOF {
+ iter.Error = newIter.Error
+ }
+}
+
+type nullableFuzzyFloat32Decoder struct {
+}
+
+func (decoder *nullableFuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ valueType := iter.WhatIsNext()
+ var str string
+ switch valueType {
+ case jsoniter.NumberValue:
+ *((*float32)(ptr)) = iter.ReadFloat32()
+ case jsoniter.StringValue:
+ str = iter.ReadString()
+ // support empty string
+ if str == "" {
+ *((*float32)(ptr)) = 0
+ return
+ }
+ newIter := iter.Pool().BorrowIterator([]byte(str))
+ defer iter.Pool().ReturnIterator(newIter)
+ *((*float32)(ptr)) = newIter.ReadFloat32()
+ if newIter.Error != nil && newIter.Error != io.EOF {
+ iter.Error = newIter.Error
+ }
+ case jsoniter.BoolValue:
+ // support bool to float32
+ if iter.ReadBool() {
+ *((*float32)(ptr)) = 1
+ } else {
+ *((*float32)(ptr)) = 0
+ }
+ case jsoniter.NilValue:
+ iter.ReadNil()
+ *((*float32)(ptr)) = 0
+ default:
+ iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string")
+ }
+}
+
+type nullableFuzzyFloat64Decoder struct {
+}
+
+func (decoder *nullableFuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ valueType := iter.WhatIsNext()
+ var str string
+ switch valueType {
+ case jsoniter.NumberValue:
+ *((*float64)(ptr)) = iter.ReadFloat64()
+ case jsoniter.StringValue:
+ str = iter.ReadString()
+ // support empty string
+ if str == "" {
+ *((*float64)(ptr)) = 0
+ return
+ }
+ newIter := iter.Pool().BorrowIterator([]byte(str))
+ defer iter.Pool().ReturnIterator(newIter)
+ *((*float64)(ptr)) = newIter.ReadFloat64()
+ if newIter.Error != nil && newIter.Error != io.EOF {
+ iter.Error = newIter.Error
+ }
+ case jsoniter.BoolValue:
+ // support bool to float64
+ if iter.ReadBool() {
+ *((*float64)(ptr)) = 1
+ } else {
+ *((*float64)(ptr)) = 0
+ }
+ case jsoniter.NilValue:
+ // support empty string
+ iter.ReadNil()
+ *((*float64)(ptr)) = 0
+ default:
+ iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string")
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go
new file mode 100644
index 000000000..8780f26f2
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go
@@ -0,0 +1,142 @@
+/*
+ * 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 responses
+
+import (
+ "bytes"
+ "encoding/xml"
+ "fmt"
+ "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
+ "io/ioutil"
+ "net/http"
+ "strings"
+)
+
+type AcsResponse interface {
+ IsSuccess() bool
+ GetHttpStatus() int
+ GetHttpHeaders() map[string][]string
+ GetHttpContentString() string
+ GetHttpContentBytes() []byte
+ GetOriginHttpResponse() *http.Response
+ parseFromHttpResponse(httpResponse *http.Response) error
+}
+
+func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
+ err = response.parseFromHttpResponse(httpResponse)
+ if err != nil {
+ return
+ }
+ if !response.IsSuccess() {
+ err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), "")
+ return
+ }
+ if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
+ // common response need not unmarshal
+ return
+ }
+
+ if len(response.GetHttpContentBytes()) == 0 {
+ return
+ }
+
+ if strings.ToUpper(format) == "JSON" {
+ initJsonParserOnce()
+ err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response)
+ if err != nil {
+ err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err)
+ }
+ } else if strings.ToUpper(format) == "XML" {
+ err = xml.Unmarshal(response.GetHttpContentBytes(), response)
+ }
+ return
+}
+
+type BaseResponse struct {
+ httpStatus int
+ httpHeaders map[string][]string
+ httpContentString string
+ httpContentBytes []byte
+ originHttpResponse *http.Response
+}
+
+func (baseResponse *BaseResponse) GetHttpStatus() int {
+ return baseResponse.httpStatus
+}
+
+func (baseResponse *BaseResponse) GetHttpHeaders() map[string][]string {
+ return baseResponse.httpHeaders
+}
+
+func (baseResponse *BaseResponse) GetHttpContentString() string {
+ return baseResponse.httpContentString
+}
+
+func (baseResponse *BaseResponse) GetHttpContentBytes() []byte {
+ return baseResponse.httpContentBytes
+}
+
+func (baseResponse *BaseResponse) GetOriginHttpResponse() *http.Response {
+ return baseResponse.originHttpResponse
+}
+
+func (baseResponse *BaseResponse) IsSuccess() bool {
+ if baseResponse.GetHttpStatus() >= 200 && baseResponse.GetHttpStatus() < 300 {
+ return true
+ }
+
+ return false
+}
+
+func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Response) (err error) {
+ defer httpResponse.Body.Close()
+ body, err := ioutil.ReadAll(httpResponse.Body)
+ if err != nil {
+ return
+ }
+ baseResponse.httpStatus = httpResponse.StatusCode
+ baseResponse.httpHeaders = httpResponse.Header
+ baseResponse.httpContentBytes = body
+ baseResponse.httpContentString = string(body)
+ baseResponse.originHttpResponse = httpResponse
+ return
+}
+
+func (baseResponse *BaseResponse) String() string {
+ resultBuilder := bytes.Buffer{}
+ // statusCode
+ resultBuilder.WriteString("\n")
+ resultBuilder.WriteString(fmt.Sprintf("%s %s\n", baseResponse.originHttpResponse.Proto, baseResponse.originHttpResponse.Status))
+ // httpHeaders
+ //resultBuilder.WriteString("Headers:\n")
+ for key, value := range baseResponse.httpHeaders {
+ resultBuilder.WriteString(key + ": " + strings.Join(value, ";") + "\n")
+ }
+ resultBuilder.WriteString("\n")
+ // content
+ //resultBuilder.WriteString("Content:\n")
+ resultBuilder.WriteString(baseResponse.httpContentString + "\n")
+ return resultBuilder.String()
+}
+
+type CommonResponse struct {
+ *BaseResponse
+}
+
+func NewCommonResponse() (response *CommonResponse) {
+ return &CommonResponse{
+ BaseResponse: &BaseResponse{},
+ }
+}
diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go
new file mode 100644
index 000000000..a00c775c2
--- /dev/null
+++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go
@@ -0,0 +1,117 @@
+/*
+ * 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 utils
+
+import (
+ "crypto/md5"
+ "encoding/base64"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "github.com/satori/go.uuid"
+ "net/url"
+ "reflect"
+ "strconv"
+ "time"
+)
+
+// if you use go 1.10 or higher, you can hack this util by these to avoid "TimeZone.zip not found" on Windows
+var LoadLocationFromTZData func(name string, data []byte) (*time.Location, error) = nil
+var TZData []byte = nil
+
+func GetUUIDV4() (uuidHex string) {
+ uuidV4 := uuid.NewV4()
+ uuidHex = hex.EncodeToString(uuidV4.Bytes())
+ return
+}
+
+func GetMD5Base64(bytes []byte) (base64Value string) {
+ md5Ctx := md5.New()
+ md5Ctx.Write(bytes)
+ md5Value := md5Ctx.Sum(nil)
+ base64Value = base64.StdEncoding.EncodeToString(md5Value)
+ return
+}
+
+func GetGMTLocation() (*time.Location, error) {
+ if LoadLocationFromTZData != nil && TZData != nil {
+ return LoadLocationFromTZData("GMT", TZData)
+ } else {
+ return time.LoadLocation("GMT")
+ }
+}
+
+func GetTimeInFormatISO8601() (timeStr string) {
+ gmt, err := GetGMTLocation()
+
+ if err != nil {
+ panic(err)
+ }
+ return time.Now().In(gmt).Format("2006-01-02T15:04:05Z")
+}
+
+func GetTimeInFormatRFC2616() (timeStr string) {
+ gmt, err := GetGMTLocation()
+
+ if err != nil {
+ panic(err)
+ }
+ return time.Now().In(gmt).Format("Mon, 02 Jan 2006 15:04:05 GMT")
+}
+
+func GetUrlFormedMap(source map[string]string) (urlEncoded string) {
+ urlEncoder := url.Values{}
+ for key, value := range source {
+ urlEncoder.Add(key, value)
+ }
+ urlEncoded = urlEncoder.Encode()
+ return
+}
+
+func GetFromJsonString(jsonString, key string) (result string, err error) {
+ var responseMap map[string]*json.RawMessage
+ err = json.Unmarshal([]byte(jsonString), &responseMap)
+ if err != nil {
+ return
+ }
+ fmt.Println(string(*responseMap[key]))
+ err = json.Unmarshal(*responseMap[key], &result)
+ return
+}
+
+func InitStructWithDefaultTag(bean interface{}) {
+ configType := reflect.TypeOf(bean)
+ for i := 0; i < configType.Elem().NumField(); i++ {
+ field := configType.Elem().Field(i)
+ defaultValue := field.Tag.Get("default")
+ if defaultValue == "" {
+ continue
+ }
+ setter := reflect.ValueOf(bean).Elem().Field(i)
+ switch field.Type.String() {
+ case "int":
+ intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
+ setter.SetInt(intValue)
+ case "time.Duration":
+ intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
+ setter.SetInt(intValue)
+ case "string":
+ setter.SetString(defaultValue)
+ case "bool":
+ boolValue, _ := strconv.ParseBool(defaultValue)
+ setter.SetBool(boolValue)
+ }
+ }
+}
diff --git a/vkubelet/lookup.go b/vkubelet/lookup.go
index 89ec9b682..b93bdee89 100644
--- a/vkubelet/lookup.go
+++ b/vkubelet/lookup.go
@@ -5,6 +5,7 @@ package vkubelet
import (
"github.com/pkg/errors"
"github.com/virtual-kubelet/virtual-kubelet/manager"
+ "github.com/virtual-kubelet/virtual-kubelet/providers/alicloud"
"github.com/virtual-kubelet/virtual-kubelet/providers/aws"
"github.com/virtual-kubelet/virtual-kubelet/providers/azure"
"github.com/virtual-kubelet/virtual-kubelet/providers/azurebatch"
@@ -18,6 +19,7 @@ import (
)
// Compile time proof that our implementations meet the Provider interface.
+var _ Provider = (*alicloud.ECIProvider)(nil)
var _ Provider = (*aws.FargateProvider)(nil)
var _ Provider = (*azure.ACIProvider)(nil)
var _ Provider = (*hypersh.HyperProvider)(nil)
@@ -33,6 +35,8 @@ var _ Provider = (*vic.VicProvider)(nil)
func lookupProvider(provider, providerConfig string, rm *manager.ResourceManager, nodeName, operatingSystem, internalIP string, daemonEndpointPort int32) (Provider, error) {
switch provider {
+ case "alicloud":
+ return alicloud.NewECIProvider(providerConfig, rm, nodeName, operatingSystem, internalIP, daemonEndpointPort)
case "aws":
return aws.NewFargateProvider(providerConfig, rm, nodeName, operatingSystem, internalIP, daemonEndpointPort)
case "azure":
diff --git a/vkubelet/lookup_darwin.go b/vkubelet/lookup_darwin.go
index a45f3d929..7c20311a0 100644
--- a/vkubelet/lookup_darwin.go
+++ b/vkubelet/lookup_darwin.go
@@ -14,6 +14,7 @@ import (
)
// Compile time proof that our implementations meet the Provider interface.
+var _ Provider = (*alicloud.ECIProvider)(nil)
var _ Provider = (*aws.FargateProvider)(nil)
var _ Provider = (*azure.ACIProvider)(nil)
var _ Provider = (*hypersh.HyperProvider)(nil)
@@ -25,6 +26,8 @@ var _ Provider = (*sfmesh.SFMeshProvider)(nil)
func lookupProvider(provider, providerConfig string, rm *manager.ResourceManager, nodeName, operatingSystem, internalIP string, daemonEndpointPort int32) (Provider, error) {
switch provider {
+ case "alicloud":
+ return alicloud.NewECIProvider(providerConfig, rm, nodeName, operatingSystem, internalIP, daemonEndpointPort)
case "aws":
return aws.NewFargateProvider(providerConfig, rm, nodeName, operatingSystem, internalIP, daemonEndpointPort)
case "azure":